Skip to content

Commit 13d198e

Browse files
authored
Merge pull request #163 from jayrm/select-case-const
Select case as const, check jump table size Add checks to ensure that while parsing the select case as const structure, that no case statement is out of range + or - 8192 from the first case statement range value. And that overall range is maximum of 8192 upon reaching the end select statement.
2 parents ae68913 + b85a780 commit 13d198e

File tree

4 files changed

+42
-2
lines changed

4 files changed

+42
-2
lines changed

changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ Version 1.07.0
4949
- sf.net #893: 'Suffixes are only valid in -lang' error message showing incorrect -lang options allowed
5050
- fbc uses '-march=armv8-a' instead of invalid option '-march=aarch64' when passing options to gcc/LLVM (czsgaba)
5151
- rtlib: sys/io.h incorrectly included on systems that do not provide it. It is used only for x86, x86_64 and is unnecessary for all other linux targets (armhf ,arm64, mips ....)
52+
- SELECT CASE AS CONST checks for ranges that would produce unreasonably large jump tables (greater than 8192 entries)
5253

5354

5455
Version 1.06.0

src/compiler/parser-compound-select-const.bas

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,17 @@ sub cSelConstStmtNext( byval stk as FB_CMPSTMTSTK ptr )
223223

224224
'' first case?
225225
if( swtbase = ctx.base ) then
226+
'' we initially set the bias to the first value minus
227+
'' FB_MAXJUMPTBSLOTS. This allows us to compare range values
228+
'' (fromvalue <= tovalue ) and check if ranges are too
229+
'' large. Later, in cSelConstStmtEnd() we will adjust the
230+
'' bias to the lowest valid range value seen.
231+
232+
'' In terms of values used by the user:
233+
'' minimum := bias
234+
'' initial := bias + FB_MAXJUMPTBSLOTS
235+
'' maximum := bias + FB_MAXJUMPTBSLOTS*2
236+
226237
stk->select.const_.bias = value - FB_MAXJUMPTBSLOTS
227238
end if
228239

@@ -253,10 +264,17 @@ sub cSelConstStmtNext( byval stk as FB_CMPSTMTSTK ptr )
253264
continue do
254265
end if
255266

256-
assert( value <= (FB_MAXJUMPTBSLOTS*2) )
257-
assert( tovalue <= (FB_MAXJUMPTBSLOTS*2) )
258267
assert( tovalue >= value )
259268

269+
'' check if emitted jump table would be too large. Even without this check,
270+
'' emitter can still build a valid jump table, as it will fill in gaps
271+
'' between ranges, however we limit the size here, as it might end up
272+
'' unreasonably large.
273+
if( (value >= FB_MAXJUMPTBSLOTS*2) or (tovalue >= FB_MAXJUMPTBSLOTS*2) ) then
274+
errReport( FB_ERRMSG_RANGETOOLARGE )
275+
continue do
276+
end if
277+
260278
'' Add Case values in range
261279
do
262280
if( hSelConstAddCase( swtbase, value, label ) = FALSE ) then
@@ -323,6 +341,13 @@ sub cSelConstStmtEnd( byval stk as FB_CMPSTMTSTK ptr )
323341
stk->select.const_.bias += adjust_bias
324342
end if
325343

344+
'' Jump table too large? We haven't overflowed any internal structures
345+
'' and the emitter will produce valid code, but to be consistent with
346+
'' limits and documentation, report an error.
347+
if( span >= FB_MAXJUMPTBSLOTS ) then
348+
errReport( FB_ERRMSG_TOOMANYLABELS )
349+
end if
350+
326351
astAdd( astBuildJMPTB( stk->select.sym, _
327352
@ctx.casevalues(stk->select.const_.base), _
328353
@ctx.caselabels(stk->select.const_.base), _
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
' TEST_MODE : COMPILE_ONLY_FAIL
2+
3+
dim x as integer
4+
select case as const x
5+
case 1 to 8193
6+
end select
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
' TEST_MODE : COMPILE_ONLY_FAIL
2+
3+
dim x as integer
4+
select case as const x
5+
case 8192
6+
case 8193
7+
case 1
8+
end select

0 commit comments

Comments
 (0)