[compiler-rt] r199724 - [Sanitizer] Support %.*s in internal printf implementation. Patch by Yuri Gribov.

Alexey Samsonov samsonov at google.com
Tue Jan 21 02:59:44 PST 2014


Author: samsonov
Date: Tue Jan 21 04:59:44 2014
New Revision: 199724

URL: http://llvm.org/viewvc/llvm-project?rev=199724&view=rev
Log:
[Sanitizer] Support %.*s in internal printf implementation. Patch by Yuri Gribov.

Modified:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_printf.cc
    compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_printf_test.cc

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_printf.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_printf.cc?rev=199724&r1=199723&r2=199724&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_printf.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_printf.cc Tue Jan 21 04:59:44 2014
@@ -95,11 +95,14 @@ static int AppendSignedDecimal(char **bu
                       minimal_num_length, pad_with_zero, negative);
 }
 
-static int AppendString(char **buff, const char *buff_end, const char *s) {
+static int AppendString(char **buff, const char *buff_end, int precision,
+                        const char *s) {
   if (s == 0)
     s = "<null>";
   int result = 0;
   for (; *s; s++) {
+    if (precision >= 0 && result >= precision)
+      break;
     result += AppendChar(buff, buff_end, *s);
   }
   return result;
@@ -107,7 +110,7 @@ static int AppendString(char **buff, con
 
 static int AppendPointer(char **buff, const char *buff_end, u64 ptr_value) {
   int result = 0;
-  result += AppendString(buff, buff_end, "0x");
+  result += AppendString(buff, buff_end, -1, "0x");
   result += AppendUnsigned(buff, buff_end, ptr_value, 16,
                            (SANITIZER_WORDSIZE == 64) ? 12 : 8, true);
   return result;
@@ -116,7 +119,7 @@ static int AppendPointer(char **buff, co
 int VSNPrintf(char *buff, int buff_length,
               const char *format, va_list args) {
   static const char *kPrintfFormatsHelp =
-    "Supported Printf formats: %([0-9]*)?(z|ll)?{d,u,x}; %p; %s; %c\n";
+    "Supported Printf formats: %([0-9]*)?(z|ll)?{d,u,x}; %p; %(\\.\\*)?s; %c\n";
   RAW_CHECK(format);
   RAW_CHECK(buff_length > 0);
   const char *buff_end = &buff[buff_length - 1];
@@ -136,6 +139,12 @@ int VSNPrintf(char *buff, int buff_lengt
         width = width * 10 + *cur++ - '0';
       }
     }
+    bool have_precision = (cur[0] == '.' && cur[1] == '*');
+    int precision = -1;
+    if (have_precision) {
+      cur += 2;
+      precision = va_arg(args, int);
+    }
     bool have_z = (*cur == 'z');
     cur += have_z;
     bool have_ll = !have_z && (cur[0] == 'l' && cur[1] == 'l');
@@ -143,6 +152,8 @@ int VSNPrintf(char *buff, int buff_lengt
     s64 dval;
     u64 uval;
     bool have_flags = have_width | have_z | have_ll;
+    // Only %s supports precision for now
+    CHECK(!(precision >= 0 && *cur != 's'));
     switch (*cur) {
       case 'd': {
         dval = have_ll ? va_arg(args, s64)
@@ -168,7 +179,7 @@ int VSNPrintf(char *buff, int buff_lengt
       }
       case 's': {
         RAW_CHECK_MSG(!have_flags, kPrintfFormatsHelp);
-        result += AppendString(&buff, buff_end, va_arg(args, char*));
+        result += AppendString(&buff, buff_end, precision, va_arg(args, char*));
         break;
       }
       case 'c': {

Modified: compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_printf_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_printf_test.cc?rev=199724&r1=199723&r2=199724&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_printf_test.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_printf_test.cc Tue Jan 21 04:59:44 2014
@@ -135,4 +135,14 @@ TEST(Printf, Padding) {
   TestAgainstLibc<int>("%03d - %03d", -12, -1234);
 }
 
+TEST(Printf, Precision) {
+  char buf[1024];
+  uptr len = internal_snprintf(buf, sizeof(buf), "%.*s", 3, "12345");
+  EXPECT_EQ(3U, len);
+  EXPECT_STREQ("123", buf);
+  len = internal_snprintf(buf, sizeof(buf), "%.*s", 6, "12345");
+  EXPECT_EQ(5U, len);
+  EXPECT_STREQ("12345", buf);
+}
+
 }  // namespace __sanitizer





More information about the llvm-commits mailing list