8383#include " src/tint/lang/core/type/storage_texture.h"
8484#include " src/tint/lang/core/type/u32.h"
8585#include " src/tint/lang/core/type/void.h"
86+ #include " src/tint/utils/constants/internal_limits.h"
8687#include " src/tint/utils/macros/compiler.h"
8788#include " src/tint/utils/rtti/switch.h"
8889
@@ -95,13 +96,16 @@ namespace {
9596struct Encoder {
9697 const Module& mod_in_;
9798 pb::Module& mod_out_;
99+
98100 Hashmap<const core::ir::Function*, uint32_t , 32 > functions_{};
99101 Hashmap<const core::ir::Block*, uint32_t , 32 > blocks_{};
100102 Hashmap<const core::type::Type*, uint32_t , 32 > types_{};
101103 Hashmap<const core::ir::Value*, uint32_t , 32 > values_{};
102104 Hashmap<const core::constant::Value*, uint32_t , 32 > constant_values_{};
103105
104- void Encode () {
106+ diag::List diags_{};
107+
108+ Result<SuccessType> Encode () {
105109 // Encode all user-declared structures first. This is to ensure that the IR disassembly
106110 // (which prints structure types first) does not reorder after encoding and decoding.
107111 for (auto * ty : mod_in_.Types ()) {
@@ -119,8 +123,16 @@ struct Encoder {
119123 PopulateFunction (fns_out[i], mod_in_.functions [i]);
120124 }
121125 mod_out_.set_root_block (Block (mod_in_.root_block ));
126+
127+ if (diags_.ContainsErrors ()) {
128+ return Failure{std::move (diags_)};
129+ }
130+ return Success;
122131 }
123132
133+ // / Adds a new error to the diagnostics and returns a reference to it
134+ diag::Diagnostic& Error () { return diags_.AddError (Source{}); }
135+
124136 // //////////////////////////////////////////////////////////////////////////
125137 // Functions
126138 // //////////////////////////////////////////////////////////////////////////
@@ -477,7 +489,13 @@ struct Encoder {
477489 array_out.set_stride (array_in->Stride ());
478490 tint::Switch (
479491 array_in->Count (), //
480- [&](const core::type::ConstantArrayCount* c) { array_out.set_count (c->value ); },
492+ [&](const core::type::ConstantArrayCount* c) {
493+ array_out.set_count (c->value );
494+ if (c->value >= internal_limits::kMaxArrayElementCount ) {
495+ Error () << " array count (" << c->value << " ) must be less than "
496+ << internal_limits::kMaxArrayElementCount ;
497+ }
498+ },
481499 [&](const core::type::RuntimeArrayCount*) { array_out.set_count (0 ); },
482500 TINT_ICE_ON_NO_MATCH);
483501 }
@@ -647,6 +665,10 @@ struct Encoder {
647665 void ConstantValueSplat (pb::ConstantValueSplat& splat_out,
648666 const core::constant::Splat* splat_in) {
649667 splat_out.set_type (Type (splat_in->type ));
668+ if (DAWN_UNLIKELY (splat_in->count > internal_limits::kMaxArrayConstructorElements )) {
669+ Error () << " array constructor has excessive number of elements (>"
670+ << internal_limits::kMaxArrayConstructorElements << " )" ;
671+ }
650672 splat_out.set_elements (ConstantValue (splat_in->el ));
651673 splat_out.set_count (static_cast <uint32_t >(splat_in->count ));
652674 }
@@ -1220,23 +1242,29 @@ struct Encoder {
12201242
12211243} // namespace
12221244
1223- std::unique_ptr<pb::Module> EncodeToProto (const Module& mod_in) {
1245+ Result< std::unique_ptr<pb::Module> > EncodeToProto (const Module& mod_in) {
12241246 GOOGLE_PROTOBUF_VERIFY_VERSION;
12251247
12261248 pb::Module mod_out;
1227- Encoder{mod_in, mod_out}.Encode ();
1249+ auto res = Encoder{mod_in, mod_out}.Encode ();
1250+ if (res != Success) {
1251+ return res.Failure ();
1252+ }
12281253
12291254 return std::make_unique<pb::Module>(mod_out);
12301255}
12311256
12321257Result<Vector<std::byte, 0 >> EncodeToBinary (const Module& mod_in) {
12331258 auto mod_out = EncodeToProto (mod_in);
1259+ if (mod_out != Success) {
1260+ return mod_out.Failure ();
1261+ }
12341262
12351263 Vector<std::byte, 0 > buffer;
1236- size_t len = mod_out->ByteSizeLong ();
1264+ size_t len = mod_out. Get () ->ByteSizeLong ();
12371265 buffer.Resize (len);
12381266 if (len > 0 ) {
1239- if (!mod_out->SerializeToArray (&buffer[0 ], static_cast <int >(len))) {
1267+ if (!mod_out. Get () ->SerializeToArray (&buffer[0 ], static_cast <int >(len))) {
12401268 return Failure{" failed to serialize protobuf" };
12411269 }
12421270 }
0 commit comments