diff --git a/CHANGES.md b/CHANGES.md index af70b0c0..931d9244 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,6 +8,10 @@ ### Fixed +- Fix the error location reported in the exception. Regression in 2.1.1 + (reported by @johnridesabike, regression test by @ElectreAAS, fix by + @Leonidas-from-XIV, #171, #172) + ### Removed ### Security diff --git a/lib/lexer_utils.mll b/lib/lexer_utils.mll index 622d7022..ad3dfe92 100644 --- a/lib/lexer_utils.mll +++ b/lib/lexer_utils.mll @@ -7,3 +7,10 @@ rule read_junk buf n = parse read_junk buf (n - 1) lexbuf end } + +{ +let read_junk_without_positions buf n (lexbuf : Lexing.lexbuf) = + let junk_start_pos = lexbuf.lex_start_pos in + read_junk buf n lexbuf; + lexbuf.lex_start_pos <- junk_start_pos + 1 +} diff --git a/lib/read.mll b/lib/read.mll index 7f2d54e9..6ea49b40 100644 --- a/lib/read.mll +++ b/lib/read.mll @@ -71,8 +71,9 @@ let long_error descr v lexbuf = let junk = Lexing.lexeme lexbuf in - let buf = Buffer.create 32 in - let () = Lexer_utils.read_junk buf 32 lexbuf in + let buf_size = 32 in + let buf = Buffer.create buf_size in + let () = Lexer_utils.read_junk_without_positions buf buf_size lexbuf in let extra_junk = Buffer.contents buf in custom_error (sprintf "%s '%s%s'" descr junk extra_junk) diff --git a/test/test_read.ml b/test/test_read.ml index 76dc1a42..5349c5f9 100644 --- a/test/test_read.ml +++ b/test/test_read.ml @@ -3,6 +3,11 @@ let from_string () = __LOC__ Fixtures.json_value (Yojson.Safe.from_string Fixtures.json_string) +let from_string_fail () = + Alcotest.check_raises "Location of parsing failure is correct" + (Yojson.Json_error "Line 1, bytes 0-5:\nInvalid token 'hello'") (fun () -> + Yojson.Safe.from_string "hello" |> ignore) + let from_file () = let input_file = Filename.temp_file "test_yojson_from_file" ".json" in let oc = open_out input_file in @@ -51,6 +56,7 @@ let map_ident_and_string () = let single_json = [ ("from_string", `Quick, from_string); + ("from_string_fail", `Quick, from_string_fail); ("from_file", `Quick, from_file); ("unquoted_from_string", `Quick, unquoted_from_string); ("map_ident/map_string", `Quick, map_ident_and_string);