]> git.rm.cloudns.org Git - xonotic/darkplaces.git/commitdiff
fix multiple bugs in strreplace
authordivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 6 Apr 2011 20:24:30 +0000 (20:24 +0000)
committerdivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 6 Apr 2011 20:24:30 +0000 (20:24 +0000)
bug 1: if search string is empty, an endless loop occurs
bug 2: searching for "foo" in "fo" is actually found, and replaced!

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11034 d7cf8633-e32d-0410-b094-e92efae38249

prvm_cmds.c

index 01386fd8852bf6a4cb7593980a2f0d68e71cf183..32587c7b823e137d5e9755bddb41e6c761c2fe58 100644 (file)
@@ -2382,25 +2382,42 @@ void VM_strreplace(void)
        subject_len = (int)strlen(subject);
 
        si = 0;
-       for (i = 0; i < subject_len; i++)
+       for (i = 0; i <= subject_len - search_len; i++)
        {
-               for (j = 0; j < search_len && i+j < subject_len; j++)
+               for (j = 0; j < search_len; j++) // thus, i+j < subject_len
                        if (subject[i+j] != search[j])
                                break;
-               if (j == search_len || i+j == subject_len)
+               if (j == search_len)
                {
-               // found it at offset 'i'
+                       // NOTE: if search_len == 0, we always hit THIS case, and never the other
+                       // found it at offset 'i'
                        for (j = 0; j < replace_len && si < (int)sizeof(string) - 1; j++)
                                string[si++] = replace[j];
-                       i += search_len - 1;
+                       if(search_len > 0)
+                       {
+                               i += search_len - 1;
+                       }
+                       else
+                       {
+                               // the above would subtract 1 from i... so we
+                               // don't do that, but instead output the next
+                               // char
+                               if (si < (int)sizeof(string) - 1)
+                                       string[si++] = subject[i];
+                       }
                }
                else
                {
-               // not found
+                       // in THIS case, we know search_len > 0, thus i < subject_len
+                       // not found
                        if (si < (int)sizeof(string) - 1)
                                string[si++] = subject[i];
                }
        }
+       // remaining chars (these cannot match)
+       for (; i < subject_len; i++)
+               if (si < (int)sizeof(string) - 1)
+                       string[si++] = subject[i];
        string[si] = '\0';
 
        PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(string);