Jelajahi Sumber

* Added a lower limit on tdynamicarray block size. Certain values less than dynamicblockbasesize+alignment, e.g. 8 on x86_64, cause grow() to enter an infinite loop. Such values come e.g. from cloning tdataconstnode, which abuses blocksize argument as data size. Mantis #20929.

git-svn-id: trunk@19873 -
sergei 13 tahun lalu
induk
melakukan
aea30f9bb2
1 mengubah file dengan 8 tambahan dan 1 penghapusan
  1. 8 1
      compiler/cclasses.pas

+ 8 - 1
compiler/cclasses.pas

@@ -433,6 +433,7 @@ type
 
      const
        dynamicblockbasesize = sizeof(tdynamicblock)-sizeof(tdynamicblockdata);
+       mindynamicblocksize = 8*sizeof(pointer);
 
      type
        tdynamicarray = class
@@ -2401,6 +2402,12 @@ end;
         FFirstblock:=nil;
         FLastblock:=nil;
         FCurrBlockSize:=0;
+        { Every block needs at least a header and alignment slack,
+          therefore its size cannot be arbitrarily small. However,
+          the blocksize argument is often confused with data size.
+          See e.g. Mantis #20929. }
+        if Ablocksize<mindynamicblocksize then
+          Ablocksize:=mindynamicblocksize;
         FMaxBlockSize:=Ablocksize;
         grow;
       end;
@@ -2454,7 +2461,7 @@ end;
       begin
         if CurrBlockSize<FMaxBlocksize then
           begin
-            IncSize := sizeof(ptrint)*8;
+            IncSize := mindynamicblocksize;
             if FCurrBlockSize > 255 then
               Inc(IncSize, FCurrBlockSize shr 2);
             inc(FCurrBlockSize,IncSize);