]> granicus.if.org Git - graphviz/commitdiff
tclpkg vgpanecmd: remove acceptance of ambiguous abbreviated commands
authorMatthew Fernandez <matthew.fernandez@gmail.com>
Tue, 8 Feb 2022 10:51:32 +0000 (21:51 +1100)
committerMatthew Fernandez <matthew.fernandez@gmail.com>
Sun, 20 Feb 2022 18:35:23 +0000 (10:35 -0800)
`vgpanecmd` accepted abbreviations of commands, e.g. `li` for list. However
these abbreviations were accepted as first match with no disambiguation. So `r`
would always be interpreted as `rotate`, not `remove`. This behavior appears to
be an unintentional side effect of commands being incrementally introduced over
time without this kind of prefix-matching overlap being taken into account,
though this is mostly a guess as all this code was implemented prior to the
first Git commit.

Gitlab: fixes #1961

CHANGELOG.md
tclpkg/tclpathplan/tclpathplan.c

index 05cfc529a1eff85857cb47b6655994d3f839e4d4..7db870ba90fe81f1f7ff5d34709ce07ba7c9f92b 100644 (file)
@@ -87,6 +87,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 - **Breaking**: GVPR now typedefs `ssize_t` as `SSIZE_T` on Windows instead of
   `int` #1804
+- **Breaking**: `vgpanecmd` in the TCL tclpathplan library no longer accepts
+  abbreviated commands (e.g. `r` for `rotate`) and commands must be given in
+  full #1961
 - fix detection of unavailable output format
 - SVG layout doesn't always respect requested size #1855
 - mismatched format string in `mingle`
index 83eecd95bda2f402a157b81f0843225795e9cbca..3eec7279a756b766584982f910069db78c46d466 100644 (file)
@@ -424,9 +424,7 @@ vgpanecmd(ClientData clientData, Tcl_Interp * interp, int argc,
     }
     vgp = *vgpp;
 
