Bug 1254061 - Rewrite nsHttp::ParseInt64 using strtoll. r=mcmanus, a=ritu
authorValentin Gosu <valentin.gosu@gmail.com>
Wed, 23 Mar 2016 13:42:12 +0100
changeset 351468 dcb34dd977943c61c6dfe2d2754c93f8e9d0c2a9
parent 351467 679f5793569e51e9fd54d68664bdd6e7a949f07b
child 351469 78b2c5c12cce9ae35fd317dcda5466144cad799b
push id15502
push userahunt@mozilla.com
push dateThu, 14 Apr 2016 20:27:48 +0000
reviewersmcmanus, ritu
bugs1254061
milestone47.0a2
Bug 1254061 - Rewrite nsHttp::ParseInt64 using strtoll. r=mcmanus, a=ritu MozReview-Commit-ID: FXjTBah4OSd * * * [mq]: test MozReview-Commit-ID: 5YT1jWVb21K
netwerk/protocol/http/nsHttp.cpp
--- a/netwerk/protocol/http/nsHttp.cpp
+++ b/netwerk/protocol/http/nsHttp.cpp
@@ -7,16 +7,17 @@
 // HttpLog.h should generally be included first
 #include "HttpLog.h"
 
 #include "nsHttp.h"
 #include "PLDHashTable.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/HashFunctions.h"
 #include "nsCRT.h"
+#include <errno.h>
 
 namespace mozilla {
 namespace net {
 
 // define storage for all atoms
 #define HTTP_ATOM(_name, _value) nsHttpAtom nsHttp::_name = { _value };
 #include "nsHttpAtomList.h"
 #undef HTTP_ATOM
@@ -290,29 +291,35 @@ nsHttp::FindToken(const char *input, con
     }
 
     return nullptr;
 }
 
 bool
 nsHttp::ParseInt64(const char *input, const char **next, int64_t *r)
 {
-    const char *start = input;
-    *r = 0;
-    while (*input >= '0' && *input <= '9') {
-        int64_t next = 10 * (*r) + (*input - '0');
-        if (next < *r) // overflow?
-            return false;
-        *r = next;
-        ++input;
+    MOZ_ASSERT(input);
+    MOZ_ASSERT(r);
+
+    char *end = nullptr;
+    errno = 0; // Clear errno to make sure its value is set by strtoll
+    int64_t value = strtoll(input, &end, /* base */ 10);
+
+    // Fail if: - the parsed number overflows.
+    //          - the end points to the start of the input string.
+    //          - we parsed a negative value. Consumers don't expect that.
+    if (errno != 0 || end == input || value < 0) {
+        LOG(("nsHttp::ParseInt64 value=%ld errno=%d", value, errno));
+        return false;
     }
-    if (input == start) // nothing parsed?
-        return false;
-    if (next)
-        *next = input;
+
+    if (next) {
+        *next = end;
+    }
+    *r = value;
     return true;
 }
 
 bool
 nsHttp::IsPermanentRedirect(uint32_t httpStatus)
 {
   return httpStatus == 301 || httpStatus == 308;
 }