------------------------------------------------------------
                        [BUG/PRB.] VFP 9.0 FIX - STRCONV() FUNCTION
                                 January 2023
                 ------------------------------------------------------------
                                     CCB



1. BUG:

     In vfp9 (and vfp8), sometimes vfp will crash when calling the STRCONV(cExpression,14) function.

     There is the bug for STRCONV(cExpression,14) function, there is no the bug for other STRCONV() functions.

     There is a test program:

     *PROC teststrconvfunction

     x1=STRCONV(REPLICATE("a",0x3000)+"b",13)
     x2=STRCONV(LEFT(x1,0x4000+1),14)

     RETURN

     * END OF PROC TESTSTRCONVFUNCTION.


2. CAUSE:

     For example, for the code:
     x1=STRCONV(REPLICATE("a",0x3000)+"b",13)
     vfp will allocate INT((0x3000+1)/3)*4 + 4 = 0x4004 bytes memory to save the returned result.

     x2=STRCONV(LEFT(x1,0x4000+1),14)
     In vfp9 (and vfp8), it will allocate ROUND((0x4000+1)/4,0)*3 = 0x3000 bytes memory to save the returned result,
     but it needs 0x3001 bytes memory to save the returned result, buffer overflow!!!

     In VFP Advanced, it will allocate ROUND((0x4000+1)/4,0)*3 + 3 = 0x3003 bytes memory to save the returned result,
     so there is no the bug.


