]> granicus.if.org Git - graphviz/commitdiff
smyrna: fix incorrect use of 'strtok'
authorMatthew Fernandez <matthew.fernandez@gmail.com>
Thu, 14 Jul 2022 00:45:31 +0000 (17:45 -0700)
committerMatthew Fernandez <matthew.fernandez@gmail.com>
Tue, 19 Jul 2022 03:05:43 +0000 (20:05 -0700)
This code was using `strtok` as if it splits based on the single separator
passed to it. But `strtok` actually treats the second parameter as a list of
character separators. In this change, we rephrase this code to do what its
original author appears to have intended.

This slightly changes the semantics of this code. But it seems we do not know
the exact intent of the original, so this is hoped to match the author’s
intention.

Gitlab: fixes #2259

CHANGELOG.md
cmd/smyrna/gui/frmobjectui.c

index 6e67b334c35b9be0d01a7c30b7aa37f9f537b719..1bce7141a65f4d5cb3032def142f5bc6eb11d510 100644 (file)
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - -Tx11: Assertion `xev.xbutton.button >= 1 && xev.xbutton.button <= 5 && "Xlib
   returned invalid button event"` failed #2256
 - missing Perl includes patch #2262
+- smyrna: incorrect tokenization in frmobjectui.c:set_attr_object_type #2259
 
 ## [5.0.0] – 2022-07-07
 
index 78645c454858c73a3e5ebe909ec8019d2ef959d7..1eb3442e9e75ef269f024476729ef1e02b22a90f 100644 (file)
@@ -8,6 +8,7 @@
  * Contributors: Details at https://graphviz.org
  *************************************************************************/
 
+#include <stdbool.h>
 #include <stdio.h>
 
 #include <stdlib.h>
@@ -23,6 +24,8 @@
 #include "gvprpipe.h"
 #include <cgraph/agxbuf.h>
 #include <cgraph/strcasecmp.h>
+#include <cgraph/strview.h>
+#include <string.h>
 
 static int sel_node;
 static int sel_edge;
@@ -217,30 +220,39 @@ static attr_data_type get_attr_data_type(char c)
     return attr_alpha;
 }
 
-static void object_type_helper(char *a, int *t)
-{
-    if (strcmp(a, "GRAPH") == 0)
+static void object_type_helper(strview_t a, int *t) {
+    if (strview_str_eq(a, "GRAPH"))
        t[0] = 1;
-    if (strcmp(a, "CLUSTER") == 0)
+    if (strview_str_eq(a, "CLUSTER"))
        t[0] = 1;
-    if (strcmp(a, "NODE") == 0)
+    if (strview_str_eq(a, "NODE"))
        t[1] = 1;
-    if (strcmp(a, "EDGE") == 0)
+    if (strview_str_eq(a, "EDGE"))
        t[2] = 1;
-    if (strcmp(a, "ANY_ELEMENT") == 0) {
+    if (strview_str_eq(a, "ANY_ELEMENT")) {
        t[0] = 1;
        t[1] = 1;
        t[2] = 1;
     }
 }
 
-static void set_attr_object_type(char *str, int *t)
-{
-    char *a;
-    a = strtok(str, " ");
+static void set_attr_object_type(const char *str, int *t) {
+  strview_t a = strview(str, ' ');
+  object_type_helper(a, t);
+  while (true) {
+    const char *start = a.data + a.size;
+    if (strncmp(start, " or ", strlen(" or ")) != 0) {
+      break;
+    }
+    start += strlen(" or ");
+    const char *end = strstr(start, " or ");
+    if (end == NULL) {
+      a = strview(start, '\0');
+    } else {
+      a = (strview_t){.data = start, .size = (size_t)(end - start)};
+    }
     object_type_helper(a, t);
-    while ((a = strtok(NULL, " or ")))
-       object_type_helper(a, t);
+  }
 }
 
 static attr_t *binarySearch(attr_list * l, char *searchKey)