From 4366a9382358da4f4be4a6e1939be2ded70947ca Mon Sep 17 00:00:00 2001 From: Daniel Oliveira <114301190+Sr0liveira02@users.noreply.github.com> Date: Tue, 21 May 2024 05:08:55 +0100 Subject: [PATCH] Fix Date parsing crash when parsing a negative year (#53981) Fixes #50328. Originally checked on version 1.10.0 but still relevant in the current version in master Bug: In method Date(str), when given a negative year as an argument (ex: "-2000"), it would output an error while in Date(int) once given a negative year (ex: "-2000") it would work as intended returning "-2000-01-01". Fix: In function tryparsenext_base10 the character '-' wasn't being accounted so i check if it existed in the first iteration of the string and if yes I would multiply the output * -1. Test: Added some tests that verify this specific Fix. --------- Co-authored-by: Jameson Nash Co-authored-by: Viral B. Shah --- stdlib/Dates/src/parse.jl | 9 ++++++++- stdlib/Dates/test/io.jl | 5 +++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/stdlib/Dates/src/parse.jl b/stdlib/Dates/src/parse.jl index 49c0234c7c9fa..b89401f086c38 100644 --- a/stdlib/Dates/src/parse.jl +++ b/stdlib/Dates/src/parse.jl @@ -161,6 +161,13 @@ end min_pos = min_width <= 0 ? i : i + min_width - 1 max_pos = max_width <= 0 ? len : min(i + max_width - 1, len) d::Int64 = 0 + c, neg = iterate(str, i)::Tuple{Char, Int} + if c == '-' + i = neg + neg = -1 + else + neg = 1 + end @inbounds while i <= max_pos c, ii = iterate(str, i)::Tuple{Char, Int} if '0' <= c <= '9' @@ -173,7 +180,7 @@ end if i <= min_pos return nothing else - return d, i + return d * neg, i end end diff --git a/stdlib/Dates/test/io.jl b/stdlib/Dates/test/io.jl index ee102288acd3e..1a92ccac79c89 100644 --- a/stdlib/Dates/test/io.jl +++ b/stdlib/Dates/test/io.jl @@ -621,4 +621,9 @@ end end end +@testset "Issue #50328: parsing negative years" begin + @test Date("-2013-10-10") == Date(-2013, 10, 10) + @test Date("-2013") == Date(-2013, 01, 01) +end + end