-    size_t length = strlen(argv[1]);
-
-    if (strncmp(argv[1], "coords", length) == 0) {
+    if (strcmp(argv[1], "coords") == 0) {
        if (argc < 3) {
            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                             " ", argv[1], " id ?x1 y1 x2 y2...?\"", NULL);
@@ -478,12 +476,12 @@ vgpanecmd(ClientData clientData, Tcl_Interp * interp, int argc,
 
        return insert_poly(interp, vgp, polyid, vargv, vargc);
 
-    } else if (strncmp(argv[1], "debug", length) == 0) {
+    } else if (strcmp(argv[1], "debug") == 0) {
        /* debug only */
        printf("debug output goes here\n");
        return TCL_OK;
 
-    } else if (strncmp(argv[1], "delete", length) == 0) {
+    } else if (strcmp(argv[1], "delete") == 0) {
        /* delete a vgpane and all memory associated with it */
        if (vgp->vc)
            Pobsclose(vgp->vc);
@@ -492,7 +490,7 @@ vgpanecmd(ClientData clientData, Tcl_Interp * interp, int argc,
        free(tclhandleFree(vgpaneTable, argv[0]));
        return TCL_OK;
 
-    } else if (strncmp(argv[1], "find", length) == 0) {
+    } else if (strcmp(argv[1], "find") == 0) {
        /* find the polygon that the point is inside and return it
           id, or null */
        if (argc < 3) {
@@ -524,7 +522,7 @@ vgpanecmd(ClientData clientData, Tcl_Interp * interp, int argc,
        }
        return TCL_OK;
 
-    } else if (strncmp(argv[1], "insert", length) == 0) {
+    } else if (strcmp(argv[1], "insert") == 0) {
        /* add poly to end poly list, and it coordinates to the end of 
           the point list */
        if ((argc < 3)) {
@@ -561,7 +559,7 @@ vgpanecmd(ClientData clientData, Tcl_Interp * interp, int argc,
        Tcl_AppendResult(interp, vbuf, NULL);
        return TCL_OK;
 
-    } else if (strncmp(argv[1], "list", length) == 0) {
+    } else if (strcmp(argv[1], "list") == 0) {
        /* return list of polygon ids */
        for (i = 0; i < vgp->Npoly; i++) {
            snprintf(vbuf, sizeof(vbuf), "%d", vgp->poly[i].id);
@@ -569,7 +567,7 @@ vgpanecmd(ClientData clientData, Tcl_Interp * interp, int argc,
        }
        return TCL_OK;
 
-    } else if (strncmp(argv[1], "path", length) == 0) {
+    } else if (strcmp(argv[1], "path") == 0) {
        /* return a list of points corresponding to the shortest path
           that does not cross the remaining "visible" polygons. */
        if (argc < 3) {
@@ -611,7 +609,7 @@ vgpanecmd(ClientData clientData, Tcl_Interp * interp, int argc,
 
        return TCL_OK;
 
-    } else if (strncmp(argv[1], "bind", length) == 0) {
+    } else if (strcmp(argv[1], "bind") == 0) {
        if (argc < 2 || argc > 4) {
            Tcl_AppendResult(interp, "wrong # args: should be \"",
                             argv[0], " bind triangle ?command?\"", NULL);
@@ -621,8 +619,7 @@ vgpanecmd(ClientData clientData, Tcl_Interp * interp, int argc,
            Tcl_AppendElement(interp, "triangle");
            return TCL_OK;
        }
-       length = strlen(argv[2]);
-       if (strncmp(argv[2], "triangle", length) == 0) {
+       if (strcmp(argv[2], "triangle") == 0) {
            s = vgp->triangle_cmd;
            if (argc == 4)
                vgp->triangle_cmd = s = buildBindings(s, argv[3]);
@@ -635,7 +632,7 @@ vgpanecmd(ClientData clientData, Tcl_Interp * interp, int argc,
            Tcl_AppendResult(interp, s, NULL);
        return TCL_OK;
 
-    } else if (strncmp(argv[1], "bpath", length) == 0) {
+    } else if (strcmp(argv[1], "bpath") == 0) {
        /* return a list of points corresponding to the shortest path
           that does not cross the remaining "visible" polygons. */
        if (argc < 3) {
@@ -690,7 +687,7 @@ vgpanecmd(ClientData clientData, Tcl_Interp * interp, int argc,
        }
        return TCL_OK;
 
-    } else if (strncmp(argv[1], "bbox", length) == 0) {
+    } else if (strcmp(argv[1], "bbox") == 0) {
        if (argc < 3) {
            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                             " ", argv[1], " id\"", NULL);
@@ -720,7 +717,7 @@ vgpanecmd(ClientData clientData, Tcl_Interp * interp, int argc,
        Tcl_AppendResult(interp, " no such polygon: ", argv[2], NULL);
        return TCL_ERROR;
 
-    } else if (strncmp(argv[1], "center", length) == 0) {
+    } else if (strcmp(argv[1], "center") == 0) {
        if (argc < 3) {
            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                             " ", argv[1], " id\"", NULL);
@@ -740,7 +737,7 @@ vgpanecmd(ClientData clientData, Tcl_Interp * interp, int argc,
        Tcl_AppendResult(interp, " no such polygon: ", argv[2], NULL);
        return TCL_ERROR;
 
-    } else if (strncmp(argv[1], "triangulate", length) == 0) {
+    } else if (strcmp(argv[1], "triangulate") == 0) {
        if (argc < 2) {
            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                             " id ", NULL);
@@ -761,7 +758,7 @@ vgpanecmd(ClientData clientData, Tcl_Interp * interp, int argc,
        }
        Tcl_AppendResult(interp, " no such polygon: ", argv[2], NULL);
        return TCL_ERROR;
-    } else if (strncmp(argv[1], "rotate", length) == 0) {
+    } else if (strcmp(argv[1], "rotate") == 0) {
        if (argc < 4) {
            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                             " ", argv[1], " id alpha\"", NULL);
@@ -789,7 +786,7 @@ vgpanecmd(ClientData clientData, Tcl_Interp * interp, int argc,
        Tcl_AppendResult(interp, " no such polygon: ", argv[2], NULL);
        return TCL_ERROR;
 
-    } else if (strncmp(argv[1], "scale", length) == 0) {
+    } else if (strcmp(argv[1], "scale") == 0) {
        if (argc < 4) {
            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                             " ", argv[1], " id gain\"", NULL);
@@ -816,7 +813,7 @@ vgpanecmd(ClientData clientData, Tcl_Interp * interp, int argc,
        Tcl_AppendResult(interp, " no such polygon: ", argv[2], NULL);
        return TCL_ERROR;
 
-    } else if (strncmp(argv[1], "remove", length) == 0) {
+    } else if (strcmp(argv[1], "remove") == 0) {
        if (argc < 3) {
            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                             " ", argv[1], " id\"", NULL);