-------------------------------------------------------------------------------------------------------------------------------
[BUG/PRB.] VFP 9.0 FIX - ADJUST THE LENGTH OF THE RETURNED STRING OF ASTERISKS WHEN CONVERTING AN INTEGER TO A STRING
January 2026
-------------------------------------------------------------------------------------------------------------------------------
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.
|