From 338ef4aa6cf39be4761b39b25ce5dec829af535b Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Tue, 8 Dec 2015 17:48:17 -0800
Subject: [PATCH] fix bug MIN_VALUE bug in ltoa and int64toa and add tests

---
 src/core/support/string.c       | 26 +++++++++++------
 test/core/support/string_test.c | 49 +++++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+), 8 deletions(-)

diff --git a/src/core/support/string.c b/src/core/support/string.c
index fad0b4008b..bebeeb9513 100644
--- a/src/core/support/string.c
+++ b/src/core/support/string.c
@@ -153,6 +153,7 @@ void gpr_reverse_bytes(char *str, int len) {
 }
 
 int gpr_ltoa(long value, char *string) {
+  unsigned long uval;
   int i = 0;
   int neg = value < 0;
 
@@ -162,10 +163,14 @@ int gpr_ltoa(long value, char *string) {
     return 1;
   }
 
-  if (neg) value = -value;
-  while (value) {
-    string[i++] = (char)('0' + value % 10);
-    value /= 10;
+  if (neg) {
+    uval = -value;
+  } else {
+    uval = value;
+  }
+  while (uval) {
+    string[i++] = (char)('0' + uval % 10);
+    uval /= 10;
   }
   if (neg) string[i++] = '-';
   gpr_reverse_bytes(string, i);
@@ -174,6 +179,7 @@ int gpr_ltoa(long value, char *string) {
 }
 
 int gpr_int64toa(gpr_int64 value, char *string) {
+  gpr_uint64 uval;
   int i = 0;
   int neg = value < 0;
 
@@ -183,10 +189,14 @@ int gpr_int64toa(gpr_int64 value, char *string) {
     return 1;
   }
 
-  if (neg) value = -value;
-  while (value) {
-    string[i++] = (char)('0' + value % 10);
-    value /= 10;
+  if (neg) {
+    uval = -value;
+  } else {
+    uval = value;
+  }
+  while (uval) {
+    string[i++] = (char)('0' + uval % 10);
+    uval /= 10;
   }
   if (neg) string[i++] = '-';
   gpr_reverse_bytes(string, i);
diff --git a/test/core/support/string_test.c b/test/core/support/string_test.c
index f62cbe3435..b4024fb799 100644
--- a/test/core/support/string_test.c
+++ b/test/core/support/string_test.c
@@ -286,6 +286,53 @@ static void test_strsplit(void) {
   gpr_free(parts);
 }
 
+test_ltoa() {
+  char *str;
+  char buf[GPR_LTOA_MIN_BUFSIZE];
+
+  LOG_TEST_NAME("test_ltoa");
+
+  /* zero */
+  GPR_ASSERT(1 == gpr_ltoa(0, buf));
+  GPR_ASSERT(0 == strcmp("0", buf));
+
+  /* positive number */
+  GPR_ASSERT(3 == gpr_ltoa(123, buf));
+  GPR_ASSERT(0 == strcmp("123", buf));
+
+  /* negative number */
+  GPR_ASSERT(6 == gpr_ltoa(-12345, buf));
+  GPR_ASSERT(0 == strcmp("-12345", buf));
+
+  /* large negative - we don't know the size of long in advance */
+  GPR_ASSERT(gpr_asprintf(&str, "%lld", (long long)LONG_MIN));
+  GPR_ASSERT(strlen(str) == gpr_ltoa(LONG_MIN, buf));
+  GPR_ASSERT(0 == strcmp(str, buf));
+  gpr_free(str);
+}
+
+test_int64toa() {
+  char buf[GPR_INT64TOA_MIN_BUFSIZE];
+
+  LOG_TEST_NAME("test_int64toa");
+
+  /* zero */
+  GPR_ASSERT(1 == gpr_int64toa(0, buf));
+  GPR_ASSERT(0 == strcmp("0", buf));
+
+  /* positive */
+  GPR_ASSERT(3 == gpr_int64toa(123, buf));
+  GPR_ASSERT(0 == strcmp("123", buf));
+
+  /* large positive */
+  GPR_ASSERT(19 == gpr_int64toa(9223372036854775807LL, buf));
+  GPR_ASSERT(0 == strcmp("9223372036854775807", buf));
+
+  /* large negative */
+  GPR_ASSERT(20 == gpr_int64toa(-9223372036854775808LL, buf));
+  GPR_ASSERT(0 == strcmp("-9223372036854775808", buf));
+}
+
 int main(int argc, char **argv) {
   grpc_test_init(argc, argv);
   test_strdup();
@@ -296,5 +343,7 @@ int main(int argc, char **argv) {
   test_strjoin();
   test_strjoin_sep();
   test_strsplit();
+  test_ltoa();
+  test_int64toa();
   return 0;
 }
-- 
GitLab