Skip to content

Commit

Permalink
fbc: sf.net # 994: Bad handling of macro argument evaluation
Browse files Browse the repository at this point in the history
- reset file pointers after evaluating arguments in __fb_query_symbol__, __fb_eval__, __fb_arg_extract__, __fb_iif__
- Some fbc built in macros like create a separate lexer context to evaluate arguments at compile time.
- When the lexer context is no longer needed, the previous lexer context needs to be restored.
- fbc was failing to correctly restore file pointers after freeing the context
- this would result in the file pointers being not synchronized with the memory buffers and memory pointers
- this would happen when the macros and arguments to be expanded sit on either side of an 8Kb boundary
- 8KB is the hard coded buffer size for reading in chunks of source code
  • Loading branch information
jayrm committed Nov 19, 2023
1 parent c9a282e commit 08fff05
Show file tree
Hide file tree
Showing 11 changed files with 145 additions and 3 deletions.
1 change: 1 addition & 0 deletions changelog.txt
Expand Up @@ -23,6 +23,7 @@ Version 1.10.1
- rtlib: emscripten: CURDIR and EXEPATH always returned ""
- emscripten/fbc: -sASYNCIFY wasn't passed to emcc at link-time as needed by recent Emscripten
- sf.net #993: ignore (parse) single line comments for macros invoked with optional parentheses instead of passing as an argument to macro
- sf.net #994: Bad handling of macro argument evaluation - reset file pointers after evaluating arguments in __fb_query_symbol__, __fb_eval__, __fb_arg_extract__, __fb_iif__


Version 1.10.0
Expand Down
6 changes: 4 additions & 2 deletions src/compiler/lex-utf.bas
Expand Up @@ -300,7 +300,8 @@ end function
private function hUTF16LEToUTF16LE( ) as integer static

