Repository: KhronosGroup/SPIRV-Tools (language: python)

Issue:
OSS-Fuzz: stack overflow in spirv-as
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=39636

This might turn out to be due to a very large example.


Discussion / hints:

Fix patch:
diff --git a/source/text_handler.cpp b/source/text_handler.cpp
index fe12a26e38..15c1741f67 100644
--- a/source/text_handler.cpp
+++ b/source/text_handler.cpp
@@ -62,28 +62,29 @@ spv_result_t advanceLine(spv_text text, spv_position position) {
 // parameters, its the users responsibility to ensure these are non null.
 spv_result_t advance(spv_text text, spv_position position) {
   // NOTE: Consume white space, otherwise don't advance.
-  if (position->index >= text->length) return SPV_END_OF_STREAM;
-  switch (text->str[position->index]) {
-    case '\0':
-      return SPV_END_OF_STREAM;
-    case ';':
-      if (spv_result_t error = advanceLine(text, position)) return error;
-      return advance(text, position);
-    case ' ':
-    case '\t':
-    case '\r':
-      position->column++;
-      position->index++;
-      return advance(text, position);
-    case '\n':
-      position->column = 0;
-      position->line++;
-      position->index++;
-      return advance(text, position);
-    default:
-      break;
+  while (true) {
+    if (position->index >= text->length) return SPV_END_OF_STREAM;
+    switch (text->str[position->index]) {
+      case '\0':
+        return SPV_END_OF_STREAM;
+      case ';':
+        if (spv_result_t error = advanceLine(text, position)) return error;
+        continue;
+      case ' ':
+      case '\t':
+      case '\r':
+        position->column++;
+        position->index++;
+        continue;
+      case '\n':
+        position->column = 0;
+        position->line++;
+        position->index++;
+        continue;
+      default:
+        return SPV_SUCCESS;
+    }
   }
-  return SPV_SUCCESS;
 }
 
 // Fetches the next word from the given text stream starting from the given


Test patch:
diff --git a/test/text_advance_test.cpp b/test/text_advance_test.cpp
index 9de77a8362..0d23ab1c1a 100644
--- a/test/text_advance_test.cpp
+++ b/test/text_advance_test.cpp
@@ -130,5 +130,14 @@ TEST(TextAdvance, SkipOverCRLFs) {
   EXPECT_EQ(2u, pos.line);
   EXPECT_EQ(4u, pos.index);
 }
+
+TEST(TextAdvance, HandleLotsOfWhitespace) {
+  std::string lots_of_spaces(10000, ' ');
+  lots_of_spaces += "Word";
+  const auto pos = PositionAfterAdvance(lots_of_spaces.c_str());
+  EXPECT_EQ(10000u, pos.column);
+  EXPECT_EQ(0u, pos.line);
+  EXPECT_EQ(10000u, pos.index);
+}
 }  // namespace
 }  // namespace spvtools