Skip to content

Commit

Permalink
parser: Select Case As Const: Fix potential hang and overflow
Browse files Browse the repository at this point in the history
A huge range like <case 0 to 4294967295u> correctly triggers an error,
but fbc still looped through all the values during error recovery, which
makes it look like it hangs.

Furthermore, I suspect the For loop could have run into overflow and
infinite looping issues, due to the iterator being a UInteger...
  • Loading branch information
dkl committed Sep 16, 2015
1 parent bca798d commit 9e0d5c6
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 7 deletions.
1 change: 1 addition & 0 deletions changelog.txt
Expand Up @@ -119,6 +119,7 @@ Version 1.04.0
- GET# didn't work with wstrings
- Integer-only operations like AND, OR, \ and MOD converted non-integer operands to Integer, even if the other was a LongInt or UInteger. Now the conversion will use an integer type matching the integer operand (if any), to avoid truncating floating point values, and give more expected results.
- ASM backend: Cross-compiling could give different results than native compilation with regards to the choice of whether to place string literals into .data or const (e.g. .rodata) sections
- Compiling a Select Case As Const block containing a Case with a huge range of values such as <case 0 to 4294967295u> won't cause the compiler to "hang" anymore


Version 1.03.0
Expand Down
23 changes: 16 additions & 7 deletions src/compiler/parser-compound-select-const.bas
Expand Up @@ -225,7 +225,8 @@ sub cSelConstStmtNext( byval stk as FB_CMPSTMTSTK ptr )
tovalue = value
end if

for value = value to tovalue
'' Add Case values in range unless it was something invalid like "1 to 0"
while( value <= tovalue )
if( value < minval ) then
minval = value
end if
Expand All @@ -236,15 +237,23 @@ sub cSelConstStmtNext( byval stk as FB_CMPSTMTSTK ptr )
'' too big?
if( (minval > maxval) or ((maxval - minval + 1) > FB_MAXJUMPTBSLOTS) ) then
errReport( FB_ERRMSG_RANGETOOLARGE )
'' error recovery: reset values
'' error recovery: reset values and abort,
'' to avoid excessive looping in case of code like "0 to 4294967295u"
minval = stk->select.const_.minval
maxval = stk->select.const_.maxval
else
if( hSelConstAddCase( swtbase, value, label ) = FALSE ) then
errReport( FB_ERRMSG_DUPDEFINITION )
end if
exit while
end if
next

if( hSelConstAddCase( swtbase, value, label ) = FALSE ) then
errReport( FB_ERRMSG_DUPDEFINITION )
end if

'' "Early" exit check to avoid overflow problems
if( value = tovalue ) then
exit while
end if
value += 1
wend

stk->select.const_.minval = minval
stk->select.const_.maxval = maxval
Expand Down
5 changes: 5 additions & 0 deletions tests/compound/select-const-huge-range.bas
@@ -0,0 +1,5 @@
' TEST_MODE : COMPILE_ONLY_FAIL

select case as const 0
case 0 to 4294967295u
end select

0 comments on commit 9e0d5c6

Please sign in to comment.