Skip to content

Incorrect escaping in Printf on master (@sprintf("GAP[%%]")) #37784

Closed

Description

On master, the Printf library is redisegned but the escape sequences seems not to be hanled correctly (or like in C as written in docs). Now, it is not possible to print single '%' in the middle of string.

julia> using Printf
julia> @sprintf("GAP[%%]")
ERROR: LoadError: ArgumentError: invalid format string: 'GAP[%%]', invalid type specifier: ']'
Stacktrace:
 [1] Printf.Format(f::String)
   @ Printf ~/software/julia/julia-dev/usr/share/julia/stdlib/v1.6/Printf/src/Printf.jl:157
 [2] @sprintf(__source__::LineNumberNode, __module__::Module, fmt::Any, args::Vararg{Any, N} where N)
   @ Printf ~/software/julia/julia-dev/usr/share/julia/stdlib/v1.6/Printf/src/Printf.jl:783
in expression starting at REPL[3]:1

C style

julia> @ccall printf("GAP[%%]\n"::Cstring)::Cvoid
GAP[%]

The problem of the new design comes from the commit #32859 where the structure in stdlib/Printf/src/Printf.jl

struct Format{S, T}
    str::S # original full format string as CodeUnits
    # keep track of non-format specifier strings to print
    # length(substringranges) == length(formats) + 1
    # so when printing, we start with printing
      # str[substringranges[1]], then formats[1] + args[1]
      # then str[substringranges[2]], then formats[2] + args[2]
      # and so on, then at the end, str[substringranges[end]]
    substringranges::Vector{UnitRange{Int}}
    formats::T # Tuple of Specs
end

expects that length(substringranges) == length(formats) + 1 but it is not true in general if "%%" occurs in the middle of the string format. To provide simple example, there is no format but several substrings in the following:

@assert @sprintf("a%%f%%d%%x") == "a%f%d%x"

Utilized version of master branch

julia> versioninfo()
Julia Version 1.6.0-DEV.unknown
Commit b89c4a3 (2020-09-28 08:12 UTC)
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: Intel(R) Core(TM) i5-1035G1 CPU @ 1.00GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-10.0.1 (ORCJIT, icelake-client)

Btw, all it works well on 1.5.2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Labels

bugIndicates an unexpected problem or unintended behavior

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions