summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaleb Raitto <caraitto@chromium.org>2020-07-23 01:45:27 +0000
committerMichael BrĂ¼ning <michael.bruning@qt.io>2020-10-27 09:29:27 +0000
commit9d173d02d5ec0a2a3e3051ced579d0507d5bcf54 (patch)
treec1afc12050884af3d14cfc3b674287be5bf3c39b
parent6ef8f4ed82915703d25c80ace6148e5e1413a78e (diff)
downloadqtwebengine-chromium-9d173d02d5ec0a2a3e3051ced579d0507d5bcf54.tar.gz
[Backport] Security bug 1106091
Manual backport of patch originally reviewed on https://chromium-review.googlesource.com/c/chromium/src/+/2309004: Remove SimpleSerialize() and SimpleDeserialize(). By handling serialization of each type explicitly, we avoid serializing padding bytes. Bug: 973801,1106091 Change-Id: I9f4e6b82fb484b9256b25b531cc2d51c800425bb Commit-Queue: Khushal <khushalsagar@chromium.org> Reviewed-by: Khushal <khushalsagar@chromium.org> Cr-Commit-Position: refs/heads/master@{#791110} Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r--chromium/cc/paint/paint_op_buffer.cc317
-rw-r--r--chromium/cc/paint/paint_op_buffer.h31
-rw-r--r--chromium/cc/paint/paint_op_reader.h9
-rw-r--r--chromium/cc/paint/paint_op_writer.h3
4 files changed, 280 insertions, 80 deletions
diff --git a/chromium/cc/paint/paint_op_buffer.cc b/chromium/cc/paint/paint_op_buffer.cc
index 6417c049cde..5f21d6c82b6 100644
--- a/chromium/cc/paint/paint_op_buffer.cc
+++ b/chromium/cc/paint/paint_op_buffer.cc
@@ -306,14 +306,6 @@ std::ostream& operator<<(std::ostream& os, PaintOpType type) {
return os << PaintOpTypeToString(type);
}
-template <typename T>
-size_t SimpleSerialize(const PaintOp* op, void* memory, size_t size) {
- if (sizeof(T) > size)
- return 0;
- memcpy(memory, op, sizeof(T));
- return sizeof(T);
-}
-
PlaybackParams::PlaybackParams(ImageProvider* image_provider)
: image_provider(image_provider),
original_ctm(SkMatrix::I()),
@@ -401,39 +393,59 @@ size_t ClipPathOp::Serialize(const PaintOp* base_op,
return helper.size();
}
-size_t ClipRectOp::Serialize(const PaintOp* op,
+size_t ClipRectOp::Serialize(const PaintOp* base_op,
void* memory,
size_t size,
const SerializeOptions& options) {
- return SimpleSerialize<ClipRectOp>(op, memory, size);
+ auto* op = static_cast<const ClipRectOp*>(base_op);
+ PaintOpWriter helper(memory, size, options);
+ helper.Write(op->rect);
+ helper.Write(op->op);
+ helper.Write(op->antialias);
+ return helper.size();
}
-size_t ClipRRectOp::Serialize(const PaintOp* op,
+size_t ClipRRectOp::Serialize(const PaintOp* base_op,
void* memory,
size_t size,
const SerializeOptions& options) {
- return SimpleSerialize<ClipRRectOp>(op, memory, size);
+ auto* op = static_cast<const ClipRRectOp*>(base_op);
+ PaintOpWriter helper(memory, size, options);
+ helper.Write(op->rrect);
+ helper.Write(op->op);
+ helper.Write(op->antialias);
+ return helper.size();
}
-size_t ConcatOp::Serialize(const PaintOp* op,
+size_t ConcatOp::Serialize(const PaintOp* base_op,
void* memory,
size_t size,
const SerializeOptions& options) {
- return SimpleSerialize<ConcatOp>(op, memory, size);
+ auto* op = static_cast<const ConcatOp*>(base_op);
+ PaintOpWriter helper(memory, size, options);
+ helper.Write(op->matrix);
+ return helper.size();
}
-size_t CustomDataOp::Serialize(const PaintOp* op,
+size_t CustomDataOp::Serialize(const PaintOp* base_op,
void* memory,
size_t size,
const SerializeOptions& options) {
- return SimpleSerialize<CustomDataOp>(op, memory, size);
+ auto* op = static_cast<const CustomDataOp*>(base_op);
+ PaintOpWriter helper(memory, size, options);
+ helper.Write(op->id);
+ return helper.size();
}
-size_t DrawColorOp::Serialize(const PaintOp* op,
+size_t DrawColorOp::Serialize(const PaintOp* base_op,
void* memory,
size_t size,
const SerializeOptions& options) {
- return SimpleSerialize<DrawColorOp>(op, memory, size);
+ auto* op = static_cast<const DrawColorOp*>(base_op);
+ PaintOpWriter helper(memory, size, options);
+ helper.Write(op->color);
+ helper.Write(op->mode);
+ return helper.size();
}
size_t DrawDRRectOp::Serialize(const PaintOp* base_op,
@@ -639,32 +651,38 @@ size_t DrawTextBlobOp::Serialize(const PaintOp* base_op,
return helper.size();
}
-size_t NoopOp::Serialize(const PaintOp* op,
+size_t NoopOp::Serialize(const PaintOp* base_op,
void* memory,
size_t size,
const SerializeOptions& options) {
- return SimpleSerialize<NoopOp>(op, memory, size);
+ PaintOpWriter helper(memory, size, options);
+ return helper.size();
}
-size_t RestoreOp::Serialize(const PaintOp* op,
+size_t RestoreOp::Serialize(const PaintOp* base_op,
void* memory,
size_t size,
const SerializeOptions& options) {
- return SimpleSerialize<RestoreOp>(op, memory, size);
+ PaintOpWriter helper(memory, size, options);
+ return helper.size();
}
-size_t RotateOp::Serialize(const PaintOp* op,
+size_t RotateOp::Serialize(const PaintOp* base_op,
void* memory,
size_t size,
const SerializeOptions& options) {
- return SimpleSerialize<RotateOp>(op, memory, size);
+ auto* op = static_cast<const RotateOp*>(base_op);
+ PaintOpWriter helper(memory, size, options);
+ helper.Write(op->degrees);
+ return helper.size();
}
-size_t SaveOp::Serialize(const PaintOp* op,
+size_t SaveOp::Serialize(const PaintOp* base_op,
void* memory,
size_t size,
const SerializeOptions& options) {
- return SimpleSerialize<SaveOp>(op, memory, size);
+ PaintOpWriter helper(memory, size, options);
+ return helper.size();
}
size_t SaveLayerOp::Serialize(const PaintOp* base_op,
@@ -681,44 +699,64 @@ size_t SaveLayerOp::Serialize(const PaintOp* base_op,
return helper.size();
}
-size_t SaveLayerAlphaOp::Serialize(const PaintOp* op,
+size_t SaveLayerAlphaOp::Serialize(const PaintOp* base_op,
void* memory,
size_t size,
const SerializeOptions& options) {
- return SimpleSerialize<SaveLayerAlphaOp>(op, memory, size);
+ auto* op = static_cast<const SaveLayerAlphaOp*>(base_op);
+ PaintOpWriter helper(memory, size, options);
+ helper.Write(op->bounds);
+ helper.Write(op->alpha);
+ return helper.size();
}
-size_t ScaleOp::Serialize(const PaintOp* op,
+size_t ScaleOp::Serialize(const PaintOp* base_op,
void* memory,
size_t size,
const SerializeOptions& options) {
- return SimpleSerialize<ScaleOp>(op, memory, size);
+ auto* op = static_cast<const ScaleOp*>(base_op);
+ PaintOpWriter helper(memory, size, options);
+ helper.Write(op->sx);
+ helper.Write(op->sy);
+ return helper.size();
}
-size_t SetMatrixOp::Serialize(const PaintOp* op,
+size_t SetMatrixOp::Serialize(const PaintOp* base_op,
void* memory,
size_t size,
const SerializeOptions& options) {
- if (options.original_ctm.isIdentity())
- return SimpleSerialize<SetMatrixOp>(op, memory, size);
+ auto* op = static_cast<const SetMatrixOp*>(base_op);
+ PaintOpWriter helper(memory, size, options);
- SetMatrixOp transformed(*static_cast<const SetMatrixOp*>(op));
- transformed.matrix.postConcat(options.original_ctm);
- return SimpleSerialize<SetMatrixOp>(&transformed, memory, size);
+ if (options.original_ctm.isIdentity()) {
+ helper.Write(op->matrix);
+ } else {
+ SkMatrix transformed = op->matrix;
+ transformed.postConcat(options.original_ctm);
+ helper.Write(transformed);
+ }
+ return helper.size();
}
-size_t SetNodeIdOp::Serialize(const PaintOp* op,
+size_t SetNodeIdOp::Serialize(const PaintOp* base_op,
void* memory,
size_t size,
const SerializeOptions& options) {
- return SimpleSerialize<SetNodeIdOp>(op, memory, size);
+ auto* op = static_cast<const SetNodeIdOp*>(base_op);
+ PaintOpWriter helper(memory, size, options);
+ helper.Write(op->node_id);
+ return helper.size();
}
-size_t TranslateOp::Serialize(const PaintOp* op,
+size_t TranslateOp::Serialize(const PaintOp* base_op,
void* memory,
size_t size,
const SerializeOptions& options) {
- return SimpleSerialize<TranslateOp>(op, memory, size);
+ auto* op = static_cast<const TranslateOp*>(base_op);
+ PaintOpWriter helper(memory, size, options);
+ helper.Write(op->dx);
+ helper.Write(op->dy);
+ return helper.size();
}
template <typename T>
@@ -727,24 +765,6 @@ void UpdateTypeAndSkip(T* op) {
op->skip = PaintOpBuffer::ComputeOpSkip(sizeof(T));
}
-template <typename T>
-T* SimpleDeserialize(const volatile void* input,
- size_t input_size,
- void* output,
- size_t output_size) {
- if (input_size < sizeof(T))
- return nullptr;
- memcpy(output, const_cast<void*>(input), sizeof(T));
-
- T* op = reinterpret_cast<T*>(output);
- if (!op->IsValid())
- return nullptr;
- // Type and skip were already read once, so could have been changed.
- // Don't trust them and clobber them with something valid.
- UpdateTypeAndSkip(op);
- return op;
-}
-
PaintOp* AnnotateOp::Deserialize(const volatile void* input,
size_t input_size,
void* output,
@@ -793,7 +813,19 @@ PaintOp* ClipRectOp::Deserialize(const volatile void* input,
size_t output_size,
const DeserializeOptions& options) {
DCHECK_GE(output_size, sizeof(ClipRectOp));
- return SimpleDeserialize<ClipRectOp>(input, input_size, output, output_size);
+ ClipRectOp* op = new (output) ClipRectOp;
+
+ PaintOpReader helper(input, input_size, options);
+ helper.Read(&op->rect);
+ helper.Read(&op->op);
+ helper.Read(&op->antialias);
+ if (!helper.valid() || !op->IsValid()) {
+ op->~ClipRectOp();
+ return nullptr;
+ }
+
+ UpdateTypeAndSkip(op);
+ return op;
}
PaintOp* ClipRRectOp::Deserialize(const volatile void* input,
@@ -802,7 +834,19 @@ PaintOp* ClipRRectOp::Deserialize(const volatile void* input,
size_t output_size,
const DeserializeOptions& options) {
DCHECK_GE(output_size, sizeof(ClipRRectOp));
- return SimpleDeserialize<ClipRRectOp>(input, input_size, output, output_size);
+ ClipRRectOp* op = new (output) ClipRRectOp;
+
+ PaintOpReader helper(input, input_size, options);
+ helper.Read(&op->rrect);
+ helper.Read(&op->op);
+ helper.Read(&op->antialias);
+ if (!helper.valid() || !op->IsValid()) {
+ op->~ClipRRectOp();
+ return nullptr;
+ }
+
+ UpdateTypeAndSkip(op);
+ return op;
}
PaintOp* ConcatOp::Deserialize(const volatile void* input,
@@ -811,10 +855,17 @@ PaintOp* ConcatOp::Deserialize(const volatile void* input,
size_t output_size,
const DeserializeOptions& options) {
DCHECK_GE(output_size, sizeof(ConcatOp));
- auto* op =
- SimpleDeserialize<ConcatOp>(input, input_size, output, output_size);
- if (op)
- PaintOpReader::FixupMatrixPostSerialization(&op->matrix);
+ ConcatOp* op = new (output) ConcatOp;
+
+ PaintOpReader helper(input, input_size, options);
+ helper.Read(&op->matrix);
+ if (!helper.valid() || !op->IsValid()) {
+ op->~ConcatOp();
+ return nullptr;
+ }
+
+ UpdateTypeAndSkip(op);
+ PaintOpReader::FixupMatrixPostSerialization(&op->matrix);
return op;
}
@@ -824,8 +875,17 @@ PaintOp* CustomDataOp::Deserialize(const volatile void* input,
size_t output_size,
const DeserializeOptions& options) {
DCHECK_GE(output_size, sizeof(CustomDataOp));
- return SimpleDeserialize<CustomDataOp>(input, input_size, output,
- output_size);
+ CustomDataOp* op = new (output) CustomDataOp;
+
+ PaintOpReader helper(input, input_size, options);
+ helper.Read(&op->id);
+ if (!helper.valid() || !op->IsValid()) {
+ op->~CustomDataOp();
+ return nullptr;
+ }
+
+ UpdateTypeAndSkip(op);
+ return op;
}
PaintOp* DrawColorOp::Deserialize(const volatile void* input,
@@ -834,7 +894,18 @@ PaintOp* DrawColorOp::Deserialize(const volatile void* input,
size_t output_size,
const DeserializeOptions& options) {
DCHECK_GE(output_size, sizeof(DrawColorOp));
- return SimpleDeserialize<DrawColorOp>(input, input_size, output, output_size);
+ DrawColorOp* op = new (output) DrawColorOp;
+
+ PaintOpReader helper(input, input_size, options);
+ helper.Read(&op->color);
+ helper.Read(&op->mode);
+ if (!helper.valid() || !op->IsValid()) {
+ op->~DrawColorOp();
+ return nullptr;
+ }
+
+ UpdateTypeAndSkip(op);
+ return op;
}
PaintOp* DrawDRRectOp::Deserialize(const volatile void* input,
@@ -1097,7 +1168,16 @@ PaintOp* NoopOp::Deserialize(const volatile void* input,
size_t output_size,
const DeserializeOptions& options) {
DCHECK_GE(output_size, sizeof(NoopOp));
- return SimpleDeserialize<NoopOp>(input, input_size, output, output_size);
+ NoopOp* op = new (output) NoopOp;
+
+ PaintOpReader helper(input, input_size, options);
+ if (!helper.valid() || !op->IsValid()) {
+ op->~NoopOp();
+ return nullptr;
+ }
+
+ UpdateTypeAndSkip(op);
+ return op;
}
PaintOp* RestoreOp::Deserialize(const volatile void* input,
@@ -1106,7 +1186,16 @@ PaintOp* RestoreOp::Deserialize(const volatile void* input,
size_t output_size,
const DeserializeOptions& options) {
DCHECK_GE(output_size, sizeof(RestoreOp));
- return SimpleDeserialize<RestoreOp>(input, input_size, output, output_size);
+ RestoreOp* op = new (output) RestoreOp;
+
+ PaintOpReader helper(input, input_size, options);
+ if (!helper.valid() || !op->IsValid()) {
+ op->~RestoreOp();
+ return nullptr;
+ }
+
+ UpdateTypeAndSkip(op);
+ return op;
}
PaintOp* RotateOp::Deserialize(const volatile void* input,
@@ -1115,7 +1204,17 @@ PaintOp* RotateOp::Deserialize(const volatile void* input,
size_t output_size,
const DeserializeOptions& options) {
DCHECK_GE(output_size, sizeof(RotateOp));
- return SimpleDeserialize<RotateOp>(input, input_size, output, output_size);
+ RotateOp* op = new (output) RotateOp;
+
+ PaintOpReader helper(input, input_size, options);
+ helper.Read(&op->degrees);
+ if (!helper.valid() || !op->IsValid()) {
+ op->~RotateOp();
+ return nullptr;
+ }
+
+ UpdateTypeAndSkip(op);
+ return op;
}
PaintOp* SaveOp::Deserialize(const volatile void* input,
@@ -1124,7 +1223,16 @@ PaintOp* SaveOp::Deserialize(const volatile void* input,
size_t output_size,
const DeserializeOptions& options) {
DCHECK_GE(output_size, sizeof(SaveOp));
- return SimpleDeserialize<SaveOp>(input, input_size, output, output_size);
+ SaveOp* op = new (output) SaveOp;
+
+ PaintOpReader helper(input, input_size, options);
+ if (!helper.valid() || !op->IsValid()) {
+ op->~SaveOp();
+ return nullptr;
+ }
+
+ UpdateTypeAndSkip(op);
+ return op;
}
PaintOp* SaveLayerOp::Deserialize(const volatile void* input,
@@ -1152,8 +1260,18 @@ PaintOp* SaveLayerAlphaOp::Deserialize(const volatile void* input,
size_t output_size,
const DeserializeOptions& options) {
DCHECK_GE(output_size, sizeof(SaveLayerAlphaOp));
- return SimpleDeserialize<SaveLayerAlphaOp>(input, input_size, output,
- output_size);
+ SaveLayerAlphaOp* op = new (output) SaveLayerAlphaOp;
+
+ PaintOpReader helper(input, input_size, options);
+ helper.Read(&op->bounds);
+ helper.Read(&op->alpha);
+ if (!helper.valid() || !op->IsValid()) {
+ op->~SaveLayerAlphaOp();
+ return nullptr;
+ }
+
+ UpdateTypeAndSkip(op);
+ return op;
}
PaintOp* ScaleOp::Deserialize(const volatile void* input,
@@ -1163,7 +1281,18 @@ PaintOp* ScaleOp::Deserialize(const volatile void* input,
const DeserializeOptions& options) {
DCHECK_GE(output_size, sizeof(ScaleOp));
- return SimpleDeserialize<ScaleOp>(input, input_size, output, output_size);
+ ScaleOp* op = new (output) ScaleOp;
+
+ PaintOpReader helper(input, input_size, options);
+ helper.Read(&op->sx);
+ helper.Read(&op->sy);
+ if (!helper.valid() || !op->IsValid()) {
+ op->~ScaleOp();
+ return nullptr;
+ }
+
+ UpdateTypeAndSkip(op);
+ return op;
}
PaintOp* SetMatrixOp::Deserialize(const volatile void* input,
@@ -1172,10 +1301,17 @@ PaintOp* SetMatrixOp::Deserialize(const volatile void* input,
size_t output_size,
const DeserializeOptions& options) {
DCHECK_GE(output_size, sizeof(SetMatrixOp));
- auto* op =
- SimpleDeserialize<SetMatrixOp>(input, input_size, output, output_size);
- if (op)
- PaintOpReader::FixupMatrixPostSerialization(&op->matrix);
+ SetMatrixOp* op = new (output) SetMatrixOp;
+
+ PaintOpReader helper(input, input_size, options);
+ helper.Read(&op->matrix);
+ if (!helper.valid() || !op->IsValid()) {
+ op->~SetMatrixOp();
+ return nullptr;
+ }
+
+ UpdateTypeAndSkip(op);
+ PaintOpReader::FixupMatrixPostSerialization(&op->matrix);
return op;
}
@@ -1185,7 +1321,17 @@ PaintOp* SetNodeIdOp::Deserialize(const volatile void* input,
size_t output_size,
const DeserializeOptions& options) {
DCHECK_GE(output_size, sizeof(SetNodeIdOp));
- return SimpleDeserialize<SetNodeIdOp>(input, input_size, output, output_size);
+ SetNodeIdOp* op = new (output) SetNodeIdOp;
+
+ PaintOpReader helper(input, input_size, options);
+ helper.Read(&op->node_id);
+ if (!helper.valid() || !op->IsValid()) {
+ op->~SetNodeIdOp();
+ return nullptr;
+ }
+
+ UpdateTypeAndSkip(op);
+ return op;
}
PaintOp* TranslateOp::Deserialize(const volatile void* input,
@@ -1194,7 +1340,18 @@ PaintOp* TranslateOp::Deserialize(const volatile void* input,
size_t output_size,
const DeserializeOptions& options) {
DCHECK_GE(output_size, sizeof(TranslateOp));
- return SimpleDeserialize<TranslateOp>(input, input_size, output, output_size);
+ TranslateOp* op = new (output) TranslateOp;
+
+ PaintOpReader helper(input, input_size, options);
+ helper.Read(&op->dx);
+ helper.Read(&op->dy);
+ if (!helper.valid() || !op->IsValid()) {
+ op->~TranslateOp();
+ return nullptr;
+ }
+
+ UpdateTypeAndSkip(op);
+ return op;
}
void AnnotateOp::Raster(const AnnotateOp* op,
diff --git a/chromium/cc/paint/paint_op_buffer.h b/chromium/cc/paint/paint_op_buffer.h
index d327fe6fc3f..24d16fddd4d 100644
--- a/chromium/cc/paint/paint_op_buffer.h
+++ b/chromium/cc/paint/paint_op_buffer.h
@@ -48,6 +48,7 @@ class CC_PAINT_EXPORT ThreadsafeMatrix : public SkMatrix {
explicit ThreadsafeMatrix(const SkMatrix& matrix) : SkMatrix(matrix) {
(void)getType();
}
+ ThreadsafeMatrix() { (void)getType(); }
};
class CC_PAINT_EXPORT ThreadsafePath : public SkPath {
@@ -401,6 +402,9 @@ class CC_PAINT_EXPORT ClipRectOp final : public PaintOp {
SkRect rect;
SkClipOp op;
bool antialias;
+
+ private:
+ ClipRectOp() : PaintOp(kType) {}
};
class CC_PAINT_EXPORT ClipRRectOp final : public PaintOp {
@@ -419,6 +423,9 @@ class CC_PAINT_EXPORT ClipRRectOp final : public PaintOp {
SkRRect rrect;
SkClipOp op;
bool antialias;
+
+ private:
+ ClipRRectOp() : PaintOp(kType) {}
};
class CC_PAINT_EXPORT ConcatOp final : public PaintOp {
@@ -433,6 +440,9 @@ class CC_PAINT_EXPORT ConcatOp final : public PaintOp {
HAS_SERIALIZATION_FUNCTIONS();
ThreadsafeMatrix matrix;
+
+ private:
+ ConcatOp() : PaintOp(kType) {}
};
class CC_PAINT_EXPORT CustomDataOp final : public PaintOp {
@@ -448,6 +458,9 @@ class CC_PAINT_EXPORT CustomDataOp final : public PaintOp {
// Stores user defined id as a placeholder op.
uint32_t id;
+
+ private:
+ CustomDataOp() : PaintOp(kType) {}
};
class CC_PAINT_EXPORT DrawColorOp final : public PaintOp {
@@ -465,6 +478,9 @@ class CC_PAINT_EXPORT DrawColorOp final : public PaintOp {
SkColor color;
SkBlendMode mode;
+
+ private:
+ DrawColorOp() : PaintOp(kType) {}
};
class CC_PAINT_EXPORT DrawDRRectOp final : public PaintOpWithFlags {
@@ -808,6 +824,9 @@ class CC_PAINT_EXPORT RotateOp final : public PaintOp {
HAS_SERIALIZATION_FUNCTIONS();
SkScalar degrees;
+
+ private:
+ RotateOp() : PaintOp(kType) {}
};
class CC_PAINT_EXPORT SaveOp final : public PaintOp {
@@ -857,6 +876,9 @@ class CC_PAINT_EXPORT SaveLayerAlphaOp final : public PaintOp {
SkRect bounds;
uint8_t alpha;
+
+ private:
+ SaveLayerAlphaOp() : PaintOp(kType) {}
};
class CC_PAINT_EXPORT ScaleOp final : public PaintOp {
@@ -896,6 +918,9 @@ class CC_PAINT_EXPORT SetMatrixOp final : public PaintOp {
HAS_SERIALIZATION_FUNCTIONS();
ThreadsafeMatrix matrix;
+
+ private:
+ SetMatrixOp() : PaintOp(kType) {}
};
class CC_PAINT_EXPORT SetNodeIdOp final : public PaintOp {
@@ -910,6 +935,9 @@ class CC_PAINT_EXPORT SetNodeIdOp final : public PaintOp {
HAS_SERIALIZATION_FUNCTIONS();
int node_id;
+
+ private:
+ SetNodeIdOp() : PaintOp(kType) {}
};
class CC_PAINT_EXPORT TranslateOp final : public PaintOp {
@@ -925,6 +953,9 @@ class CC_PAINT_EXPORT TranslateOp final : public PaintOp {
SkScalar dx;
SkScalar dy;
+
+ private:
+ TranslateOp() : PaintOp(kType) {}
};
#undef HAS_SERIALIZATION_FUNCTIONS
diff --git a/chromium/cc/paint/paint_op_reader.h b/chromium/cc/paint/paint_op_reader.h
index 9de213ec7f0..e20611747cb 100644
--- a/chromium/cc/paint/paint_op_reader.h
+++ b/chromium/cc/paint/paint_op_reader.h
@@ -99,6 +99,15 @@ class CC_PAINT_EXPORT PaintOpReader {
}
*quality = static_cast<SkFilterQuality>(value);
}
+ void Read(SkBlendMode* blend_mode) {
+ uint8_t value = 0u;
+ Read(&value);
+ if (value > static_cast<uint8_t>(SkBlendMode::kLastMode)) {
+ SetInvalid();
+ return;
+ }
+ *blend_mode = static_cast<SkBlendMode>(value);
+ }
void Read(bool* data) {
uint8_t value = 0u;
Read(&value);
diff --git a/chromium/cc/paint/paint_op_writer.h b/chromium/cc/paint/paint_op_writer.h
index 187d697796b..a05ae667af6 100644
--- a/chromium/cc/paint/paint_op_writer.h
+++ b/chromium/cc/paint/paint_op_writer.h
@@ -75,6 +75,9 @@ class CC_PAINT_EXPORT PaintOpWriter {
void Write(SkFilterQuality filter_quality) {
Write(static_cast<uint8_t>(filter_quality));
}
+ void Write(SkBlendMode blend_mode) {
+ Write(static_cast<uint8_t>(blend_mode));
+ }
void Write(bool data) { Write(static_cast<uint8_t>(data)); }
// Aligns the memory to the given alignment.