[tint][ir] Reject malformed strings in IR binary decode

Fixes: 367415886
Change-Id: I67a3478bbab13fff8284c7b8815e293a464f120b
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/206718
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Auto-Submit: Ryan Harrison <rharrison@chromium.org>
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
diff --git a/src/tint/lang/core/ir/binary/decode.cc b/src/tint/lang/core/ir/binary/decode.cc
index b81d19a..8397b25 100644
--- a/src/tint/lang/core/ir/binary/decode.cc
+++ b/src/tint/lang/core/ir/binary/decode.cc
@@ -241,7 +241,12 @@
 
     void PopulateFunction(ir::Function* fn_out, const pb::Function& fn_in) {
         if (!fn_in.name().empty()) {
-            mod_out_.SetName(fn_out, fn_in.name());
+            if (DAWN_UNLIKELY(fn_in.name().find('\0') != std::string::npos)) {
+                Error() << "function name '" << fn_in.name()
+                        << "' contains '\\0' before end of the string";
+            } else {
+                mod_out_.SetName(fn_out, fn_in.name());
+            }
         }
         fn_out->SetReturnType(Type(fn_in.return_type()));
         if (fn_in.has_pipeline_stage()) {
@@ -940,6 +945,11 @@
         auto* type = Type(res_in.type());
         auto* res_out = b.InstructionResult(type);
         if (!res_in.name().empty()) {
+            if (DAWN_UNLIKELY(res_in.name().find('\0') != std::string::npos)) {
+                Error() << "result name '" << res_in.name()
+                        << "' contains '\\0' before end of the string";
+                return nullptr;
+            }
             mod_out_.SetName(res_out, res_in.name());
         }
         return res_out;
@@ -949,6 +959,11 @@
         auto* type = Type(param_in.type());
         auto* param_out = b.FunctionParam(type);
         if (!param_in.name().empty()) {
+            if (DAWN_UNLIKELY(param_in.name().find('\0') != std::string::npos)) {
+                Error() << "param name '" << param_in.name()
+                        << "' contains '\\0' before end of the string";
+                return nullptr;
+            }
             mod_out_.SetName(param_out, param_in.name());
         }
 
@@ -982,6 +997,11 @@
         auto* type = Type(param_in.type());
         auto* param_out = b.BlockParam(type);
         if (!param_in.name().empty()) {
+            if (DAWN_UNLIKELY(param_in.name().find('\0') != std::string::npos)) {
+                Error() << "param name '" << param_in.name()
+                        << "' contains '\\0' before end of the string";
+                return nullptr;
+            }
             mod_out_.SetName(param_out, param_in.name());
         }
         return param_out;