Skip to content

Commit c8456af

Browse files
committed
fixed a bug where an invalid expression could cause a crash
added more unit tests in the CI for error conditions
1 parent 49a617e commit c8456af

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

src/function_parser.f90

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1405,6 +1405,8 @@ function mathitem_index (me, f, var) result (n)
14051405
integer :: n !! byte value of math item
14061406

14071407
n = 0
1408+
if (len(f)==0) return ! error condition
1409+
14081410
if (scan(f(1:1),'0123456789.') > 0) then ! check for begin of a number
14091411
me%immedsize = me%immedsize + 1
14101412
if (allocated(me%immed)) then

test/tests.f90

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ program tests
1616
call fptest4()
1717
call fptest5()
1818
call fptest6()
19+
call error_tests()
1920

2021
contains
2122
!*******************************************************************************
@@ -302,6 +303,81 @@ subroutine fptest6()
302303
end subroutine fptest6
303304
!*******************************************************************************
304305

306+
!*******************************************************************************
307+
!>
308+
! Test some of the error cases.
309+
310+
subroutine error_tests()
311+
312+
implicit none
313+
314+
integer, parameter :: nvar = 3
315+
character (len=*), dimension(nvar), parameter :: var = [ 'x', &
316+
'a', &
317+
'b' ]
318+
real(wp), dimension(nvar), parameter :: val = [ 2.0_wp, 3.0_wp, 4.0_wp ]
319+
type(fparser_array) :: parser
320+
321+
write(*,*) ''
322+
write(*,*) ' Test 7 - Test error conditions'
323+
write(*,*) ''
324+
325+
call parse_error(parser,'st(-x)',var,val)
326+
call parse_error(parser,'x * 452d3234.2323',var,val)
327+
call parse_error(parser,'x * (123',var,val)
328+
call parse_error(parser,'x +-* y',var,val)
329+
call parse_error(parser,'x + sin',var,val)
330+
call parse_error(parser,'x + ()',var,val)
331+
call parse_error(parser,'x +',var,val)
332+
333+
call eval_error(parser,'sqrt(-x)',var,val)
334+
call eval_error(parser,'acos(10.0)',var,val)
335+
call eval_error(parser,'asin(10.0)',var,val)
336+
call eval_error(parser,'log(-x)',var,val)
337+
call eval_error(parser,'1/0',var,val)
338+
339+
end subroutine error_tests
340+
!*******************************************************************************
341+
342+
subroutine parse_error(parser,str,var,val)
343+
type(fparser_array),intent(inout) :: parser
344+
character(len=*),intent(in) :: str !! expression with a parsing error
345+
real(wp),dimension(1) :: res
346+
character(len=*),dimension(:),intent(in) :: var
347+
real(wp),dimension(:),intent(in) :: val
348+
call parser%parse([str], var, .false.) ! parse and bytecompile function string
349+
if (parser%error()) then
350+
call parser%print_errors(output_unit)
351+
write(*,*) 'PASSED : parsing error'
352+
else
353+
error stop 'FAILED : there should have been a parsing error'
354+
end if
355+
call parser%clear_errors()
356+
call parser%destroy()
357+
end subroutine parse_error
358+
359+
subroutine eval_error(parser,str,var,val)
360+
type(fparser_array),intent(inout) :: parser
361+
character(len=*),intent(in) :: str !! expression with a parsing error
362+
real(wp),dimension(1) :: res
363+
character(len=*),dimension(:),intent(in) :: var
364+
real(wp),dimension(:),intent(in) :: val
365+
call parser%parse([str], var, .false.) ! parse and bytecompile function string
366+
if (parser%error()) then
367+
call parser%print_errors(output_unit)
368+
error stop
369+
end if
370+
call parser%evaluate(val,res) ! interprete bytecode representation of function
371+
if (parser%error()) then
372+
call parser%print_errors(output_unit)
373+
write(*,*) 'PASSED : evaluation errors detected'
374+
else
375+
error stop 'FAILED : there should have been evaluation errors'
376+
end if
377+
call parser%clear_errors()
378+
call parser%destroy()
379+
end subroutine eval_error
380+
305381
!*******************************************************************************
306382
!>
307383
! Compare the results from the parser to the actualy expression

0 commit comments

Comments
 (0)