]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect: replace strtoul with ByteExtractStringUint32
authorFupeng Zhao <fupeng.zhao@foxmail.com>
Thu, 19 Jun 2025 05:48:07 +0000 (13:48 +0800)
committerVictor Julien <victor@inliniac.net>
Fri, 27 Jun 2025 16:58:42 +0000 (18:58 +0200)
Also added and updated unit tests to ensure correctness.

Ticket: #7212

src/detect-gid.c
src/detect-mark.c
src/detect-rev.c
src/detect-sid.c

index e131b535918f40c1d650722590d91a7772554ce2..9f346f10500825ce50cb911ad82d95a7336c242e 100644 (file)
@@ -33,6 +33,7 @@
 #include "decode-events.h"
 
 #include "detect-gid.h"
+#include "util-byte.h"
 #include "util-unittest.h"
 #include "util-debug.h"
 
@@ -71,21 +72,13 @@ void DetectGidRegister (void)
  */
 static int DetectGidSetup (DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
 {
-    unsigned long gid = 0;
-    char *endptr = NULL;
-    errno = 0;
-    gid = strtoul(rawstr, &endptr, 10);
-    if (errno == ERANGE || endptr == NULL || *endptr != '\0') {
-        SCLogError("invalid character as arg "
-                   "to gid keyword");
-        goto error;
-    }
-    if (gid >= UINT_MAX) {
-        SCLogError("gid value to high, max %u", UINT_MAX);
+    uint32_t gid = 0;
+    if (ByteExtractStringUint32(&gid, 10, strlen(rawstr), rawstr) <= 0) {
+        SCLogError("invalid input as arg to gid keyword");
         goto error;
     }
 
-    s->gid = (uint32_t)gid;
+    s->gid = gid;
 
     return 0;
 
index 985865cedd8bda2f64ff1003c7165a7596d0604c..4c25f261f2a7bba7bec2f7bcc27ca1800a2aa3c5 100644 (file)
@@ -35,6 +35,7 @@
 #include "detect-parse.h"
 
 #include "util-unittest.h"
+#include "util-byte.h"
 #include "util-debug.h"
 
 #define PARSE_REGEX "([0x]*[0-9a-f]+)/([0x]*[0-9a-f]+)"
@@ -81,7 +82,6 @@ static void * DetectMarkParse (const char *rawstr)
     size_t pcre2_len;
     const char *str_ptr = NULL;
     char *ptr = NULL;
-    char *endptr = NULL;
     uint32_t mark;
     uint32_t mask;
     DetectMarkData *data;
@@ -105,20 +105,8 @@ static void * DetectMarkParse (const char *rawstr)
     if (ptr == NULL)
         goto error;
 
-    errno = 0;
-    mark = strtoul(ptr, &endptr, 0);
-    if (errno == ERANGE) {
-        SCLogError("Numeric value out of range");
-        pcre2_substring_free((PCRE2_UCHAR8 *)ptr);
-        goto error;
-    }     /* If there is no numeric value in the given string then strtoull(), makes
-             endptr equals to ptr and return 0 as result */
-    else if (endptr == ptr && mark == 0) {
-        SCLogError("No numeric value");
-        pcre2_substring_free((PCRE2_UCHAR8 *)ptr);
-        goto error;
-    } else if (endptr == ptr) {
-        SCLogError("Invalid numeric value");
+    if (ByteExtractStringUint32(&mark, 0, strlen(ptr), ptr) <= 0) {
+        SCLogError("invalid input as arg to nfq_set_mark keyword");
         pcre2_substring_free((PCRE2_UCHAR8 *)ptr);
         goto error;
     }
@@ -143,21 +131,8 @@ static void * DetectMarkParse (const char *rawstr)
         return data;
     }
 
-    errno = 0;
-    mask = strtoul(ptr, &endptr, 0);
-    if (errno == ERANGE) {
-        SCLogError("Numeric value out of range");
-        pcre2_substring_free((PCRE2_UCHAR8 *)ptr);
-        goto error;
-    }     /* If there is no numeric value in the given string then strtoull(), makes
-             endptr equals to ptr and return 0 as result */
-    else if (endptr == ptr && mask == 0) {
-        SCLogError("No numeric value");
-        pcre2_substring_free((PCRE2_UCHAR8 *)ptr);
-        goto error;
-    }
-    else if (endptr == ptr) {
-        SCLogError("Invalid numeric value");
+    if (ByteExtractStringUint32(&mask, 0, strlen(ptr), ptr) <= 0) {
+        SCLogError("invalid input as arg to nfq_set_mark keyword");
         pcre2_substring_free((PCRE2_UCHAR8 *)ptr);
         goto error;
     }
@@ -272,6 +247,8 @@ static int MarkTestParse01 (void)
     data = DetectMarkParse("1/1");
 
     FAIL_IF_NULL(data);
+    FAIL_IF(data->mark != 1);
+    FAIL_IF(data->mask != 1);
 
     DetectMarkDataFree(NULL, data);
     PASS;
@@ -302,6 +279,8 @@ static int MarkTestParse03 (void)
     DetectMarkData *data;
 
     data = DetectMarkParse("0x10/0xff");
+    FAIL_IF(data->mark != 0x10);
+    FAIL_IF(data->mask != 0xff);
 
     FAIL_IF_NULL(data);
 
index 6f0f94b1305b7846d2ff0e23e7b1ac4e971f6f5d..6b247561d51f99a14a25f23c5a79bfcb160c10c0 100644 (file)
 
 #include "suricata-common.h"
 #include "detect.h"
+#include "detect-engine.h"
+#include "detect-parse.h"
 #include "detect-rev.h"
+#include "util-byte.h"
 #include "util-debug.h"
 #include "util-error.h"
+#include "util-unittest.h"
 
 static int DetectRevSetup (DetectEngineCtx *, Signature *, const char *);
+#ifdef UNITTESTS
+static void DetectRevRegisterTests(void);
+#endif
 
 void DetectRevRegister (void)
 {
@@ -37,21 +44,16 @@ void DetectRevRegister (void)
     sigmatch_table[DETECT_REV].desc = "set version of the rule";
     sigmatch_table[DETECT_REV].url = "/rules/meta.html#rev-revision";
     sigmatch_table[DETECT_REV].Setup = DetectRevSetup;
+#ifdef UNITTESTS
+    sigmatch_table[DETECT_REV].RegisterTests = DetectRevRegisterTests;
+#endif
 }
 
 static int DetectRevSetup (DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
 {
-    unsigned long rev = 0;
-    char *endptr = NULL;
-    errno = 0;
-    rev = strtoul(rawstr, &endptr, 10);
-    if (errno == ERANGE || endptr == NULL || *endptr != '\0') {
-        SCLogError("invalid character as arg "
-                   "to rev keyword");
-        goto error;
-    }
-    if (rev >= UINT_MAX) {
-        SCLogError("rev value to high, max %u", UINT_MAX);
+    uint32_t rev = 0;
+    if (ByteExtractStringUint32(&rev, 10, strlen(rawstr), rawstr) <= 0) {
+        SCLogError("invalid input as arg to rev keyword");
         goto error;
     }
     if (rev == 0) {
@@ -63,10 +65,85 @@ static int DetectRevSetup (DetectEngineCtx *de_ctx, Signature *s, const char *ra
         goto error;
     }
 
-    s->rev = (uint32_t)rev;
-
+    s->rev = rev;
     return 0;
 
- error:
+error:
     return -1;
- }
+}
+
+#ifdef UNITTESTS
+/**
+ * \test RevTestParse01 is a test for a valid rev value
+ */
+static int RevTestParse01(void)
+{
+    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+    FAIL_IF_NULL(de_ctx);
+
+    Signature *s =
+            DetectEngineAppendSig(de_ctx, "alert tcp 1.2.3.4 any -> any any (sid:1; rev:1;)");
+
+    FAIL_IF_NULL(s);
+    FAIL_IF(s->rev != 1);
+
+    DetectEngineCtxFree(de_ctx);
+    PASS;
+}
+
+/**
+ * \test RevTestParse02 is a test for an invalid rev value
+ */
+static int RevTestParse02(void)
+{
+    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+    FAIL_IF_NULL(de_ctx);
+
+    FAIL_IF_NOT_NULL(
+            DetectEngineAppendSig(de_ctx, "alert tcp 1.2.3.4 any -> any any (sid:1; rev:a;)"));
+
+    DetectEngineCtxFree(de_ctx);
+    PASS;
+}
+
+/**
+ * \test RevTestParse03 is a test for a rev containing of a single quote.
+ */
+static int RevTestParse03(void)
+{
+    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+    FAIL_IF_NULL(de_ctx);
+
+    FAIL_IF_NOT_NULL(DetectEngineAppendSig(
+            de_ctx, "alert tcp any any -> any any (content:\"ABC\"; rev:\";)"));
+
+    DetectEngineCtxFree(de_ctx);
+    PASS;
+}
+
+/**
+ * \test RevTestParse04 is a test for a rev value of 0
+ */
+static int RevTestParse04(void)
+{
+    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+    FAIL_IF_NULL(de_ctx);
+
+    FAIL_IF_NOT_NULL(DetectEngineAppendSig(
+            de_ctx, "alert tcp any any -> any any (content:\"ABC\"; rev:0;)"));
+
+    DetectEngineCtxFree(de_ctx);
+    PASS;
+}
+
+/**
+ * \brief this function registers unit tests for Rev
+ */
+static void DetectRevRegisterTests(void)
+{
+    UtRegisterTest("RevTestParse01", RevTestParse01);
+    UtRegisterTest("RevTestParse02", RevTestParse02);
+    UtRegisterTest("RevTestParse03", RevTestParse03);
+    UtRegisterTest("RevTestParse04", RevTestParse04);
+}
+#endif /* UNITTESTS */
index be017e2507fed09170dfbe1a938f12fdef0f115a..1d65f569383f491ff4d4a4c367b0641675dac4be 100644 (file)
@@ -28,6 +28,7 @@
 #include "detect-engine.h"
 #include "detect-parse.h"
 #include "detect-sid.h"
+#include "util-byte.h"
 #include "util-debug.h"
 #include "util-error.h"
 #include "util-unittest.h"
@@ -52,17 +53,9 @@ void DetectSidRegister (void)
 
 static int DetectSidSetup (DetectEngineCtx *de_ctx, Signature *s, const char *sidstr)
 {
-    unsigned long id = 0;
-    char *endptr = NULL;
-    errno = 0;
-    id = strtoul(sidstr, &endptr, 10);
-    if (errno == ERANGE || endptr == NULL || *endptr != '\0') {
-        SCLogError("invalid character as arg "
-                   "to sid keyword");
-        goto error;
-    }
-    if (id >= UINT_MAX) {
-        SCLogError("sid value too high, max %u", UINT_MAX);
+    uint32_t id = 0;
+    if (ByteExtractStringUint32(&id, 10, strlen(sidstr), sidstr) <= 0) {
+        SCLogError("invalid input as arg to sid keyword");
         goto error;
     }
     if (id == 0) {
@@ -74,7 +67,7 @@ static int DetectSidSetup (DetectEngineCtx *de_ctx, Signature *s, const char *si
         goto error;
     }
 
-    s->id = (uint32_t)id;
+    s->id = id;
     return 0;
 
  error: