]> granicus.if.org Git - graphviz/commitdiff
remove temporary buffer for name of the GVC plugin being loaded
authorMatthew Fernandez <matthew.fernandez@gmail.com>
Sat, 29 May 2021 20:47:55 +0000 (13:47 -0700)
committerMatthew Fernandez <matthew.fernandez@gmail.com>
Sat, 5 Jun 2021 01:56:44 +0000 (18:56 -0700)
The GVC plugin loading machinery copied the first 63 characters of the plugin
name to a temporary buffer in order to mutate it. However the mutation is simply
chopping up the plugin name based on a ':' separator. By tracking the start and
end of each component as pointers into the original sting, we can remove the
need for this temporary buffer.

Though this saves some stack memory, the primary motivation for this change is
to remove the truncation-to-63-characters behavior. There is no need to limit
plugin names to 63 characters. Note that the names of registered plugins are
still limited to 63 characters, so this does not fully remove the restriction.

lib/gvc/gvplugin.c

index 254900d4cc57fda3f1e04fc446bf96190b570eb4..402fe36b9395498ac404ab1b9c2543d1b88bea7e 100644 (file)
@@ -262,8 +262,8 @@ gvplugin_available_t *gvplugin_load(GVC_t * gvc, api_t api, const char *str)
     gvplugin_api_t *apis;
     gvplugin_installed_t *types;
 #define TYPBUFSIZ 64
-    char reqtyp[TYPBUFSIZ] = {0}, typ[TYPBUFSIZ] = {0};
-    char *reqdep, *dep = NULL, *reqpkg;
+    char typ[TYPBUFSIZ] = {0};
+    char *dep = NULL;
     int i;
     api_t apidep;
 
@@ -273,15 +273,27 @@ gvplugin_available_t *gvplugin_load(GVC_t * gvc, api_t api, const char *str)
     else
         apidep = api;
 
-    strncpy(reqtyp, str, TYPBUFSIZ - 1);
-    reqdep = strchr(reqtyp, ':');
-    if (reqdep) {
-        *reqdep++ = '\0';
-        reqpkg = strchr(reqdep, ':');
-        if (reqpkg)
-            *reqpkg++ = '\0';
-    } else
-        reqpkg = NULL;
+    const char *reqtyp = str;
+    const char *reqtyp_end = strchr(reqtyp, ':');
+    size_t reqtyp_len =
+      reqtyp_end == NULL ? strlen(reqtyp) : (size_t)(reqtyp_end - reqtyp);
+
+    const char *reqdep = NULL;
+    const char *reqdep_end = NULL;
+    size_t reqdep_len = 0;
+
+    const char *reqpkg = NULL;
+
+    if (reqtyp_end != NULL) {
+        reqdep = reqtyp_end + strlen(":");
+        reqdep_end = strchr(reqdep, ':');
+        if (reqdep_end != NULL) {
+            reqdep_len = (size_t)(reqdep_end - reqdep);
+            reqpkg = reqdep_end + strlen(":");
+        } else {
+            reqdep_len = strlen(reqdep);
+        }
+    }
 
     /* iterate the linked list of plugins for this api */
     for (pnext = gvc->apis[api]; pnext; pnext = pnext->next) {
@@ -289,10 +301,13 @@ gvplugin_available_t *gvplugin_load(GVC_t * gvc, api_t api, const char *str)
         dep = strchr(typ, ':');
         if (dep)
             *dep++ = '\0';
-        if (strcmp(typ, reqtyp))
+        if (strlen(typ) != reqtyp_len || strncmp(typ, reqtyp, reqtyp_len))
             continue;           /* types empty or mismatched */
-        if (dep && reqdep && strcmp(dep, reqdep))
-            continue;           /* dependencies not empty, but mismatched */
+        if (dep && reqdep) {
+            if (strlen(dep) != reqdep_len || strncmp(dep, reqdep, reqdep_len)) {
+                continue;           /* dependencies not empty, but mismatched */
+            }
+        }
         if (!reqpkg || strcmp(reqpkg, pnext->package->name) == 0) {
             /* found with no packagename constraints, or with required matching packagname */