Browse Source

inet_ntop: add typecast to silence Coverity

CID 1024653:  Integer handling issues  (SIGN_EXTENSION)

Suspicious implicit sign extension: "src[i]" with type "unsigned char
const" (8 bits, unsigned) is promoted in "src[i] << (1 - i % 2 << 3)" to
type "int" (32 bits, signed), then sign-extended to type "unsigned long"
(64 bits, unsigned).  If "src[i] << (1 - i % 2 << 3)" is greater than
0x7FFFFFFF, the upper bits of the result will all be 1.

111         words[i/2] |= (src[i] << ((1 - (i % 2)) << 3));

The value will not be greater than 0x7FFFFFFF so this still cannot
happen.

Also, switch to ints here instead of longs. The values stored are 16 bit
so at least no need to use 64 bit variables. Also, longs are 32 bit on
some platforms so this logic still needs to work with 32 bits.

Closes #11960
Daniel Stenberg 7 months ago
parent
commit
1f92db87e0
1 changed files with 5 additions and 5 deletions
  1. 5 5
      lib/inet_ntop.c

+ 5 - 5
lib/inet_ntop.c

@@ -96,10 +96,10 @@ static char *inet_ntop6 (const unsigned char *src, char *dst, size_t size)
   char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
   char *tp;
   struct {
-    long base;
-    long len;
+    int base;
+    int len;
   } best, cur;
-  unsigned long words[IN6ADDRSZ / INT16SZ];
+  unsigned int words[IN6ADDRSZ / INT16SZ];
   int i;
 
   /* Preprocess:
@@ -108,7 +108,7 @@ static char *inet_ntop6 (const unsigned char *src, char *dst, size_t size)
    */
   memset(words, '\0', sizeof(words));
   for(i = 0; i < IN6ADDRSZ; i++)
-    words[i/2] |= (src[i] << ((1 - (i % 2)) << 3));
+    words[i/2] |= ((unsigned int)src[i] << ((1 - (i % 2)) << 3));
 
   best.base = -1;
   cur.base  = -1;
@@ -159,7 +159,7 @@ static char *inet_ntop6 (const unsigned char *src, char *dst, size_t size)
       tp += strlen(tp);
       break;
     }
-    tp += msnprintf(tp, 5, "%lx", words[i]);
+    tp += msnprintf(tp, 5, "%x", words[i]);
   }
 
   /* Was it a trailing run of 0x00's?