------------------------------------------------------------------------------- [BUG/PRB.] VFP 9.0 FIX - CHECK AVAILABLE MEMORY FOR COMPARING STRINGS January 2024 ------------------------------------------------------------------------------- CCB 1. BUG: If we enable checking available memory for comparing strings in Visual FoxPro Advanced, but there is not enough memory to compare strings, it will cause the error "There is not enough memory to complete this operation (Error 43)", or the error "Insufficient stack space (Error 1308)". It is the startup default for Visual FoxPro Advanced. If we disable checking available memory for comparing strings in Visual FoxPro Advanced, but there is not enough memory to compare strings, sometimes it will cause the error "There is not enough memory to complete this operation (Error 43)", or the error "Insufficient stack space (Error 1308)", sometimes it will cause the memory access violation exception (exception code 0xC0000005). The bug only occurs when SET("COLLATE") != "MACHINE", it does not occur when SET("COLLATE") == "MACHINE". The bug only occurs in the following functions and operators: BETWEEN() function, INLIST() function, < operator, <= operator, != operator, = operator, > operator, >= operator, == operator. 2. CAUSE: When SET("COLLATE") != "MACHINE", to compare strings in Visual FoxPro, it will use stack space to save some temporary data. Usually the default stack size is about 1 MB (in fact, the stack size is about 920 KB in Visual FoxPro), if the strings are too long, there is not enough stack space to save some temporary data, it will cause the error "There is not enough memory to complete this operation (Error 43)", or the error "Insufficient stack space (Error 1308)". Usually, to compare strings x1 and x2, it needs the stack size LEN(x1) + LEN(x2) + MAX(LEN(x1)*r , LEN(x2)*r), the rate variable r is between 1 and 4 for different collation sequence. For example, r = 2 when SET("COLLATE") == "PINYIN", x1=REPLICATE("a",250000) x2=REPLICATE("b",150000) it needs the stack size 250 + 150 + MAX(250*2 , 150*2) = 900 KB < 920 KB, for the expression x2 > x1, usually it will run fine. For example, r = 2 when SET("COLLATE") == "PINYIN", x1=REPLICATE("a",300000) x2=REPLICATE("b",100000) it needs the stack size 300 + 100 + MAX(300*2 , 100*2) = 1000 KB > 920 KB, for the expression x2 > x1, it will cause the error "There is not enough memory to complete this operation (Error 43)", or the error "Insufficient stack space (Error 1308)". 3. RESOLUTION: We can write some code to fix the BUG. Fun53beb2 :: ; proc near push ebp ;0x0053beb2 : 55 mov ebp , esp ;0x0053beb3 : 8bec sub esp , 020h ;0x0053beb5 : 83ec20 mov eax , dword ptr [ Data9370f8 ] ;0x0053beb8 : a1f8709300 mov edx , dword ptr [eax] ;0x0053bebd : 8b10 mov ecx , dword ptr [ ebp + 12 ] ;0x0053bebf : 8b4d0c mov eax , dword ptr [ edx + 0C8h ] ;0x0053bec2 : 8b82c8000000 test eax , eax ;0x0053bec8 : 85c0 push ebx ;0x0053beca : 53 push esi ;0x0053becb : 56 mov esi , dword ptr [ ebp + 8 ] ;0x0053becc : 8b7508 mov ebx , dword ptr [ esi + 8 ] ;0x0053becf : 8b5e08 push edi ;0x0053bed2 : 57 mov edi , dword ptr [ ecx + 8 ] ;0x0053bed3 : 8b7908 mov dword ptr [ ebp - 16 ] , edi ;0x0053bed6 : 897df0 mov dword ptr [ ebp - 8 ] , eax ;0x0053bed9 : 8945f8 je Label502873 ;0x0053bedc : 0f849169fcff cmp dword ptr [ esi + 4 ] , 01h ;0x0053bee2 : 837e0401 je Label502873 ;0x0053bee6 : 0f848769fcff ; ; -------------------------------------------------------------------- ; VFP 9.0 FIX - CHECK AVAILABLE MEMORY FOR COMPARING STRINGS ; May 2022 ; -------------------------------------------------------------------- ; CCB ; ; Check available memory for comparing strings. ; ; 2022/5/8, by ccb ; cmp dword ptr vfpa_sys9077_data,00h je Label53beec cmp ebx , 07FFFE0h jge Label58e6b4 cmp edi , 07FFFE0h jge Label58e6b4 mov dword ptr [ ebp - 12 ] , ebx mov dword ptr [ ebp - 28 ] , edi mov dword ptr [ ebp - 24 ] , 00h mov dword ptr [ ebp - 20 ] , 00h xor eax , eax call Fun42c118 mov ecx , esp sub ecx , dword ptr [ Data9370c4 ] lea eax , dword ptr [ ebx + edi ] add eax , 03h and eax , 0FFFFFFFCh cmp ecx , eax jle Label58e6b4 Label53beec :: lea eax , dword ptr [ ebx + edi ] ;0x0053beec : 8d043b add eax , 03h ;0x0053beef : 83c003 and eax , 0FFFFFFFCh ;0x0053bef2 : 83e0fc mov dword ptr [ ebp - 12 ] , ebx ;0x0053bef5 : 895df4 mov dword ptr [ ebp - 28 ] , edi ;0x0053bef8 : 897de4 call Fun42c118 ;0x0053befb : e81802efff mov ecx , esp ;0x0053bf00 : 8bcc test ecx , ecx ;0x0053bf02 : 85c9 mov dword ptr [ ebp - 24 ] , ecx ;0x0053bf04 : 894de8 je Label58e685 ;0x0053bf07 : 0f8478270500 mov eax , dword ptr [ esi + 32 ] ;0x0053bf0d : 8b4620 mov edx , dword ptr [eax] ;0x0053bf10 : 8b10 push ebx ;0x0053bf12 : 53 mov dword ptr [ ebp - 20 ] , 01h ;0x0053bf13 : c745ec01000000 call Fun42c19b ;0x0053bf1a : e87c02efff mov ecx , dword ptr [ ebp + 12 ] ;0x0053bf1f : 8b4d0c mov eax , dword ptr [ ebp - 24 ] ;0x0053bf22 : 8b45e8 mov edx , dword ptr [ ecx + 32 ] ;0x0053bf25 : 8b5120 lea ecx , dword ptr [ eax + ebx ] ;0x0053bf28 : 8d0c18 Label53bf2b :: mov edx , dword ptr [edx] ;0x0053bf2b : 8b12 push edi ;0x0053bf2d : 57 call Fun42c19b ;0x0053bf2e : e86802efff mov eax , dword ptr [ ebp + 16 ] ;0x0053bf33 : 8b4510 sub eax , 02h ;0x0053bf36 : 83e802 je Label58e72b ;0x0053bf39 : 0f84ec270500 cmp ebx , edi ;0x0053bf3f : 3bdf mov ecx , ebx ;0x0053bf41 : 8bcb jb Label53bf47 ;0x0053bf43 : 7202 mov ecx , edi ;0x0053bf45 : 8bcf Label53bf47 :: mov edx , dword ptr [ ebp + 12 ] ;0x0053bf47 : 8b550c mov eax , dword ptr [ edx + 32 ] ;0x0053bf4a : 8b4220 mov edx , dword ptr [ esi + 32 ] ;0x0053bf4d : 8b5620 mov edi , dword ptr [eax] ;0x0053bf50 : 8b38 mov esi , dword ptr [edx] ;0x0053bf52 : 8b32 xor eax , eax ;0x0053bf54 : 33c0 repz cmpsb ;0x0053bf56 : f3a6 je Label53bf5f ;0x0053bf58 : 7405 sbb eax , eax ;0x0053bf5a : 1bc0 sbb eax , 0FFFFFFFFh ;0x0053bf5c : 83d8ff Label53bf5f :: mov edi , eax ;0x0053bf5f : 8bf8 test edi , edi ;0x0053bf61 : 85ff je Label53bfb9 ;0x0053bf63 : 7454 mov esi , dword ptr [ ebp - 8 ] ;0x0053bf65 : 8b75f8 mov edi , dword ptr [ ebp + 8 ] ;0x0053bf68 : 8b7d08 push esi ;0x0053bf6b : 56 xor eax , eax ;0x0053bf6c : 33c0 mov ecx , edi ;0x0053bf6e : 8bcf call Fun53c1a9 ;0x0053bf70 : e834020000 push esi ;0x0053bf75 : 56 mov esi , dword ptr [ ebp + 12 ] ;0x0053bf76 : 8b750c mov ebx , eax ;0x0053bf79 : 8bd8 xor eax , eax ;0x0053bf7b : 33c0 mov ecx , esi ;0x0053bf7d : 8bce call Fun53c1a9 ;0x0053bf7f : e825020000 mov ecx , eax ;0x0053bf84 : 8bc8 mov eax , dword ptr [ ebp - 8 ] ;0x0053bf86 : 8b45f8 mov edx , dword ptr [eax] ;0x0053bf89 : 8b10 mov eax , dword ptr [ edx + 16 ] ;0x0053bf8b : 8b4210 test eax , eax ;0x0053bf8e : 85c0 mov dword ptr [ ebp - 16 ] , ecx ;0x0053bf90 : 894df0 jne Label58e716 ;0x0053bf93 : 0f857d270500 cmp ebx , ecx ;0x0053bf99 : 3bd9 pushd 00h ;0x0053bf9b : 6a00 jb Label53b85e ;0x0053bf9d : 0f82bbf8ffff Label53bfa3 :: mov edx , dword ptr [ esi + 32 ] ;0x0053bfa3 : 8b5620 mov eax , dword ptr [edx] ;0x0053bfa6 : 8b02 push eax ;0x0053bfa8 : 50 mov eax , dword ptr [ edi + 32 ] ;0x0053bfa9 : 8b4720 mov eax , dword ptr [eax] ;0x0053bfac : 8b00 mov edx , ecx ;0x0053bfae : 8bd1 mov ecx , ebx ;0x0053bfb0 : 8bcb call Fun53c1fb ;0x0053bfb2 : e844020000 mov edi , eax ;0x0053bfb7 : 8bf8 Label53bfb9 :: mov esi , dword ptr [ ebp + 8 ] ;0x0053bfb9 : 8b7508 Label53bfbc :: mov eax , dword ptr [ ebp - 20 ] ;0x0053bfbc : 8b45ec test eax , eax ;0x0053bfbf : 85c0 mov eax , dword ptr [ esi + 32 ] ;0x0053bfc1 : 8b4620 je Label58e768 ;0x0053bfc4 : 0f849e270500 mov ecx , dword ptr [ ebp - 12 ] ;0x0053bfca : 8b4df4 mov esi , dword ptr [ ebp - 24 ] ;0x0053bfcd : 8b75e8 push ecx ;0x0053bfd0 : 51 mov ecx , dword ptr [eax] ;0x0053bfd1 : 8b08 mov edx , esi ;0x0053bfd3 : 8bd6 call Fun42c19b ;0x0053bfd5 : e8c101efff mov ecx , dword ptr [ ebp - 28 ] ;0x0053bfda : 8b4de4 mov eax , dword ptr [ ebp + 12 ] ;0x0053bfdd : 8b450c mov edx , dword ptr [ ebp - 12 ] ;0x0053bfe0 : 8b55f4 push ecx ;0x0053bfe3 : 51 mov ecx , dword ptr [ eax + 32 ] ;0x0053bfe4 : 8b4820 mov ecx , dword ptr [ecx] ;0x0053bfe7 : 8b09 add edx , esi ;0x0053bfe9 : 03d6 call Fun42c19b ;0x0053bfeb : e8ab01efff Label53bff0 :: test edi , edi ;0x0053bff0 : 85ff je Label53b7d7 ;0x0053bff2 : 0f84dff7ffff Label53bff8 :: mov eax , edi ;0x0053bff8 : 8bc7 lea esp , dword ptr [ ebp - 44 ] ;0x0053bffa : 8d65d4 pop edi ;0x0053bffd : 5f pop esi ;0x0053bffe : 5e pop ebx ;0x0053bfff : 5b mov esp , ebp ;0x0053c000 : 8be5 pop ebp ;0x0053c002 : 5d ret 0Ch ;0x0053c003 : c20c00 4. APPLIES TO: VFP 6.0.8167.0 VFP 6.0.8961.0 (SP5) VFP 7.0.0.9262 VFP 7.0.0.9465 (SP1) VFP 8.0.0.2521 VFP 8.0.0.3117 (SP1) VFP 9.0.0.2412 VFP 9.0.0.3504 (SP1) VFP 9.0.0.4611 (SP2) VFP 9.0.0.5015 (SP2) VFP 9.0.0.5411 (SP2) VFP 9.0.0.5721 (SP2) VFP 9.0.0.5815 (SP2) VFP 9.0.0.6303 (SP2) VFP 9.0.0.6602 (SP2) VFP 9.0.0.7423 (SP2) The bug has been fixed in VFP Advanced. 5. REFERENCE WEBSITES: 1, baiyujia.com: http://www.baiyujia.com http://www.baiyujia.com/vfpdocuments/f_vfp9fix208.asp http://www.baiyujia.com/vfpdocuments/f_vfp9fix210.asp http://www.baiyujia.com/vfpdocuments/f_vfp9fix211.asp 6. OTHER: For reference only, there is no guarantees. Any questions or suggestions, please send me an email at ccb2000@163.com. |