[Sanitizer] More fixes to scanf interceptor: stub support for %s, support for %[...
authorAlexey Samsonov <samsonov@google.com>
Fri, 25 Jan 2013 15:26:19 +0000 (15:26 +0000)
committerAlexey Samsonov <samsonov@google.com>
Fri, 25 Jan 2013 15:26:19 +0000 (15:26 +0000)
llvm-svn: 173451

compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_scanf.inc
compiler-rt/lib/sanitizer_common/tests/sanitizer_scanf_interceptor_test.cc

index 72ff34a..f6433f9 100644 (file)
@@ -23,6 +23,8 @@ struct ScanfSpec {
 
 // One-letter specs.
 static const ScanfSpec scanf_specs[] = {
+  {'s', 1},  // FIXME: This is incorrect, we should check the actual number
+             // of bytes written to the string.
   {'c', sizeof(char)},
   {'p', sizeof(void *)},
   {'e', sizeof(float)},
@@ -98,6 +100,8 @@ static void scanf_common(void *ctx, const char *format, va_list ap_const) {
     }
     ++p;
     if (*p == '*' || *p == '%' || *p == '\0') {
+      // FIXME: Bailing out for (p == "*") is wrong, we should parse the
+      // directive to the end.
       if (*p != '\0')
         ++p;
       continue;
@@ -120,6 +124,23 @@ static void scanf_common(void *ctx, const char *format, va_list ap_const) {
       }
     }
 
+    if (*p == '[') {
+      // Search for the closing bracket. It is ignored if it goes right after
+      // the opening bracket or after ^.
+      p++;
+      if (*p == ']') {
+        p++;
+      } else if (*p == '^' && *(p+1) == ']') {
+        p += 2;
+      }
+      while (*p != ']')
+        p++;
+      // +1 for the \0 at the end.
+      field_width++;
+      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, va_arg(aq, void*), field_width);
+      continue;
+    }
+
     if (*p == 'L' || *p == 'q') {
       ++p;
       size = match_spec(scanf_llspecs, scanf_llspecs_cnt, *p);
index e8bd195..a1daa4e 100644 (file)
@@ -86,4 +86,11 @@ TEST(SanitizerCommonInterceptors, Scanf) {
   testScanf("%*d", 0);
 
   testScanf("%4d%8f%c", 3, I, F, C);
+  testScanf("%s%d", 2, 1, I);
+  testScanf("%[abc]", 1, 1);
+  testScanf("%4[bcdef]", 1, 5);
+  testScanf("%[]]", 1, 1);
+  testScanf("%8[^]%d0-9-]%c", 2, 9, C);
+
+  testScanf("%*[^:]%n:%d:%1[ ]%n", 4, I, I, 2, I);
 }