if( get( #env.inf.num, , lex.ctx->buffw ) = 0 ) then
function = cunsg(seek( env.inf.num ) - lex.ctx->filepos) \ len( ushort )
lex.ctx->physfilepos = seek( env.inf.num )
function = cunsg(lex.ctx->physfilepos - lex.ctx->filepos) \ len( ushort )
else
function = 0
end if
Expand Down Expand Up @@ -600,7 +601,8 @@ end function
private function hUTF32LEToUTF32LE( ) as integer static

if( get( #env.inf.num, , lex.ctx->buffw ) = 0 ) then
function = cunsg(seek( env.inf.num ) - lex.ctx->filepos) \ sizeof( ulong )
lex.ctx->physfilepos = seek( env.inf.num )
function = cunsg(lex.ctx->physfilepos - lex.ctx->filepos) \ sizeof( ulong )
else
function = 0
end if
Expand Down
12 changes: 11 additions & 1 deletion src/compiler/lex.bas
Expand Up @@ -60,6 +60,13 @@ sub lexPopCtx( )
DWstrAllocate( lex.ctx->deftextw, 0 )
end if

'' restore file pointer position if current context is different from previous
if( (lex.ctx-1)->physfilepos > 0 ) then
if( (lex.ctx-1)->physfilepos <> lex.ctx->physfilepos ) then
seek #env.inf.num, lex.ctx->physfilepos
end if
end if

lex.ctx -= 1

end sub
Expand Down Expand Up @@ -133,9 +140,11 @@ sub lexInit _
if( is_fb_eval ) then
lex.ctx->filepos = (lex.ctx-1)->filepos
lex.ctx->lastfilepos = (lex.ctx-1)->lastfilepos
lex.ctx->physfilepos = (lex.ctx-1)->physfilepos
else
lex.ctx->filepos = 0
lex.ctx->lastfilepos = 0
lex.ctx->physfilepos = 0
end if

'' only if it's not on an inc file
Expand Down Expand Up @@ -227,7 +236,8 @@ private function hReadChar _
select case as const env.inf.format
case FBFILE_FORMAT_ASCII
if( get( #env.inf.num, , lex.ctx->buff ) = 0 ) then
lex.ctx->bufflen = seek( env.inf.num ) - lex.ctx->filepos
lex.ctx->physfilepos = seek( env.inf.num )
lex.ctx->bufflen = lex.ctx->physfilepos - lex.ctx->filepos
lex.ctx->buffptr = @lex.ctx->buff
end if

Expand Down
1 change: 1 addition & 0 deletions src/compiler/lex.bi
Expand Up @@ -129,6 +129,7 @@ type LEX_TKCTX

filepos as integer
lastfilepos as integer
physfilepos as integer

currline as DZSTRING '' current line in text form

Expand Down
17 changes: 17 additions & 0 deletions src/compiler/symb-define.bas
Expand Up @@ -1041,6 +1041,10 @@ private function hDefQuerySymZ_cb( byval argtb as LEXPP_ARGTB ptr, byval errnum
lex.ctx->defptr = lex.ctx->deftext.data
lex.ctx->deflen += len( *sexpr )

DZstrConcatAssign( lex.ctx->deftext, LFCHAR )
lex.ctx->defptr = lex.ctx->deftext.data
lex.ctx->deflen += len( LFCHAR )

'' if filtervalue is zero then set the default methods to use for
'' look-up depending on what we are looking for
if( filtervalue = 0 ) then
Expand Down Expand Up @@ -1073,6 +1077,9 @@ private function hDefQuerySymZ_cb( byval argtb as LEXPP_ARGTB ptr, byval errnum
FB_TKCLASS_QUIRKWD, FB_TKCLASS_OPERATOR

sym = cIdentifierOrUDTMember( )
if( sym = NULL ) then
retry = TRUE
end if
end select

'' for some symbols, we maybe want to reset and try a TYPEOF below
Expand Down Expand Up @@ -1129,6 +1136,10 @@ private function hDefQuerySymZ_cb( byval argtb as LEXPP_ARGTB ptr, byval errnum
DZstrAssign( lex.ctx->deftext, *sexpr )
lex.ctx->defptr = lex.ctx->deftext.data
lex.ctx->deflen += len( *sexpr )

DZstrConcatAssign( lex.ctx->deftext, LFCHAR )
lex.ctx->defptr = lex.ctx->deftext.data
lex.ctx->deflen += len( LFCHAR )
end if

end if
Expand Down Expand Up @@ -1183,6 +1194,12 @@ private function hDefQuerySymZ_cb( byval argtb as LEXPP_ARGTB ptr, byval errnum
res = str( -1 )
end select

if( *errnum <> FB_ERRMSG_OK ) then
errReport( *errnum )
'' error recovery: skip until next line (in the buffer)
hSkipUntil( FB_TK_EOL, TRUE )
end if

lex.ctx->reclevel -= 1

lexPopCtx()
Expand Down
106 changes: 106 additions & 0 deletions tests/syntax/fb_query_symbol-error-1.bas
@@ -0,0 +1,106 @@
const fbc_FB_QUERY_SYMBOL_symbclass = 0
#macro SomeLongishExpressionToHitTheBadSpot(longish_argument_name)
longish_argument_name
#endmacro
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' Padding to fill the source file to 8Kb---------------------------------------
'' That should be close enough
print __FB_QUERY_SYMBOL__( _
SomeLongishExpressionToHitTheBadSpot( fbc_FB_QUERY_SYMBOL_symbclass ), _
SomeUndefinedSymbol )
print "This is the last lines of the file - This is the last lines of the file"
print "This is the last lines of the file - This is the last lines of the file"
print "This is the last lines of the file - This is the last lines of the file"
print "This is the last lines of the file - This is the last lines of the file"
print "This is the last lines of the file - This is the last lines of the file"
1 change: 1 addition & 0 deletions tests/syntax/r/dos/fb_query_symbol-error-1.txt
@@ -0,0 +1 @@
fb_query_symbol-error-1.bas(101) error 42: Variable not declared, SomeUndefinedSymbol in 'SomeUndefinedSymbol )'
1 change: 1 addition & 0 deletions tests/syntax/r/linux-x86/fb_query_symbol-error-1.txt
@@ -0,0 +1 @@
fb_query_symbol-error-1.bas(101) error 42: Variable not declared, SomeUndefinedSymbol in 'SomeUndefinedSymbol )'
1 change: 1 addition & 0 deletions tests/syntax/r/linux-x86_64/fb_query_symbol-error-1.txt
@@ -0,0 +1 @@
fb_query_symbol-error-1.bas(101) error 42: Variable not declared, SomeUndefinedSymbol in 'SomeUndefinedSymbol )'
1 change: 1 addition & 0 deletions tests/syntax/r/win32/fb_query_symbol-error-1.txt
@@ -0,0 +1 @@
fb_query_symbol-error-1.bas(101) error 42: Variable not declared, SomeUndefinedSymbol in 'SomeUndefinedSymbol )'
1 change: 1 addition & 0 deletions tests/syntax/r/win64/fb_query_symbol-error-1.txt
@@ -0,0 +1 @@
fb_query_symbol-error-1.bas(101) error 42: Variable not declared, SomeUndefinedSymbol in 'SomeUndefinedSymbol )'

0 comments on commit 08fff05

Please sign in to comment.