From 6bcf925f235dd3c40871721f417068ff9af9d107 Mon Sep 17 00:00:00 2001 From: Jacob Quinn Date: Tue, 8 Sep 2020 11:25:48 -0600 Subject: [PATCH] Fix escaped '%' check when building Printf.Format Addresses https://github.com/JuliaLang/julia/pull/32859#issuecomment-688826726. The issue here was advancing the parsing position too far when an escaped `'%'` was encountered after the first format specifier. If an escaped `'%'` was then followed by another specifier, it was ignored due to being classified as an "escaped" character. --- stdlib/Printf/src/Printf.jl | 5 ++--- stdlib/Printf/test/runtests.jl | 5 +++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/stdlib/Printf/src/Printf.jl b/stdlib/Printf/src/Printf.jl index 7a1800c87051f7..f504402a266412 100644 --- a/stdlib/Printf/src/Printf.jl +++ b/stdlib/Printf/src/Printf.jl @@ -165,17 +165,16 @@ function Format(f::AbstractString) end push!(fmts, Spec{type}(leftalign, plus, space, zero, hash, width, precision)) start = pos - prevperc = false while pos <= len b = bytes[pos] pos += 1 if b == UInt8('%') pos > len && throw(ArgumentError("invalid format string: '$f'")) if bytes[pos] == UInt8('%') - pos += 1 - pos > len && break + # escaped '%' b = bytes[pos] pos += 1 + # break else break end diff --git a/stdlib/Printf/test/runtests.jl b/stdlib/Printf/test/runtests.jl index 4ff60c8aab085f..1a47a82d78fa86 100644 --- a/stdlib/Printf/test/runtests.jl +++ b/stdlib/Printf/test/runtests.jl @@ -414,6 +414,11 @@ end @test Printf.@sprintf("%f", 1) == "1.000000" @test Printf.@sprintf("%e", 1) == "1.000000e+00" @test Printf.@sprintf("%g", 1) == "1" + + # escaped '%' + @test_throws ArgumentError @sprintf("%s%%%s", "a") + @test @sprintf("%s%%%s", "a", "b") == "a%%b" + end @testset "integers" begin