2017-03-11 03:28:18 -07:00
local helpers = require ( ' test.unit.helpers ' ) ( after_each )
2017-03-04 18:02:45 -07:00
local itp = helpers.gen_itp ( it )
2016-03-06 21:10:38 -07:00
local cimport = helpers.cimport
local eq = helpers.eq
2016-03-06 22:54:39 -07:00
local neq = helpers.neq
local ffi = helpers.ffi
2016-03-06 21:10:38 -07:00
2016-07-26 13:16:23 -07:00
local decode = cimport ( ' ./src/nvim/eval/decode.h ' , ' ./src/nvim/eval/typval.h ' ,
2016-03-06 22:54:39 -07:00
' ./src/nvim/globals.h ' , ' ./src/nvim/memory.h ' ,
' ./src/nvim/message.h ' )
2016-03-06 21:10:38 -07:00
describe ( ' json_decode_string() ' , function ( )
2016-03-06 21:50:17 -07:00
local char = function ( c )
return ffi.gc ( decode.xmemdup ( c , 1 ) , decode.xfree )
end
2017-03-04 18:02:45 -07:00
itp ( ' does not overflow when running with `n…`, `t…`, `f…` ' , function ( )
2016-03-06 21:50:17 -07:00
local rettv = ffi.new ( ' typval_T ' , { v_type = decode.VAR_UNKNOWN } )
2016-03-06 21:10:38 -07:00
decode.emsg_silent = 1
2016-11-16 16:33:45 -07:00
-- This will not crash, but if `len` argument will be ignored it will parse
2016-03-06 21:10:38 -07:00
-- `null` as `null` and if not it will parse `null` as `n`.
eq ( 0 , decode.json_decode_string ( ' null ' , 1 , rettv ) )
eq ( decode.VAR_UNKNOWN , rettv.v_type )
eq ( 0 , decode.json_decode_string ( ' true ' , 1 , rettv ) )
eq ( decode.VAR_UNKNOWN , rettv.v_type )
eq ( 0 , decode.json_decode_string ( ' false ' , 1 , rettv ) )
eq ( decode.VAR_UNKNOWN , rettv.v_type )
eq ( 0 , decode.json_decode_string ( ' null ' , 2 , rettv ) )
eq ( decode.VAR_UNKNOWN , rettv.v_type )
eq ( 0 , decode.json_decode_string ( ' true ' , 2 , rettv ) )
eq ( decode.VAR_UNKNOWN , rettv.v_type )
eq ( 0 , decode.json_decode_string ( ' false ' , 2 , rettv ) )
eq ( decode.VAR_UNKNOWN , rettv.v_type )
eq ( 0 , decode.json_decode_string ( ' null ' , 3 , rettv ) )
eq ( decode.VAR_UNKNOWN , rettv.v_type )
eq ( 0 , decode.json_decode_string ( ' true ' , 3 , rettv ) )
eq ( decode.VAR_UNKNOWN , rettv.v_type )
eq ( 0 , decode.json_decode_string ( ' false ' , 3 , rettv ) )
eq ( decode.VAR_UNKNOWN , rettv.v_type )
eq ( 0 , decode.json_decode_string ( ' false ' , 4 , rettv ) )
eq ( decode.VAR_UNKNOWN , rettv.v_type )
end )
2017-03-04 18:02:45 -07:00
itp ( ' does not overflow and crash when running with `n`, `t`, `f` ' , function ( )
2016-03-06 21:50:17 -07:00
local rettv = ffi.new ( ' typval_T ' , { v_type = decode.VAR_UNKNOWN } )
2016-03-06 21:10:38 -07:00
decode.emsg_silent = 1
eq ( 0 , decode.json_decode_string ( char ( ' n ' ) , 1 , rettv ) )
eq ( decode.VAR_UNKNOWN , rettv.v_type )
eq ( 0 , decode.json_decode_string ( char ( ' t ' ) , 1 , rettv ) )
eq ( decode.VAR_UNKNOWN , rettv.v_type )
eq ( 0 , decode.json_decode_string ( char ( ' f ' ) , 1 , rettv ) )
eq ( decode.VAR_UNKNOWN , rettv.v_type )
end )
2016-03-06 21:50:17 -07:00
2017-03-04 18:02:45 -07:00
itp ( ' does not overflow when running with `"…` ' , function ( )
2016-03-06 21:50:17 -07:00
local rettv = ffi.new ( ' typval_T ' , { v_type = decode.VAR_UNKNOWN } )
decode.emsg_silent = 1
eq ( 0 , decode.json_decode_string ( ' "t" ' , 2 , rettv ) )
eq ( decode.VAR_UNKNOWN , rettv.v_type )
eq ( 0 , decode.json_decode_string ( ' "" ' , 1 , rettv ) )
eq ( decode.VAR_UNKNOWN , rettv.v_type )
end )
2016-03-09 15:06:43 -07:00
local check_failure = function ( s , len , msg )
2016-03-06 22:54:39 -07:00
local rettv = ffi.new ( ' typval_T ' , { v_type = decode.VAR_UNKNOWN } )
2016-03-09 15:06:43 -07:00
eq ( 0 , decode.json_decode_string ( s , len , rettv ) )
eq ( decode.VAR_UNKNOWN , rettv.v_type )
neq ( nil , decode.last_msg_hist )
eq ( msg , ffi.string ( decode.last_msg_hist . msg ) )
end
2017-03-04 18:02:45 -07:00
itp ( ' does not overflow in error messages ' , function ( )
2017-04-08 09:06:03 -07:00
collectgarbage ( ' restart ' )
2016-03-06 22:54:39 -07:00
check_failure ( ' ]test ' , 1 , ' E474: No container to close: ] ' )
check_failure ( ' [}test ' , 2 , ' E474: Closing list with curly bracket: } ' )
check_failure ( ' {]test ' , 2 ,
' E474: Closing dictionary with square bracket: ] ' )
check_failure ( ' [1,]test ' , 4 , ' E474: Trailing comma: ] ' )
check_failure ( ' {"1":}test ' , 6 , ' E474: Expected value after colon: } ' )
check_failure ( ' {"1"}test ' , 5 , ' E474: Expected value: } ' )
check_failure ( ' ,test ' , 1 , ' E474: Comma not inside container: , ' )
check_failure ( ' [1,,1]test ' , 6 , ' E474: Duplicate comma: ,1] ' )
check_failure ( ' {"1":,}test ' , 7 , ' E474: Comma after colon: ,} ' )
check_failure ( ' {"1",}test ' , 6 , ' E474: Using comma in place of colon: ,} ' )
check_failure ( ' {,}test ' , 3 , ' E474: Leading comma: ,} ' )
check_failure ( ' [,]test ' , 3 , ' E474: Leading comma: ,] ' )
check_failure ( ' :test ' , 1 , ' E474: Colon not inside container: : ' )
check_failure ( ' [:]test ' , 3 , ' E474: Using colon not in dictionary: :] ' )
check_failure ( ' {:}test ' , 3 , ' E474: Unexpected colon: :} ' )
check_failure ( ' {"1"::1}test ' , 8 , ' E474: Duplicate colon: :1} ' )
check_failure ( ' ntest ' , 1 , ' E474: Expected null: n ' )
check_failure ( ' ttest ' , 1 , ' E474: Expected true: t ' )
check_failure ( ' ftest ' , 1 , ' E474: Expected false: f ' )
check_failure ( ' " \\ test ' , 2 , ' E474: Unfinished escape sequence: " \\ ' )
check_failure ( ' " \\ u"test ' , 4 ,
' E474: Unfinished unicode escape sequence: " \\ u" ' )
check_failure ( ' " \\ uXXXX"est ' , 8 ,
' E474: Expected four hex digits after \\ u: \\ uXXXX" ' )
check_failure ( ' " \\ ?"test ' , 4 , ' E474: Unknown escape sequence: \\ ?" ' )
check_failure (
' " \t "test ' , 3 ,
' E474: ASCII control characters cannot be present inside string: \t " ' )
check_failure ( ' " \194 "test ' , 3 , ' E474: Only UTF-8 strings allowed: \194 " ' )
2016-03-20 14:19:41 -07:00
check_failure ( ' " \252 \144 \128 \128 \128 \128 "test ' , 8 , ' E474: Only UTF-8 code points up to U+10FFFF are allowed to appear unescaped: \252 \144 \128 \128 \128 \128 " ' )
2016-03-06 22:54:39 -07:00
check_failure ( ' "test ' , 1 , ' E474: Expected string end: " ' )
check_failure ( ' -test ' , 1 , ' E474: Missing number after minus sign: - ' )
check_failure ( ' -1.test ' , 3 , ' E474: Missing number after decimal dot: -1. ' )
check_failure ( ' -1.0etest ' , 5 , ' E474: Missing exponent: -1.0e ' )
check_failure ( ' ?test ' , 1 , ' E474: Unidentified byte: ? ' )
check_failure ( ' 1?test ' , 2 , ' E474: Trailing characters: ? ' )
check_failure ( ' [1test ' , 2 , ' E474: Unexpected end of input: [1 ' )
end )
2017-03-04 18:02:45 -07:00
itp ( ' does not overflow with `-` ' , function ( )
2016-03-09 15:06:43 -07:00
check_failure ( ' -0 ' , 1 , ' E474: Missing number after minus sign: - ' )
end )
2017-03-04 18:02:45 -07:00
itp ( ' does not overflow and crash when running with `"` ' , function ( )
2016-03-06 21:50:17 -07:00
local rettv = ffi.new ( ' typval_T ' , { v_type = decode.VAR_UNKNOWN } )
2016-03-06 22:54:39 -07:00
decode.emsg_silent = 1
2016-03-06 21:50:17 -07:00
eq ( 0 , decode.json_decode_string ( char ( ' " ' ) , 1 , rettv ) )
eq ( decode.VAR_UNKNOWN , rettv.v_type )
end )
2016-03-06 21:10:38 -07:00
end )