Copilot commented on code in PR #3786:
URL: https://github.com/apache/thrift/pull/3786#discussion_r3959842653


##########
compiler/cpp/src/thrift/thriftl.ll:
##########
@@ -290,14 +290,21 @@ literal_begin (['\"])
     int ch = yyinput();
     switch (ch) {
       case EOF:
-        yyerror("End of file while read string at %d\n", yylineno);
+        yyerror("End of file while reading string at %d\n", yylineno);
         exit(1);
       case '\n':
-        yyerror("End of line while read string at %d\n", yylineno - 1);
+        yyerror("End of line while reading string at %d\n", yylineno - 1);
         exit(1);
       case '\\':
         ch = yyinput();
         switch (ch) {
+          // Flex yyinput() returns zero at end of input.
+          case 0:
+            yyerror("End of file while reading string at %d\n", yylineno);
+            exit(1);

Review Comment:
   Treating `yyinput()` returning `0` as end-of-file can misdiagnose (or 
prematurely terminate on) a literal NUL byte after a backslash. If NUL is 
possible in scanned input (e.g., via `yy_scan_bytes`), this branches to an EOF 
message instead of reporting an invalid escape byte (0x00). Consider 
distinguishing true end-of-buffer from a NUL byte (e.g., using Flex 
mechanisms/guards) or treating `0` here as `Invalid escape byte 0x00` for 
correctness.



##########
compiler/cpp/src/thrift/thriftl.ll:
##########
@@ -317,7 +324,12 @@ literal_begin (['\"])
             result.push_back('\\');
             continue;
           default:
-            yyerror("Bad escape character\n");
+            if (ch >= 0x20 && ch <= 0x7e) {
+              yyerror("Invalid escape sequence '\\%c'. Use \\\\ for a literal 
backslash.\n", ch);
+            } else {
+              yyerror("Invalid escape byte 0x%02X. Use \\\\ for a literal 
backslash.\n",
+                      static_cast<unsigned int>(ch));

Review Comment:
   `ch` is an `int` from `yyinput()` and can be negative depending on 
platform/char signedness or scanner internals. In that scenario, the 
printable-range check is wrong and `static_cast<unsigned int>(ch)` can yield 
values like `0xFFFFFFFF` instead of the intended single-byte hex. Normalize to 
an unsigned byte before comparisons/formatting (e.g., cast to `unsigned char` 
and format that value) to ensure diagnostics are correct for bytes >= 0x80 and 
any negative values.



##########
compiler/cpp/tests/thrift_test_parser_support.cc:
##########
@@ -46,11 +46,21 @@ void yyerror(const char* fmt, ...) {
   std::fprintf(stderr, "[ERROR:%s:%d] ", g_curpath.c_str(), yylineno);
   va_list args;
   va_start(args, fmt);
-  std::vfprintf(stderr, fmt, args);
+  va_list size_args;
+  va_copy(size_args, args);
+  const int size = std::vsnprintf(nullptr, 0, fmt, size_args);
+  va_end(size_args);
+  if (size < 0) {
+    va_end(args);
+    throw std::runtime_error("Unable to format thrift parser error");
+  }
+  std::vector<char> message(size + 1);
+  std::vsnprintf(message.data(), message.size(), fmt, args);
   va_end(args);
+  std::fwrite(message.data(), 1, static_cast<size_t>(size), stderr);
   std::fprintf(stderr, "\n");
 
-  throw std::runtime_error("thrift parser error");
+  throw std::runtime_error(std::string(message.data(), 
static_cast<size_t>(size)));

Review Comment:
   Two issues here: (1) the return value of the second `vsnprintf` call is 
ignored, so formatting errors (or unexpected size changes) won’t be detected 
and could lead to throwing/printing a partially formatted message; consider 
checking that return value and failing deterministically if it’s negative. (2) 
`yyerror` unconditionally prints an extra newline via `fprintf(\"\\n\")`, but 
many call sites already include `\\n` in the format string (including the new 
lexer messages), which will produce double blank lines on stderr; consider 
enforcing a single newline policy (either remove embedded `\\n` from call sites 
or only print the extra newline when the formatted message doesn’t already end 
with one).



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to