Remove quadratic behavior from g_strconcat. (mono/mono#15630)
authorJay Krell <jaykrell@microsoft.com>
Wed, 10 Jul 2019 16:06:51 +0000 (09:06 -0700)
committerAleksey Kliger (λgeek) <alklig@microsoft.com>
Wed, 10 Jul 2019 16:06:51 +0000 (12:06 -0400)
Prefer strlen + memcpy over strcat.

Commit migrated from https://github.com/mono/mono/commit/7a486d8f438434159e1a7f0f8762a76b2faffeac

src/mono/mono/eglib/gstr.c

index b43f3d9..d6b26b4 100644 (file)
@@ -276,26 +276,28 @@ gchar *
 g_strconcat (const gchar *first, ...)
 {
        va_list args;
-       size_t total = 0;
        char *s, *ret;
        g_return_val_if_fail (first != NULL, NULL);
 
-       total += strlen (first);
+       size_t len = strlen (first);
        va_start (args, first);
        for (s = va_arg (args, char *); s != NULL; s = va_arg(args, char *)){
-               total += strlen (s);
+               len += strlen (s);
        }
        va_end (args);
        
-       ret = g_malloc (total + 1);
+       ret = (char*)g_malloc (len + 1);
        if (ret == NULL)
                return NULL;
 
-       ret [total] = 0;
-       strcpy (ret, first);
+       ret [len] = 0;
+       len = strlen (first);
+       memcpy (ret, first, len);
        va_start (args, first);
+       first = ret; // repurpose first as cursor
        for (s = va_arg (args, char *); s != NULL; s = va_arg(args, char *)){
-               strcat (ret, s);
+               first += len;
+               memcpy ((char*)first, s, len = strlen (s));
        }
        va_end (args);
 
@@ -512,7 +514,7 @@ g_strjoin (const gchar *separator, ...)
        if (slen > 0 && len > 0)
                len -= slen;
 
-       res = g_malloc (len + 1);
+       res = (char*)g_malloc (len + 1);
        va_start (args, separator);
        s = va_arg (args, char *);
        r = g_stpcpy (res, s);