prawn icon indicating copy to clipboard operation
prawn copied to clipboard

Link URL escaping breaks escaped URLs

Open peret opened this issue 5 years ago • 2 comments

I'm trying to generate a PDF containing a signed link. The signature strings contains characters that need to be URL encoded for use in the query parameters, e.g. "wJ7OAi7u3WSJtzEq0b+xaoEG9yY=". So my entire (encoded) link should be something like: https://www.google.com?signature=wJ7OAi7u3WSJtzEq0b%2BxaoEG9yY%3D (non-sense link of course, just for illustration purposes).

Now, if I render this link using text with inline_format the resulting link will have the percent-characters in the already encoded string encoded again, resulting in this invalid link: https://www.google.com?signature=wJ7OAi7u3WSJtzEq0b%252BxaoEG9yY%253D

However, if I pass the un-encoded URL, i.e. https://www.google.com?signature=wJ7OAi7u3WSJtzEq0b+xaoEG9yY=, no URL-escaping is happening at all, which also gives me a broken link, because the + is interpreted as a space.

Here's some sample code to reproduce the behaviour:

require 'cgi'
require 'prawn'

Prawn::Document.generate("url_escaped.pdf") do
  signature = CGI.escape("wJ7OAi7u3WSJtzEq0b+xaoEG9yY=")
  text("<u><color rgb=\"#78c8fa\">\
            <link href=\"https://www.google.com?signature=#{signature}\">Link</link>\
          </color></u>", inline_format: true)
end

Prawn::Document.generate("url_unescaped.pdf") do
  signature = "wJ7OAi7u3WSJtzEq0b+xaoEG9yY="
  text("<u><color rgb=\"#78c8fa\">\
            <link href=\"https://www.google.com?signature=#{signature}\">Link</link>\
          </color></u>", inline_format: true)
end

Why is the %-character seemingly escaped by prawn, but nothing else? Is this a legit bug or am I not using this method correctly?

peret avatar Dec 06 '19 14:12 peret

@peret Hi did you ever discover the issue?

stellard avatar Apr 14 '21 09:04 stellard

@stellard As far as I can determine from the code, Prawn does not do anything with the value of the "link" attribute with respect to escaping.

Looking at the generated PDF object for url_escaped.pdf results in:

<< /Border [0 0 0]
/A << /Type /Action
/S /URI
/URI (https://www.google.com?signature=wJ7OAi7u3WSJtzEq0b%2BxaoEG9yY%3D)
>>

So the escaped URL gets inserted. And when I open the PDF in Evince and click on the link I get directed to https://www.google.com/?signature=wJ7OAi7u3WSJtzEq0b%2BxaoEG9yY%3D.

Do you have a current example code that fails?

gettalong avatar Apr 14 '21 19:04 gettalong