]> Sergey Matveev's repositories - dht-bootstrap.git/commitdiff
Stricter integers parsing
authorSergey Matveev <stargrave@stargrave.org>
Sat, 12 Nov 2022 08:33:23 +0000 (11:33 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Sat, 12 Nov 2022 08:35:37 +0000 (11:35 +0300)
CHANGES
dht-bootstrap.c

diff --git a/CHANGES b/CHANGES
index b1c71818b4da1edf134a75c3670384120a4c4131..fd07a402c95f4bd947cb2b7fc8bc6ae27e2c2851 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -3,6 +3,7 @@
   * Privilege-separated packets sender
   * FreeBSD Capsicum sandboxing
   * poll() replaced with kqueue()
+  * stricter bencoded integers parser
 
 2022-11-09:
 
index 9b6f714a7324df36078c6006464eea1fcc3bfb9c..977d966840b65b4162bf006b5e7abec0a4063ef1 100644 (file)
@@ -20,6 +20,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 */
 
+#include <ctype.h>
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -121,6 +122,20 @@ getAddr(const struct sockaddr *sa, const socklen_t saLen)
     return addr;
 }
 
+static bool
+stricttol(const char *p, unsigned long *l, char **q)
+{
+    if ((isdigit((int)(p[0])) == 0) || (p[0] == '0'))
+        return false;
+    errno = 0;
+    *l = strtoul(p, q, 10);
+    if (errno != 0) {
+        perror("strtoul()");
+        return false;
+    }
+    return true;
+}
+
 static int
 parse_message(
     const unsigned char *buf,
@@ -162,8 +177,8 @@ parse_message(
     if (tid_return) {
         p = memmem(buf, buflen, "1:t", 3);
         if (p) {
-            l = strtoul((const char *)p + 3, &q, 10);
-            if (q && *q == ':' && l > 0 && l < *tid_len) {
+            if (stricttol((const char *)p + 3, &l, &q) && (q && *q == ':') &&
+                (l > 0 && l < *tid_len)) {
                 CHECK(q + 1, l);
                 memcpy(tid_return, q + 1, l);
                 *tid_len = l;
@@ -192,8 +207,8 @@ parse_message(
     if (port_return) {
         p = memmem(buf, buflen, "porti", 5);
         if (p) {
-            l = strtoul((const char *)p + 5, &q, 10);
-            if (q && *q == 'e' && l > 0 && l < 0x10000)
+            if (stricttol((const char *)p + 5, &l, &q) && (q && *q == 'e') &&
+                (l > 0 && l < 0x10000))
                 *port_return = (unsigned short)l;
             else
                 *port_return = 0;
@@ -212,8 +227,8 @@ parse_message(
     if (token_return) {
         p = memmem(buf, buflen, "5:token", 7);
         if (p) {
-            l = strtoul((const char *)p + 7, &q, 10);
-            if (q && *q == ':' && l > 0 && l < *token_len) {
+            if (stricttol((const char *)p + 7, &l, &q) && (q && *q == ':') &&
+                (l > 0 && l < *token_len)) {
                 CHECK(q + 1, l);
                 memcpy(token_return, q + 1, l);
                 *token_len = l;
@@ -226,8 +241,8 @@ parse_message(
     if (nodes_len) {
         p = memmem(buf, buflen, "5:nodes", 7);
         if (p) {
-            l = strtoul((const char *)p + 7, &q, 10);
-            if (q && *q == ':' && l > 0 && l < *nodes_len) {
+            if (stricttol((const char *)p + 7, &l, &q) && (q && *q == ':') &&
+                (l > 0 && l < *nodes_len)) {
                 CHECK(q + 1, l);
                 memcpy(nodes_return, q + 1, l);
                 *nodes_len = l;
@@ -240,8 +255,8 @@ parse_message(
     if (nodes6_len) {
         p = memmem(buf, buflen, "6:nodes6", 8);
         if (p) {
-            l = strtoul((const char *)p + 8, &q, 10);
-            if (q && *q == ':' && l > 0 && l < *nodes6_len) {
+            if (stricttol((const char *)p + 8, &l, &q) && (q && *q == ':') &&
+                (l > 0 && l < *nodes6_len)) {
                 CHECK(q + 1, l);
                 memcpy(nodes6_return, q + 1, l);
                 *nodes6_len = l;
@@ -257,8 +272,8 @@ parse_message(
             size_t i = p - buf + 9;
             unsigned long j = 0, j6 = 0;
             for (;;) {
-                l = strtoul((const char *)buf + i, &q, 10);
-                if (q && *q == ':' && l > 0) {
+                if (stricttol((const char *)buf + i, &l, &q) && (q && *q == ':') &&
+                    (l > 0)) {
                     CHECK(q + 1, l);
                     if (l == 6) {
                         if (j + l > *values_len)