------------------------------------------------------------------------------------------------------------------------------- [BUG/PRB.] VFP 9.0 FIX - ADJUST THE LENGTH OF THE RETURNED STRING OF ASTERISKS WHEN CONVERTING AN INTEGER TO A STRING March 2024 ------------------------------------------------------------------------------------------------------------------------------- CCB 1. BUG: There is a test program: *PROC testindexonstrfunction CLOSE DATABASES ALL CLOSE TABLES ALL CREATE CURSOR curs1 (field1 c(4)) INDEX ON STR(CTOBIN(field1),10) TAG tag1 && no error. INSERT INTO curs1 VALUES (BINTOC(1)) && causes the error "Error building key for index 'name' (Error 2199)"! WAIT CLOSE DATABASES ALL CLOSE TABLES ALL CREATE CURSOR curs1 (field1 c(4)) INSERT INTO curs1 VALUES (BINTOC(1)) && no error. INDEX ON STR(CTOBIN(field1),10) TAG tag1 && no error. INSERT INTO curs1 VALUES (BINTOC(1)) && no error. WAIT RETURN * END OF PROC TESTINDEXONSTRFUNCTION. The bug was reported by Ravil. 2. CAUSE: When VFP run the following code to create an index file: INDEX ON STR(CTOBIN(field1),10) TAG tag1 If there is no record (RECCOUNT() = 0), or there is only a blank record (RECCOUNT() = 1), field1 = SPACE(4) CTOBIN(field1) = 0x80202020 (signed integer) = -0x7FDFDFDF = -2145378271 STR(CTOBIN(field1),10) = STR(-2145378271,10) = "****" && nLength1 >= 7, nLength1 = nLength1 - 6 = 4. and then VFP run the following code: INSERT INTO curs1 VALUES (BINTOC(1)) STR(CTOBIN(field1),10) = STR(1,10) = " 1" && nLength2 = 10. nLength2 != nLength1, so it causes the error "Error building key for index 'name' (Error 2199)"! For example, INDEX ON STR(CTOBIN(field1),1) TAG tag1 && no error. INDEX ON STR(CTOBIN(field1),2) TAG tag1 && no error. INDEX ON STR(CTOBIN(field1),3) TAG tag1 && no error. INDEX ON STR(CTOBIN(field1),4) TAG tag1 && no error. INDEX ON STR(CTOBIN(field1),5) TAG tag1 && no error. INDEX ON STR(CTOBIN(field1),6) TAG tag1 && no error. INDEX ON STR(CTOBIN(field1),7) TAG tag1 && causes the error "Error building key for index 'name' (Error 2199)"! INDEX ON STR(CTOBIN(field1),8) TAG tag1 && causes the error "Error building key for index 'name' (Error 2199)"! INDEX ON STR(CTOBIN(field1),9) TAG tag1 && causes the error "Error building key for index 'name' (Error 2199)"! INDEX ON STR(CTOBIN(field1),10) TAG tag1 && causes the error "Error building key for index 'name' (Error 2199)"! INDEX ON STR(CTOBIN(field1),11) TAG tag1 && no error, because nLength >= the maximum of the length of a signed integer (11). INDEX ON STR(CTOBIN(field1),12) TAG tag1 && no error, because nLength >= the maximum of the length of a signed integer (11). INDEX ON STR(CTOBIN(field1),13) TAG tag1 && no error, because nLength >= the maximum of the length of a signed integer (11). INDEX ON STR(CTOBIN(field1),14) TAG tag1 && no error, because nLength >= the maximum of the length of a signed integer (11). INDEX ON STR(CTOBIN(field1),15) TAG tag1 && no error, because nLength >= the maximum of the length of a signed integer (11). ... Recommend to set nLength >= 11 to use the STR() function to convert an integer to a string. 3. RESOLUTION: We can write some code to fix the BUG. Fun4309ad :: ; proc near push ebp ;0x004309ad : 55 mov ebp , esp ;0x004309ae : 8bec sub esp , 02Ch ;0x004309b0 : 83ec2c test edx , edx ;0x004309b3 : 85d2 mov eax , dword ptr [ Data937090 ] ;0x004309b5 : a190709300 push ebx ;0x004309ba : 53 push esi ;0x004309bb : 56 push edi ;0x004309bc : 57 mov edi , ecx ;0x004309bd : 8bf9 mov dword ptr [ ebp - 4 ] , eax ;0x004309bf : 8945fc mov dword ptr [ ebp - 40 ] , edx ;0x004309c2 : 8955d8 mov dword ptr [ ebp - 36 ] , edi ;0x004309c5 : 897ddc mov byte ptr [ ebp - 29 ] , 00h ;0x004309c8 : c645e300 jl Label487993 ;0x004309cc : 0f8cc16f0500 Label4309d2 :: mov ebx , edx ;0x004309d2 : 8bda lea esi , dword ptr [ ebp - 8 ] ;0x004309d4 : 8d75f8 Label4309d7 :: mov eax , ebx ;0x004309d7 : 8bc3 xor edx , edx ;0x004309d9 : 33d2 pushd 0Ah ;0x004309db : 6a0a pop ecx ;0x004309dd : 59 div ecx ;0x004309de : f7f1 mov dl , 0Ah ;0x004309e0 : b20a dec esi ;0x004309e2 : 4e mov ecx , eax ;0x004309e3 : 8bc8 mov al , cl ;0x004309e5 : 8ac1 imul dl ;0x004309e7 : f6ea sub bl , al ;0x004309e9 : 2ad8 add bl , 030h ;0x004309eb : 80c330 test ecx , ecx ;0x004309ee : 85c9 mov byte ptr [esi] , bl ;0x004309f0 : 881e mov ebx , ecx ;0x004309f2 : 8bd9 jne Label4309d7 ;0x004309f4 : 75e1 cmp byte ptr [ ebp - 29 ] , cl ;0x004309f6 : 384de3 jne Label48799e ;0x004309f9 : 0f859f6f0500 Label4309ff :: mov ebx , dword ptr [ ebp + 8 ] ;0x004309ff : 8b5d08 mov edx , esi ;0x00430a02 : 8bd6 lea eax , dword ptr [ ebp - 8 ] ;0x00430a04 : 8d45f8 sub edx , eax ;0x00430a07 : 2bd0 add edx , ebx ;0x00430a09 : 03d3 test edx , edx ;0x00430a0b : 85d2 mov byte ptr [ ebp - 8 ] , 00h ;0x00430a0d : c645f800 jg Label4eec03 ;0x00430a11 : 0f8fece10b00 Label430a17 :: jnl Label430a23 ;0x00430a17 : 7d0a cmp dword ptr [ ebp + 12 ] , 00h ;0x00430a19 : 837d0c00 jne Label59b03b ;0x00430a1d : 0f8518a61600 Label430a23 :: mov edx , dword ptr [ ebp - 36 ] ;0x00430a23 : 8b55dc mov eax , esi ;0x00430a26 : 8bc6 sub edx , esi ;0x00430a28 : 2bd6 Label430a2a :: mov cl , byte ptr [eax] ;0x00430a2a : 8a08 mov byte ptr [ edx + eax ] , cl ;0x00430a2c : 880c02 inc eax ;0x00430a2f : 40 test cl , cl ;0x00430a30 : 84c9 jne Label430a2a ;0x00430a32 : 75f6 xor eax , eax ;0x00430a34 : 33c0 Label430a36 :: mov ecx , dword ptr [ ebp - 4 ] ;0x00430a36 : 8b4dfc call Fun42bf1d ;0x00430a39 : e8dfb4ffff pop edi ;0x00430a3e : 5f pop esi ;0x00430a3f : 5e pop ebx ;0x00430a40 : 5b leave ;0x00430a41 : c9 ret 08h ;0x00430a42 : c20800 Label59b03b :: cmp ebx , 07h ;0x0059b03b : 83fb07 jnl Label59b067 ;0x0059b03e : 7d27 mov edi , dword ptr [ ebp - 36 ] ;0x0059b040 : 8b7ddc mov ecx , ebx ;0x0059b043 : 8bcb mov edx , ecx ;0x0059b045 : 8bd1 shr ecx , 02h ;0x0059b047 : c1e902 mov eax , 02A2A2A2Ah ;0x0059b04a : b82a2a2a2a rep stosd ;0x0059b04f : f3ab mov ecx , edx ;0x0059b051 : 8bca and ecx , 03h ;0x0059b053 : 83e103 rep stosb ;0x0059b056 : f3aa mov eax , dword ptr [ ebp - 36 ] ;0x0059b058 : 8b45dc mov byte ptr [ eax + ebx ] , 00h ;0x0059b05b : c6041800 Label59b05f :: xor eax , eax ;0x0059b05f : 33c0 inc eax ;0x0059b061 : 40 jmp Label430a36 ;0x0059b062 : e9cf59e9ff Label59b067 :: fild dword ptr [ ebp - 40 ] ;0x0059b067 : db45d8 push ecx ;0x0059b06a : 51 push ecx ;0x0059b06b : 51 mov ecx , dword ptr [ ebp - 36 ] ;0x0059b06c : 8b4ddc ; ; -------------------------------------------------------------------------------------------------------------------- ; VFP 9.0 FIX - ADJUST THE LENGTH OF THE RETURNED STRING OF ASTERISKS WHEN CONVERTING AN INTEGER TO A STRING ; March 2024 ; -------------------------------------------------------------------------------------------------------------------- ; CCB ; ; Adjust the length of the returned string of asterisks when converting an integer to a string. ; ; 2024/3/1, by ccb ; push eax push ecx push edi mov edi , ecx mov ecx , ebx xor eax , eax cld rep stosb pop edi pop ecx pop eax mov eax , ebx cmp dword ptr vfpa_sys9148_data,00h je Label59b072 lea eax , dword ptr [ ebx - 6 ] ;0x0059b06f : 8d43fa Label59b072 :: fstp qword ptr [ esp ] ;0x0059b072 : dd1c24 call Fun76a15c ;0x0059b075 : e8e2f01c00 jmp Label59b05f ;0x0059b07a : ebe3 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_vfp9fix309.asp 2, github.io: https://hackfox.github.io/section4/s4g022.html 6. OTHER: For reference only, there is no guarantees. Any questions or suggestions, please send me an email at ccb2000@163.com. |