View Issue Details

IDProjectCategoryView StatusLast Update
0002462NoesisGUIC++ SDKpublic2022-11-18 01:13
ReporterAnKor Assigned Tojsantos  
PrioritynormalSeveritycrashReproducibilityalways
Status resolvedResolutionfixed 
Product Version3.1.5 
Target Version3.1.6Fixed in Version3.1.6 
Summary0002462: Memory corruption in Noesis::String::Replace
DescriptionString::Replace does not increase capacity when replacement string is larger than the number of replaced characters (e.g. when "inserts > removes").
This causes memmove to write outside of allocated memory and corrupts the stack for small strings (or heap for large strings).

There's a simple workaround (either call Reserve before Replace or use Erase + Insert combo), but the bug seems pretty major and non-obvious.
Steps To ReproduceA simple code snippet:
Noesis::String x = "12345-67890";
x.Replace(5, 1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");

Results in the following state:
mSize=36
mCapacity=23
mIsSmall=1

and potentially corrupts adjacent data on the stack.
TagsNo tags attached.
PlatformAny

Activities

jsantos

jsantos

2022-11-18 01:13

manager   ~0008165

Thanks for catching this! Patch fixing the issue:

Index: String.inl
===================================================================
--- String.inl	(revision 11729)
+++ String.inl	(working copy)
@@ -430,10 +430,17 @@
     NS_ASSERT(pos <= mSize);
     NS_ASSERT(str != nullptr);
 
-    char* dest = Begin() + pos;
     uint32_t removes = Min(n, mSize - pos);
     uint32_t inserts = (uint32_t)strlen(str);
+    uint32_t newSize = mSize + inserts - removes;
 
+    if (NS_UNLIKELY(newSize > Capacity()))
+    {
+        Grow(newSize);
+    }
+
+    char* dest = Begin() + pos;
+
     if (removes != inserts)
     {
         memmove(dest + inserts, dest + removes, mSize - pos - removes + 1);
@@ -440,7 +447,7 @@
     }
 
     memcpy(dest, str, inserts);
-    ForceSize(mSize + inserts - removes);
+    ForceSize(newSize);
 }
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////

Issue History

Date Modified Username Field Change
2022-11-17 18:57 AnKor New Issue
2022-11-17 18:57 AnKor Steps to Reproduce Updated
2022-11-17 21:02 jsantos Assigned To => jsantos
2022-11-17 21:02 jsantos Status new => assigned
2022-11-17 21:02 jsantos Target Version => 3.1.6
2022-11-18 01:13 jsantos Status assigned => resolved
2022-11-18 01:13 jsantos Resolution open => fixed
2022-11-18 01:13 jsantos Fixed in Version => 3.1.6
2022-11-18 01:13 jsantos Note Added: 0008165