瀏覽代碼

* fixed reading past end-of-heap again (correctly this time I hope)

Jonas Maebe 25 年之前
父節點
當前提交
964dd80cda
共有 1 個文件被更改,包括 50 次插入35 次删除
  1. 50 35
      rtl/i386/stringss.inc

+ 50 - 35
rtl/i386/stringss.inc

@@ -18,75 +18,90 @@
 function strpas(p : pchar) : string;
 begin
 asm
+        movl    p,%esi
         movl    __RESULT,%edi
-        movb    $1,%cl
+        movl    %esi,%edx
+        movl    $1,%ecx
+        andl    $0x0fffffff8,%esi
+        // skip length byte
+        incl    %edi
+        subl    %esi,%edx
+        jz      .LStrPasAligned
         movl    p,%esi
-        // skip length byte -> align dest to multiple of 4
-.LStrCopyAlignLoop:
+        // align source to multiple of 4 (not dest, because we can't read past
+        // the end of the source, since that may be past the end of the heap
+        // -> sigsegv!!)
+.LStrPasAlignLoop:
         movb    (%esi),%al
-        incl    %edi
         incl    %esi
         testb   %al,%al
-        jz      .LStrCopyDone
-        incb    %cl
-        movb    %al,(%edi)
-        cmpb    $4,%cl
-        jne     .LStrCopyAlignLoop
+        jz      .LStrPasDone
         incl    %edi
-        .align  16
-.LStrCopyAligned:
+        incb    %cl
+        decb    %dl
+        movb    %al,-1(%edi)
+        jne     .LStrPasAlignLoop
+        .balign  16
+.LStrPasAligned:
         movl    (%esi),%eax
         addl    $4,%esi
         // this won't overwrite data since the result = 255 char string
+        // and we never process more than the first 255 chars of p
         movl    %eax,(%edi)
         testl   $0x0ff,%eax
-        jz      .LStrCopyDone
+        jz      .LStrPasDone
+        incl    %ecx
         testl   $0x0ff00,%eax
-        jz      .LStrCopyByte
+        jz      .LStrPasDone
+        incl    %ecx
         testl   $0x0ff0000,%eax
-        jz      .LStrCopyWord
+        jz      .LStrPasDone
+        incl    %ecx
         testl   $0x0ff000000,%eax
-        jz      .LStrCopy3Bytes
+        jz      .LStrPasDone
+        incl    %ecx
         addl    $4,%edi
-        addb    $4,%cl
-        // since ecx = 4 at the start of the loop, it will always count
-        // upto exactly 0
-        jnz     .LStrCopyAligned
-        jmp     .LStrCopyDone
-.LStrCopy3Bytes:
-        addb     $3,%cl
-        jmp     .LStrCopyDone
-.LStrCopyWord:
-        addb    $2,%cl
-        jmp     .LStrCopyDone
-.LStrCopyByte:
+        cmpl    $252,%ecx
+        jbe     .LStrPasAligned
+        testb   %cl,%cl
+        jz      .LStrPasDone
+        movl    (%esi),%eax
+.LStrPasEndLoop:
+        testb   %al,%al
+        jz      .LStrPasDone
+        movb    %al,(%edi)
+        shrl    $8,%eax
+        incl    %edi
         incb    %cl
-.LStrCopyDone:
+        jnz     .LStrPasEndLoop
+.LStrPasDone:
         movl    __RESULT,%edi
         addb    $255,%cl
         movb    %cl,(%edi)
-end ['EAX','ECX','ESI','EDI'];
+end ['EAX','ECX','EDX','ESI','EDI'];
 end;
 
 function strpcopy(d : pchar;const s : string) : pchar;assembler;
 asm
         pushl   %esi            // Save ESI
         cld
-        movl    d,%edi          // load destination address
         movl    s,%esi          // Load Source adress
-        lodsb                   // load length in ECX
-        movzbl  %al,%ecx
+        movl    d,%edi          // load destination address
+        movzbl  (%esi),%ecx        // load length in ECX
+        incl    %esi
         rep
         movsb
-        xorb    %al,%al         // Set #0
-        stosb
+        movb    $0,(%edi)
         movl    d,%eax       // return value to EAX
         popl    %esi
 end ['EDI','EAX','ECX'];
 
 {
   $Log$
-  Revision 1.14  2000-06-30 12:20:20  jonas
+  Revision 1.15  2000-07-01 10:52:12  jonas
+    * fixed reading past end-of-heap again (correctly this time I hope)
+
+  Revision 1.14  2000/06/30 12:20:20  jonas
     * strpas is again slightly slower, but won't crash anymore if a pchar
       is passed to it that starts less than 4 bbytes from the heap end