Memory corruption

Issue #204 resolved
Former user created an issue

When I needed to compile an old project I noticed some odd issues likely related to some memory corruption. Hence I enabled the FastMM debug mode and it returned this:

A memory block footer has been corrupted.

The block size is 22.

The block was allocated by thread 0x2008, and the stack trace (return addresses) at the time was:
4218E6 [FastMM5.pas][FastMM5][FastMM_DebugGetMem$qqri][7777]
407212 [System.pas][System][@GetMem$qqri][4830]
40B56F [System.pas][System][@NewUnicodeString$qqri][25285]
40C803 [System.pas][System][@UStrSetLength$qqrr20System.UnicodeStringi][30591]
A18D76 [dwsJSRTL.pas][dwsJSRTL][EscapeRegExpSpecials][2137]
A18F04 [dwsJSRTL.pas][dwsJSRTL][TJSStrReplaceFuncExpr.CodeGen][2175]
A3F0DF [dwsJSCodeGen.pas][dwsJSCodeGen][TJSFuncBaseExpr.CodeGenNoWrap][4783]
A16E81 [dwsJSRTL.pas][dwsJSRTL][TJSMagicFuncExpr.DoCodeGen][1617]
A16F30 [dwsJSRTL.pas][dwsJSRTL][TJSMagicFuncExpr.CodeGenNoWrap][1636]
9E835E [dwsCodeGen.pas][dwsCodeGen][TdwsCodeGen.CompileNoWrap][716]
A3EBF7 [dwsJSCodeGen.pas][dwsJSCodeGen][TJSAssignExpr.CodeGenRight][4624]
A3EBBB [dwsJSCodeGen.pas][dwsJSCodeGen][TJSAssignExpr.CodeGenNoStatement][4614]
A3EB6A [dwsJSCodeGen.pas][dwsJSCodeGen][TJSAssignExpr.CodeGen][4601]
9E82E6 [dwsCodeGen.pas][dwsCodeGen][TdwsCodeGen.Compile][693]
9E8303 [dwsCodeGen.pas][dwsCodeGen][TdwsCodeGen.CompileStatement][701]
A3DE4E [dwsJSCodeGen.pas][dwsJSCodeGen][TJSBlockExprBase.CodeGen][4089]
9E82E6 [dwsCodeGen.pas][dwsCodeGen][TdwsCodeGen.Compile][693]
9E8303 [dwsCodeGen.pas][dwsCodeGen][TdwsCodeGen.CompileStatement][701]
A3BF18 [dwsJSCodeGen.pas][dwsJSCodeGen][TdwsJSCodeGen.CompileFuncBody][3383]
40B64D [System.pas][System][@LStrClr$qqrpv][25553]

Now looking into the code:

function EscapeRegExpSpecials(const s : String) : String;
var
  pSrc, pDest : PChar;
begin
  SetLength(Result, Length(s));
  pSrc := Pointer(s);
  pDest := Pointer(Result);
  repeat
     case pSrc^ of
        #0 : begin
           SetLength(Result, (NativeUInt(pDest)-NativeUInt(Result)) div SizeOf(Char));
           Exit;
        end;
        '-', '!', '[', ']', '(', ')', '?', '+', '*', '{', '}', '.', '^', '$', '|' : begin
           pDest[0] := '\';
           pDest[1] := pSrc^;
           Inc(pDest, 2);
        end;
        '0'..'>', '@'..'Z', #$005F..'z', ' ' : begin
           pDest^ := pSrc^;
           Inc(pDest);
        end;
     else
        Exit('');
     end;
     Inc(pSrc);
  until False;
//       Code : 'function StrRegExp(s) { return s.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&") }'),
end;

I'd say that it makes sense if tested with a string like '!!'

In that case the pDest will easily go beyond its boundaries.

Normally it's not really an issue, but in some cases it is.

Comments (3)

  1. Eric Grange repo owner

    Yes, as soon as there was more than one escaped character, it would go beyond boundary

  2. Log in to comment