-------------------------------------------------------------------------------------------------------------------------------
                      [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.