------------------------------------------------------------------------------------------------------
                      [BUG/PRB.] VFP 9.0 FIX - FIX THE MACRO SUBSTITUTION SPECIFIES THE NAME WITH AN ARRAY ELEMENT
                                 January 2024
                 ------------------------------------------------------------------------------------------------------
                                     CCB



1. BUG:

     In vfp9 (and vfp6, vfp7, vfp8), if the macro substitution specifies the name with an array element,
     sometimes the macro substitution will not be replaced.

     In Visual FoxPro Advanced, if the macro substitution specifies the name with an array element,
     the macro substitution will be replaced with the content of the array element.

     There is a test program:

     *PROC testmacroarray

     PUBLIC x1(300)
     x1="ABC"

     ?"&X1(255)" && it displays "ABC", ok.
     WAIT

     ?"&X1(256)" && sometimes it displays "&X1(256)" in vfp9! it always displays "ABC" in Visual FoxPro Advanced, ok.
     WAIT

     RETURN

     * END OF PROC TESTMACROARRAY.


2. CAUSE:

     In vfp9 (and vfp6, vfp7, vfp8), for example,
     the expression X1(256) will be compiled to the p-code (total 10 bytes):
     F6 18 04 FC F9 03 00 01 FD 03 ?? ?? ?? ?? ?? ??
     -----------------------------------------------
     the pointer of p-code points to the end of the p-code (the 11th byte: ??),
     if the 11th byte is 0x51 (AS type),
     the macro substitution will not be replaced.

     There are some BUGs in the following code.


