------------------------------------------------------------------ [BUG/PRB.] VFP 9.0 FIX - INVALID RELATIONALEXPR EXPRESSION January 2024 ------------------------------------------------------------------ CCB 1. BUG: In vfp9 (and vfp6, vfp7, vfp8), if the RelationalExpr expression includes the EVALUATE() or TYPE() functions, vfp will crash. 1, If the RelationalExpr expression includes the macro substitution, vfp will cause the error "Relational expression is not valid (Error 1555)". *PROC testrelationalexpr_macro SET STEP OFF SET ECHO OFF SET DEBUG OFF SET ESCAPE OFF SET TALK OFF SET SAFETY OFF _SCREEN.VISIBLE=.T. _SCREEN.WINDOWSTATE=2 SET EXCLUSIVE OFF SET MULTILOCK ON SET COLLATE TO "MACHINE" CLOSE DATABASES ALL CLOSE TABLES ALL PUBLIC x1 x1="CHR(65)" DO FORM testrelationalexpr_macro.scx CLOSE DATABASES ALL CLOSE TABLES ALL RETURN * END OF PROC TESTRELATIONALEXPR_MACRO. In the testrelationalexpr_macro.scx: relation1.RelationalExpr = "fld1+LEFT(&x1,0)" 2, If the RelationalExpr expression includes the EVALUATE() or TYPE() functions, vfp will crash. *PROC testrelationalexpr_evaluate SET STEP OFF SET ECHO OFF SET DEBUG OFF SET ESCAPE OFF SET TALK OFF SET SAFETY OFF _SCREEN.VISIBLE=.T. _SCREEN.WINDOWSTATE=2 SET EXCLUSIVE OFF SET MULTILOCK ON SET COLLATE TO "MACHINE" CLOSE DATABASES ALL CLOSE TABLES ALL DO FORM testrelationalexpr_evaluate.scx CLOSE DATABASES ALL CLOSE TABLES ALL RETURN * END OF PROC TESTRELATIONALEXPR_evaluate. In the testrelationalexpr_evaluate.scx: relation1.RelationalExpr = "fld1+EVALUATE('LEFT(CHR(65),0)')" 3, If the RelationalExpr expression includes the user-defined function and the user-defined function includes EVALUATE() or TYPE() functions, vfp will crash too. *PROC testrelationalexpr_udf_evaluate SET STEP OFF SET ECHO OFF SET DEBUG OFF SET ESCAPE OFF SET TALK OFF SET SAFETY OFF _SCREEN.VISIBLE=.T. _SCREEN.WINDOWSTATE=2 SET EXCLUSIVE OFF SET MULTILOCK ON SET COLLATE TO "MACHINE" CLOSE DATABASES ALL CLOSE TABLES ALL DO FORM testrelationalexpr_udf_evaluate.scx CLOSE DATABASES ALL CLOSE TABLES ALL RETURN FUNCTION testrelationalexpr_udf_evaluate2 PRIVATE x2 x2=EVALUATE('LEFT(CHR(65),0)') RETU "" * END OF FUNCTION TESTRELATIONALEXPR_UDF_EVALUATE2. * END OF PROC TESTRELATIONALEXPR_UDF_EVALUATE. In the testrelationalexpr_udf_evaluate.scx: relation1.RelationalExpr = "fld1+testrelationalexpr_udf_evaluate2()" 4, If the RelationalExpr expression includes the user-defined function and the user-defined function does not include the EVALUATE() and TYPE() functions, vfp will run correctly. 5, If we don't set RelationalExpr expression at design-time, we can set RelationalExpr expression at run time. For example, THISFORM.DATAENVIRONMENT.ADDOBJECT("Relation1","Relation") THISFORM.DATAENVIRONMENT.relation1.PARENTALIAS = "testa" THISFORM.DATAENVIRONMENT.relation1.RELATIONALEXPR = "fld1+EVALUATE('LEFT(CHR(65),0)')" THISFORM.DATAENVIRONMENT.relation1.CHILDALIAS = "testb" THISFORM.DATAENVIRONMENT.relation1.CHILDORDER = "fld1" vfp will not crash, BUT vfp will run incorrectly: now the RELATION(1) is not equal to "fld1+EVALUATE('LEFT(CHR(65),0)')", it is equal to "LEFT(CHR(65),0)" (the parameter passed to the EVALUATE() or TYPE() functions). 6, If we don't use the relation object, we can use SET RELATION TO statement instead of the relation object, then there is no any problem. 2. CAUSE: There are some BUGs in the following code. 3. RESOLUTION: We can write some code to fix the BUG. Label722b1b :: mov ecx , dword ptr [ Data937f94 ] ;0x00722b1b : 8b0d947f9300 pushd 00h ;0x00722b21 : 6a00 lea edx , dword ptr [ esp + 02124h ] ;0x00722b23 : 8d942424210000 push edx ;0x00722b2a : 52 call Fun434500 ;0x00722b2b : e8d019d1ff test eax , eax ;0x00722b30 : 85c0 jle Label722b59 ;0x00722b32 : 7e25 pushd 00h ;0x00722b34 : 6a00 pushd 01h ;0x00722b36 : 6a01 pushd 00h ;0x00722b38 : 6a00 lea eax , dword ptr [ esp + 0212Ch ] ;0x00722b3a : 8d84242c210000 push eax ;0x00722b41 : 50 call Fun430428 ;0x00722b42 : e8e1d8d0ff test eax , eax ;0x00722b47 : 85c0 jne Label722b59 ;0x00722b49 : 750e ; ; ------------------------------------------------------- ; VFP 9.0 FIX - INVALID RELATIONALEXPR EXPRESSION ; January 2018 ; ------------------------------------------------------- ; CCB ; ; If the RelationalExpr expression includes the EVALUATE() or TYPE() functions, vfp will crash. ; ; 2018/1/23, by ccb ; mov dword ptr vfpa_relationalexpr_flag,01h mov eax,dword ptr [ Data937f94 ] cmp byte ptr [eax],0FDh je Label722b4a Label722b49 :: call Fun4360e0 cmp byte ptr [eax],0FDh jne Label722b49 Label722b4a :: sub eax,dword ptr [ Data937f94 ] inc eax mov dword ptr vfpa_relationalexpr_len,eax cmp dword ptr vfpa_relationalexpr_len,100h jae Label722b4b push ecx push esi push edi mov ecx,dword ptr vfpa_relationalexpr_len mov esi,dword ptr [ Data937f94 ] lea edi,dword ptr vfpa_relationalexpr_data cld rep movsb pop edi pop esi pop ecx Label722b4b :: mov eax , dword ptr [ Data937f94 ] ;0x00722b4b : a1947f9300 push esi ;0x00722b50 : 56 push ebx ;0x00722b51 : 53 call Fun44df4c ;0x00722b52 : e8f5b3d2ff ; ; ------------------------------------------------------- ; VFP 9.0 FIX - INVALID RELATIONALEXPR EXPRESSION ; January 2018 ; ------------------------------------------------------- ; CCB ; ; If the RelationalExpr expression includes the EVALUATE() or TYPE() functions, vfp will crash. ; ; 2018/1/23, by ccb ; mov dword ptr vfpa_relationalexpr_flag,00h jmp Label722b63 ;0x00722b57 : eb0a We can also use the EXECSCRIPT() function instead of the EVALUATE() function, and use the VARTYPE() function instead of the TYPE() function, and then vfp will run correctly. For example, RelationalExpr = "fld1+EVALUATE('LEFT(CHR(65),0)')" we can change it to: RelationalExpr = "fld1+EXECSCRIPT('RETURN '+'LEFT(CHR(65),0)')" VFP C++ Compiler frequently uses the _Evaluate() and _Execute() API functions, so if the RelationalExpr expression includes the user-defined function, recommend to set VFP C++ Compiler does not compile the user-defined function. For example, we can change it to: FUNCTION testrelationalexpr_udf_evaluate2 =[FOXRUN OFF] PRIVATE x2 x2=EVALUATE('LEFT(CHR(65),0)') RETU "" =[FOXRUN ON] * END OF FUNCTION TESTRELATIONALEXPR_UDF_EVALUATE2. 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 6. OTHER: For reference only, there is no guarantees. Any questions or suggestions, please send me an email at ccb2000@163.com. |