3. RESOLUTION:

     We can write some code to fix the BUG.

     CallBackc2f6c7c :: ; proc near
             mov  dword ptr [ ebp - 16 ] , 0200h                             ;0x0c2f6c7c :        c745f000020000

     Labelc2f6c83 ::
             cmp  dword ptr [ ebp + 12 ] , edi                               ;0x0c2f6c83 :        397d0c
             je Labelc2f6cdb                                                 ;0x0c2f6c86 :        7453
             cmp  dword ptr [ ebp + 12 ] , 07D0h                             ;0x0c2f6c88 :        817d0cd0070000
             ja Labelc2f6cc9                                                 ;0x0c2f6c8f :        7738
             cmp  dword ptr [ Datac41a178 ] , 03h                            ;0x0c2f6c91 :        833d78a1410c03
             jne Labelc2f6ca1                                                ;0x0c2f6c98 :        7507
             mov eax , 0100000h                                              ;0x0c2f6c9a :        b800001000
             jmp Labelc2f6cb0                                                ;0x0c2f6c9f :        eb0f

     Labelc2f6ca1 ::
             xor eax , eax                                                   ;0x0c2f6ca1 :        33c0
             call Func026283                                                 ;0x0c2f6ca3 :        e8dbf5d2ff
             mov eax , esp                                                   ;0x0c2f6ca8 :        8bc4
             sub  eax , dword ptr [ Datac41a1a4 ]                            ;0x0c2f6caa :        2b05a4a1410c

     Labelc2f6cb0 ::
             cmp  eax , dword ptr [ ebp + 12 ]                               ;0x0c2f6cb0 :        3b450c
             jle Labelc2f6cc5                                                ;0x0c2f6cb3 :        7e10
             mov  eax , dword ptr [ ebp + 12 ]                               ;0x0c2f6cb5 :        8b450c


     ;
     ;                 -------------------------------------------------
     ;                        VFP 9.0 FIX - STRCONV() FUNCTION
     ;                                December 2022
     ;                 -------------------------------------------------
     ;                                     CCB
     ;
     ; Sometimes vfp will crash when calling the STRCONV() function.
     ;
     ; 2022/12/12, by ccb
     ;

             cmp ebx , 0Eh
             jne Labelc2f6cb8
             add eax , 03h


     Labelc2f6cb8 ::
             add eax , 03h                                                   ;0x0c2f6cb8 :        83c003
             and eax , 0FFFFFFFCh                                            ;0x0c2f6cbb :        83e0fc
             call Func026283                                                 ;0x0c2f6cbe :        e8c0f5d2ff
             mov edi , esp                                                   ;0x0c2f6cc3 :        8bfc

     Labelc2f6cc5 ::
             test edi , edi                                                  ;0x0c2f6cc5 :        85ff
             jne Labelc2f6cdb                                                ;0x0c2f6cc7 :        7512

     Labelc2f6cc9 ::
             mov  eax , dword ptr [ ebp + 12 ]                               ;0x0c2f6cc9 :        8b450c


     ;
     ;                 -------------------------------------------------
     ;                        VFP 9.0 FIX - STRCONV() FUNCTION
     ;                                December 2022
     ;                 -------------------------------------------------
     ;                                     CCB
     ;
     ; Sometimes vfp will crash when calling the STRCONV() function.
     ;
     ; 2022/12/12, by ccb
     ;

             cmp ebx , 0Eh
             jne Labelc2f6ccc
             add eax , 03h


     Labelc2f6ccc ::
             pushd 01008h                                                    ;0x0c2f6ccc :        6808100000
             call Func0261af                                                 ;0x0c2f6cd1 :        e8d9f4d2ff
             mov  edi , dword ptr [eax]                                      ;0x0c2f6cd6 :        8b38
             mov  dword ptr [ ebp - 24 ] , eax                               ;0x0c2f6cd8 :        8945e8

     Labelc2f6cdb ::
             cmp ebx , 0Dh                                                   ;0x0c2f6cdb :        83fb0d
             jg Labelc2f6d88                                                 ;0x0c2f6cde :        0f8fa4000000
             je Labelc2f6d63                                                 ;0x0c2f6ce4 :        747d
             mov eax , ebx                                                   ;0x0c2f6ce6 :        8bc3
             sub eax , 05h                                                   ;0x0c2f6ce8 :        83e805
             je Labelc2f6d44                                                 ;0x0c2f6ceb :        7457
             dec eax                                                         ;0x0c2f6ced :        48
             je Labelc2f6d27                                                 ;0x0c2f6cee :        7437
             sub eax , 04h                                                   ;0x0c2f6cf0 :        83e804
             je Labelc2f6d11                                                 ;0x0c2f6cf3 :        741c
             dec eax                                                         ;0x0c2f6cf5 :        48
             dec eax                                                         ;0x0c2f6cf6 :        48
             jne Labelc2f6d95                                                ;0x0c2f6cf7 :        0f8598000000
             mov  eax , dword ptr [ ebp + 12 ]                               ;0x0c2f6cfd :        8b450c
             shr eax , 1                                                     ;0x0c2f6d00 :        d1e8
             push eax                                                        ;0x0c2f6d02 :        50
             push edi                                                        ;0x0c2f6d03 :        57
             push esi                                                        ;0x0c2f6d04 :        56
             push  dword ptr [ ebp + 8 ]                                     ;0x0c2f6d05 :        ff7508
             pushd 00h                                                       ;0x0c2f6d08 :        6a00
             pushd 0FDE9h                                                    ;0x0c2f6d0a :        68e9fd0000
             jmp Labelc2f6d54                                                ;0x0c2f6d0f :        eb43

     Labelc2f6d11 ::
             xor eax , eax                                                   ;0x0c2f6d11 :        33c0
             push eax                                                        ;0x0c2f6d13 :        50
             push eax                                                        ;0x0c2f6d14 :        50
             push  dword ptr [ ebp + 12 ]                                    ;0x0c2f6d15 :        ff750c
             shr esi , 1                                                     ;0x0c2f6d18 :        d1ee
             push edi                                                        ;0x0c2f6d1a :        57
             push esi                                                        ;0x0c2f6d1b :        56
             push  dword ptr [ ebp + 8 ]                                     ;0x0c2f6d1c :        ff7508
             push eax                                                        ;0x0c2f6d1f :        50
             pushd 0FDE9h                                                    ;0x0c2f6d20 :        68e9fd0000
             jmp Labelc2f6d39                                                ;0x0c2f6d25 :        eb12

     Labelc2f6d27 ::
             xor eax , eax                                                   ;0x0c2f6d27 :        33c0
             push eax                                                        ;0x0c2f6d29 :        50
             push eax                                                        ;0x0c2f6d2a :        50
             push  dword ptr [ ebp + 12 ]                                    ;0x0c2f6d2b :        ff750c
             shr esi , 1                                                     ;0x0c2f6d2e :        d1ee
             push edi                                                        ;0x0c2f6d30 :        57
             push esi                                                        ;0x0c2f6d31 :        56
             push  dword ptr [ ebp + 8 ]                                     ;0x0c2f6d32 :        ff7508
             push eax                                                        ;0x0c2f6d35 :        50
             push  dword ptr [ ebp - 20 ]                                    ;0x0c2f6d36 :        ff75ec

     Labelc2f6d39 ::
             call  WideCharToMultiByte                         ;0x0c2f6d39 :        ff157cc13f0c
             jmp Labelc2f6dea                                                ;0x0c2f6d3f :        e9a6000000

     Labelc2f6d44 ::
             mov  eax , dword ptr [ ebp + 12 ]                               ;0x0c2f6d44 :        8b450c
             shr eax , 1                                                     ;0x0c2f6d47 :        d1e8
             push eax                                                        ;0x0c2f6d49 :        50
             push edi                                                        ;0x0c2f6d4a :        57
             push esi                                                        ;0x0c2f6d4b :        56
             push  dword ptr [ ebp + 8 ]                                     ;0x0c2f6d4c :        ff7508
             pushd 01h                                                       ;0x0c2f6d4f :        6a01
             push  dword ptr [ ebp - 20 ]                                    ;0x0c2f6d51 :        ff75ec

     Labelc2f6d54 ::
             call  MultiByteToWideChar                         ;0x0c2f6d54 :        ff15b8c13f0c
             mov esi , eax                                                   ;0x0c2f6d5a :        8bf0
             shl esi , 1                                                     ;0x0c2f6d5c :        d1e6
             jmp Labelc2f6dec                                                ;0x0c2f6d5e :        e989000000

     Labelc2f6d63 ::
             test edi , edi                                                  ;0x0c2f6d63 :        85ff
             jne Labelc2f6d7b                                                ;0x0c2f6d65 :        7514
             lea eax ,  dword ptr [ esi + 2 ]                                ;0x0c2f6d67 :        8d4602
             pushd 03h                                                       ;0x0c2f6d6a :        6a03
             xor edx , edx                                                   ;0x0c2f6d6c :        33d2
             pop ecx                                                         ;0x0c2f6d6e :        59
             div ecx                                                         ;0x0c2f6d6f :        f7f1
             mov esi , eax                                                   ;0x0c2f6d71 :        8bf0
             shl esi , 02h                                                   ;0x0c2f6d73 :        c1e602
             jmp Labelc2f6e01                                                ;0x0c2f6d76 :        e986000000

     Labelc2f6d7b ::
             mov  edx , dword ptr [ ebp + 8 ]                                ;0x0c2f6d7b :        8b5508
             push edi                                                        ;0x0c2f6d7e :        57
             mov eax , esi                                                   ;0x0c2f6d7f :        8bc6
             call Func2f67b2                                                 ;0x0c2f6d81 :        e82cfaffff
             jmp Labelc2f6dea                                                ;0x0c2f6d86 :        eb62

     Labelc2f6d88 ::
             mov eax , ebx                                                   ;0x0c2f6d88 :        8bc3
             sub eax , 0Eh                                                   ;0x0c2f6d8a :        83e80e
             je Labelc2f6ddf                                                 ;0x0c2f6d8d :        7450
             dec eax                                                         ;0x0c2f6d8f :        48
             je Labelc2f6dca                                                 ;0x0c2f6d90 :        7438
             dec eax                                                         ;0x0c2f6d92 :        48
             je Labelc2f6dbb                                                 ;0x0c2f6d93 :        7426

     Labelc2f6d95 ::
             cmp  dword ptr [ ebp + 20 ] , 00h                               ;0x0c2f6d95 :        837d1400
             jne Labelc2f6db1                                                ;0x0c2f6d99 :        7516
             push  dword ptr [ ebp + 12 ]                                    ;0x0c2f6d9b :        ff750c
             push edi                                                        ;0x0c2f6d9e :        57
             push esi                                                        ;0x0c2f6d9f :        56
             push  dword ptr [ ebp + 8 ]                                     ;0x0c2f6da0 :        ff7508
             push  dword ptr [ ebp - 16 ]                                    ;0x0c2f6da3 :        ff75f0
             push  dword ptr [ ebp + 16 ]                                    ;0x0c2f6da6 :        ff7510
             call  LCMapStringA                                ;0x0c2f6da9 :        ff156cc03f0c
             jmp Labelc2f6dea                                                ;0x0c2f6daf :        eb39

     Labelc2f6db1 ::
             mov ecx , 0385h                                                 ;0x0c2f6db1 :        b985030000
             call Func01494b                                                 ;0x0c2f6db6 :        e890dbd1ff

     Labelc2f6dbb ::
             mov  eax , dword ptr [ ebp + 8 ]                                ;0x0c2f6dbb :        8b4508
             pushd 01h                                                       ;0x0c2f6dbe :        6a01
             push edi                                                        ;0x0c2f6dc0 :        57
             mov ecx , esi                                                   ;0x0c2f6dc1 :        8bce
             call Func2f6aa0                                                 ;0x0c2f6dc3 :        e8d8fcffff
             jmp Labelc2f6dea                                                ;0x0c2f6dc8 :        eb20

     Labelc2f6dca ::
             test edi , edi                                                  ;0x0c2f6dca :        85ff
             jne Labelc2f6dd2                                                ;0x0c2f6dcc :        7504
             add esi , esi                                                   ;0x0c2f6dce :        03f6
             jmp Labelc2f6e01                                                ;0x0c2f6dd0 :        eb2f

     Labelc2f6dd2 ::
             mov  ecx , dword ptr [ ebp + 8 ]                                ;0x0c2f6dd2 :        8b4d08
             push edi                                                        ;0x0c2f6dd5 :        57
             mov eax , esi                                                   ;0x0c2f6dd6 :        8bc6
             call Func2f6a52                                                 ;0x0c2f6dd8 :        e875fcffff
             jmp Labelc2f6dea                                                ;0x0c2f6ddd :        eb0b

     Labelc2f6ddf ::
             mov  ecx , dword ptr [ ebp + 8 ]                                ;0x0c2f6ddf :        8b4d08
             push edi                                                        ;0x0c2f6de2 :        57
             mov eax , esi                                                   ;0x0c2f6de3 :        8bc6
             call Func2f689d                                                 ;0x0c2f6de5 :        e8b3faffff

     Labelc2f6dea ::
             mov esi , eax                                                   ;0x0c2f6dea :        8bf0

     Labelc2f6dec ::
             test edi , edi                                                  ;0x0c2f6dec :        85ff
             je Labelc2f6e01                                                 ;0x0c2f6dee :        7411
             cmp  dword ptr [ ebp + 12 ] , 00h                               ;0x0c2f6df0 :        837d0c00
             je Labelc2f6e01                                                 ;0x0c2f6df4 :        740b
             mov  ecx , dword ptr [ ebp + 8 ]                                ;0x0c2f6df6 :        8b4d08
             push esi                                                        ;0x0c2f6df9 :        56
             mov edx , edi                                                   ;0x0c2f6dfa :        8bd7
             call Func026168                                                 ;0x0c2f6dfc :        e867f3d2ff

     Labelc2f6e01 ::
             mov  ecx , dword ptr [ ebp - 24 ]                               ;0x0c2f6e01 :        8b4de8
             test ecx , ecx                                                  ;0x0c2f6e04 :        85c9
             je Labelc2f6e0d                                                 ;0x0c2f6e06 :        7405
             call Func02636a                                                 ;0x0c2f6e08 :        e85df5d2ff

     Labelc2f6e0d ::
             mov eax , esi                                                   ;0x0c2f6e0d :        8bc6
             lea esp ,  dword ptr [ ebp - 64 ]                               ;0x0c2f6e0f :        8d65c0
             mov  ecx , dword ptr [ ebp - 4 ]                                ;0x0c2f6e12 :        8b4dfc
             call Func02619c                                                 ;0x0c2f6e15 :        e882f3d2ff
             pop edi                                                         ;0x0c2f6e1a :        5f
             pop esi                                                         ;0x0c2f6e1b :        5e
             leave                                                           ;0x0c2f6e1c :        c9
             ret 010h                                                        ;0x0c2f6e1d :        c21000


4. APPLIES TO:

     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

     2, foxite.com:
     https://www.foxite.com/archives/base64-0000492043.htm


6. OTHER:

     For reference only, there is no guarantees.

     Any questions or suggestions, please send me an email at ccb2000@163.com.