3. RESOLUTION:

     We can write some code to fix the BUG.

     Label4b77d4 ::
             pushd 00h                                                       ;0x004b77d4 :        6a00
             lea eax ,  dword ptr [ ebp + 0FFFFFE38h ]                       ;0x004b77d6 :        8d8538feffff
             push eax                                                        ;0x004b77dc :        50
             call Fun432788                                                  ;0x004b77dd :        e8a6aff7ff
             cmp eax , 0FFFFFFFFh                                            ;0x004b77e2 :        83f8ff
             je Label504787                                                  ;0x004b77e5 :        0f849ccf0400
             mov  edx , dword ptr [ Data9388e4 ]                             ;0x004b77eb :        8b15e4889300
             lea ecx ,  dword ptr [ eax + 4 * eax ]                          ;0x004b77f1 :        8d0c80
             movzx ecx ,word ptr [ edx + 4 * ecx + 14 ]                      ;0x004b77f4 :        0fb74c8a0e
             pushd 00h                                                       ;0x004b77f9 :        6a00
             dec ecx                                                         ;0x004b77fb :        49
             call Fun53c57a                                                  ;0x004b77fc :        e8794d0800
             cmp eax , 0FFFFFFFFh                                            ;0x004b7801 :        83f8ff
             je Label504787                                                  ;0x004b7804 :        0f847dcf0400
             call Fun531d24                                                  ;0x004b780a :        e815a50700
             imul eax , eax , 01Eh                                           ;0x004b780f :        6bc01e
             mov  ecx , dword ptr [ Data936b68 ]                             ;0x004b7812 :        8b0d686b9300
             cmp  byte ptr [ eax + ecx ] , 041h                              ;0x004b7818 :        803c0841
             jne Label504787                                                 ;0x004b781c :        0f8565cf0400
             mov  eax , dword ptr [ ebp + 0FFFFFD0Ch ]                       ;0x004b7822 :        8b850cfdffff
             mov  edx , dword ptr [ Data937f94 ]                             ;0x004b7828 :        8b15947f9300
             inc eax                                                         ;0x004b782e :        40
             pushd 041h                                                      ;0x004b782f :        6a41
             mov  dword ptr [ ebp + 0FFFFFD30h ] , eax                       ;0x004b7831 :        898530fdffff
             push edx                                                        ;0x004b7837 :        52
             lea eax ,  dword ptr [ ebp + 0FFFFFD10h ]                       ;0x004b7838 :        8d8510fdffff
             push eax                                                        ;0x004b783e :        50
             mov  byte ptr [ ebp + 0FFFFFD10h ] , 07h                        ;0x004b783f :        c68510fdffff07
             call Fun50c6e5                                                  ;0x004b7846 :        e89a4e0500
             mov edi , eax                                                   ;0x004b784b :        8bf8
             mov  eax , dword ptr [ ebp + 0FFFFFD30h ]                       ;0x004b784d :        8b8530fdffff
             cmp  byte ptr [eax] , 02Eh                                      ;0x004b7853 :        80382e
             mov  dword ptr [ ebp + 0FFFFFD08h ] , eax                       ;0x004b7856 :        898508fdffff
             je Label5b1986                                                  ;0x004b785c :        0f8424a10f00

     Label4b7862 ::
             test edi , edi                                                  ;0x004b7862 :        85ff
             jl Label5047a4                                                  ;0x004b7864 :        0f8c3acf0400
             xor eax , eax                                                   ;0x004b786a :        33c0
             call Fun42c118                                                  ;0x004b786c :        e8a748f7ff
             mov  edx , dword ptr [ Data9370c4 ]                             ;0x004b7871 :        8b15c4709300
             mov eax , esp                                                   ;0x004b7877 :        8bc4
             sub eax , edx                                                   ;0x004b7879 :        2bc2
             cmp eax , edi                                                   ;0x004b787b :        3bc7
             jle Label5b1992                                                 ;0x004b787d :        0f8e0fa10f00
             mov eax , edi                                                   ;0x004b7883 :        8bc7


     ;
     ;                 -------------------------------------------------------------------------------------------
     ;                      VFP 9.0 FIX - FIX THE MACRO SUBSTITUTION SPECIFIES THE NAME WITH AN ARRAY ELEMENT
     ;                                February 2023
     ;                 -------------------------------------------------------------------------------------------
     ;                                     CCB
     ;
     ; Fix the macro substitution specifies the name with an array element.
     ;
     ; 2023/2/9, by ccb
     ;

             add eax , 01h


             add eax , 07h                                                   ;0x004b7885 :        83c007
             and eax , 0FFFFFFF8h                                            ;0x004b7888 :        83e0f8
             call Fun42c118                                                  ;0x004b788b :        e88848f7ff
             mov esi , esp                                                   ;0x004b7890 :        8bf4


     ;
     ;                 -------------------------------------------------------------------------------------------
     ;                      VFP 9.0 FIX - FIX THE MACRO SUBSTITUTION SPECIFIES THE NAME WITH AN ARRAY ELEMENT
     ;                                February 2023
     ;                 -------------------------------------------------------------------------------------------
     ;                                     CCB
     ;
     ; Fix the macro substitution specifies the name with an array element.
     ;
     ; 2023/2/9, by ccb
     ;

             mov byte ptr [esi+edi],00h


     Label4b7892 ::
             test esi , esi                                                  ;0x004b7892 :        85f6
             je Label5b1999                                                  ;0x004b7894 :        0f84ffa00f00
             mov  edx , dword ptr [ Data937f94 ]                             ;0x004b789a :        8b15947f9300
             push edi                                                        ;0x004b78a0 :        57
             mov ecx , esi                                                   ;0x004b78a1 :        8bce
             call Fun42c19b                                                  ;0x004b78a3 :        e8f348f7ff
             lea edx ,  dword ptr [ ebp + 0FFFFFCFCh ]                       ;0x004b78a8 :        8d95fcfcffff
             lea eax ,  dword ptr [ ebp + 0FFFFFC90h ]                       ;0x004b78ae :        8d8590fcffff
             mov  dword ptr [ Data9393ac ] , esi                             ;0x004b78b4 :        8935ac939300
             call Fun42c27f                                                  ;0x004b78ba :        e8c049f7ff
             pushd 00h                                                       ;0x004b78bf :        6a00
             push eax                                                        ;0x004b78c1 :        50
             call Fun42c2be                                                  ;0x004b78c2 :        e8f749f7ff
             mov esi , eax                                                   ;0x004b78c7 :        8bf0
             add esp , 08h                                                   ;0x004b78c9 :        83c408
             test esi , esi                                                  ;0x004b78cc :        85f6
             jne Label4b78f3                                                 ;0x004b78ce :        7523
             pushd 0FFFFFFFFh                                                ;0x004b78d0 :        6aff
             mov edx , 01800h                                                ;0x004b78d2 :        ba00180000
             lea ecx ,  dword ptr [ ebp + 0FFFFFCE4h ]                       ;0x004b78d7 :        8d8de4fcffff
             call Fun421184                                                  ;0x004b78dd :        e8a298f6ff
             lea edx ,  dword ptr [ ebp + 0FFFFFCE4h ]                       ;0x004b78e2 :        8d95e4fcffff
             lea eax ,  dword ptr [ ebp + 0FFFFFF38h ]                       ;0x004b78e8 :        8d8538ffffff
             call Fun4b6623                                                  ;0x004b78ee :        e830edffff

     Label4b78f3 ::
             lea ecx ,  dword ptr [ ebp + 0FFFFFCFCh ]                       ;0x004b78f3 :        8d8dfcfcffff
             push ecx                                                        ;0x004b78f9 :        51
             lea eax ,  dword ptr [ ebp + 0FFFFFC90h ]                       ;0x004b78fa :        8d8590fcffff
             call Fun42d200                                                  ;0x004b7900 :        e8fb58f7ff
             cmp  byte ptr [ ebp + 0FFFFFF38h ] , 043h                       ;0x004b7905 :        80bd38ffffff43
             jne Label4b8529                                                 ;0x004b790c :        0f85170c0000
             test esi , esi                                                  ;0x004b7912 :        85f6
             jne Label4b8529                                                 ;0x004b7914 :        0f850f0c0000
             mov  edx , dword ptr [ ebp + 0FFFFFD04h ]                       ;0x004b791a :        8b9504fdffff
             mov  eax , dword ptr [ ebp + 0FFFFFF40h ]                       ;0x004b7920 :        8b8540ffffff
             mov  ecx , dword ptr [ ebp + 124 ]                              ;0x004b7926 :        8b4d7c
             add eax , edx                                                   ;0x004b7929 :        03c2
             cmp eax , ecx                                                   ;0x004b792b :        3bc1
             jnb Label5b19ad                                                 ;0x004b792d :        0f837aa00f00
             mov  esi , dword ptr [ ebp + 120 ]                              ;0x004b7933 :        8b7578
             mov  eax , dword ptr [ ebp + 0FFFFFD08h ]                       ;0x004b7936 :        8b8508fdffff
             lea ecx ,  dword ptr [ ebp + 0FFFFFF38h ]                       ;0x004b793c :        8d8d38ffffff
             push ecx                                                        ;0x004b7942 :        51
             mov  ecx , dword ptr [ ebp + 0FFFFFD0Ch ]                       ;0x004b7943 :        8b8d0cfdffff
             lea edx ,  dword ptr [ ebp + 0FFFFFD04h ]                       ;0x004b7949 :        8d9504fdffff
             push edx                                                        ;0x004b794f :        52
             mov edx , esi                                                   ;0x004b7950 :        8bd6
             call Fun508a2e                                                  ;0x004b7952 :        e8d7100500
             mov  dword ptr [ ebp + 0FFFFFD0Ch ] , esi                       ;0x004b7957 :        89b50cfdffff
             jmp Label5047a4                                                 ;0x004b795d :        e942ce0400

     Label508b60 ::
             mov  edx , dword ptr [ Data9388e4 ]                             ;0x00508b60 :        8b15e4889300
             lea ecx ,  dword ptr [ eax + 4 * eax ]                          ;0x00508b66 :        8d0c80
             movzx ecx ,word ptr [ edx + 4 * ecx + 14 ]                      ;0x00508b69 :        0fb74c8a0e
             pushd 00h                                                       ;0x00508b6e :        6a00
             dec ecx                                                         ;0x00508b70 :        49
             call Fun53c57a                                                  ;0x00508b71 :        e8043a0300
             cmp eax , 0FFFFFFFFh                                            ;0x00508b76 :        83f8ff
             je Label50479e                                                  ;0x00508b79 :        0f841fbcffff
             pushd 03h                                                       ;0x00508b7f :        6a03
             lea ecx ,  dword ptr [ ebp + 0FFFFFF38h ]                       ;0x00508b81 :        8d8d38ffffff
             push ecx                                                        ;0x00508b87 :        51
             inc eax                                                         ;0x00508b88 :        40
             pushd 00h                                                       ;0x00508b89 :        6a00
             call Fun52a40c                                                  ;0x00508b8b :        e87c180200
             mov  al , byte ptr [ ebp + 0FFFFFF38h ]                         ;0x00508b90 :        8a8538ffffff
             cmp al , 043h                                                   ;0x00508b96 :        3c43
             jne Label5b1979                                                 ;0x00508b98 :        0f85db8d0a00

     Label508b9e ::
             mov  eax , dword ptr [ ebp + 0FFFFFD04h ]                       ;0x00508b9e :        8b8504fdffff
             mov  edx , dword ptr [ ebp + 0FFFFFF40h ]                       ;0x00508ba4 :        8b9540ffffff
             add edx , eax                                                   ;0x00508baa :        03d0
             cmp  edx , dword ptr [ ebp + 124 ]                              ;0x00508bac :        3b557c
             jnb Label5b19ad                                                 ;0x00508baf :        0f83f88d0a00
             mov  esi , dword ptr [ ebp + 120 ]                              ;0x00508bb5 :        8b7578
             lea ecx ,  dword ptr [ ebp + 0FFFFFF38h ]                       ;0x00508bb8 :        8d8d38ffffff
             push ecx                                                        ;0x00508bbe :        51
             mov  ecx , dword ptr [ ebp + 0FFFFFD0Ch ]                       ;0x00508bbf :        8b8d0cfdffff
             lea edx ,  dword ptr [ ebp + 0FFFFFD04h ]                       ;0x00508bc5 :        8d9504fdffff
             push edx                                                        ;0x00508bcb :        52
             mov eax , edi                                                   ;0x00508bcc :        8bc7
             mov edx , esi                                                   ;0x00508bce :        8bd6
             call Fun508a2e                                                  ;0x00508bd0 :        e859feffff
             dec esi                                                         ;0x00508bd5 :        4e
             mov  dword ptr [ ebp + 0FFFFFD0Ch ] , esi                       ;0x00508bd6 :        89b50cfdffff
             jmp Label50479e                                                 ;0x00508bdc :        e9bdbbffff


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_vfp9fix241.asp
     http://www.baiyujia.com/vfpdocuments/f_vfp9fix2.asp
     http://www.baiyujia.com/vfpdocuments/f_vfp9fix157.asp
     http://www.baiyujia.com/vfpdocuments/f_vfp9fix158.asp

     2, foxite.com:
     https://www.foxite.com/archives/vfp-90-fix-macro-substitution-0000250329.htm


6. OTHER:

     For reference only, there is no guarantees.

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