mileszs / wicked_pdf

PDF generator (from HTML) plugin for Ruby on Rails
http://www.mileszs.com/wicked-pdf-plugin
MIT License
3.54k stars 645 forks source link

Apostrophes in footer break the shell command #432

Open allavena opened 9 years ago

allavena commented 9 years ago

There is an issue in passing apostrophes in the command line options on Linux. :footer => {left: "This works"} :footer => {left: "That's broken"}

RuntimeError: RuntimeError: Error: Failed to execute: ["/home/andre/.rvm/gems/ruby-2.1.2/bin/wkhtmltopdf", "-q", "--footer-left", "That's broken", "--margin-top", "20", "file:///tmp/wicked_pdf20150720-28528-wu5tk5.html", "/tmp/wicked_pdf_generated_file20150720-28528-adav70.pdf"]

    Error: PDF could not be generated!
     Command Error: sh: 1: Syntax error: Unterminated quoted string

I've tried adding a Shellwords.escape(v) in make_option, to no success.

RuntimeError: RuntimeError: Error: Failed to execute: ["/home/andre/.rvm/gems/ruby-2.1.2/bin/wkhtmltopdf", "-q", "--footer-left", "That\'s\ broken", "--margin-top", "20", "file:///tmp/wicked_pdf20150720-28768-19awro4.html", "/tmp/wicked_pdf_generated_file20150720-28768-1v26xok.pdf"] Error: PDF could not be generated! Command Error: sh: 1: Syntax error: Unterminated quoted string

Thanks André

McLibboc commented 8 years ago

+1

sampi60 commented 8 years ago

@allavena did you solve it?

allavena commented 8 years ago

May have found a work around while answering this. But there is a bug.

  1. I tried various combinations of escaping, double escaping, etc. in what I passed to whicked_pdf, never found something that worked
  2. I don't remember trying know I had tried directly from the command line to wkhtmltopdf.

I've tried now, and the below works: wkhtmltopdf "-q" "--footer-left" "That'\''s broken" "--margin-top" "20" input.html out.pdf

In other words, if you replace your single quote inside your footer by '\'' you should be good, and keep the outer in double quotes. [Don't ask me why this works, and other combinations don't work, it makes no sense to me - haven't tried to make it work from Ruby side]

As for finding the root of the bug, it looks to me the issue may be elsewhere. The chain is wicked_pdf -> run shell command calling wkhtmltopdf -> calls other stuff [don't know the details here] Shell command looks correct to me, and correct bash escaping fails.

On my machine 'calls other stuff' means calling the script below as I have I installed wkhtmltopdf via the wkhtmltopdf-binary-edge gem.

#!/usr/bin/env ruby_executable_hooks
#
# This file was generated by RubyGems.
#
# The application 'wkhtmltopdf-binary-edge' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0"

if ARGV.first
  str = ARGV.first
  str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
  if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
    version = $1
    ARGV.shift
  end
end

gem 'wkhtmltopdf-binary-edge', version
load Gem.bin_path('wkhtmltopdf-binary-edge', 'wkhtmltopdf', version)
unixmonkey commented 8 years ago

I think I've addressed this with https://github.com/mileszs/wicked_pdf/commit/024e74928dc3de49abfb6b326746829e6ae91bb2

You can check it out in your application by pointing your Gemfile to the master branch like this:

gem 'wicked_pdf', github: 'mileszs/wicked_pdf'

Please check it out and report back if you can. I'll try to cut a new gem version soon if there are no issues.

unixmonkey commented 8 years ago

I've released version 1.0.5 of the gem to deal with this. Please reopen if there are any further issues!

unixmonkey commented 8 years ago

I've reverted this change in 1.0.6 due to issues detailed in #514.

mikeLspohn commented 7 years ago

Any tips on how to solve this? I have something like

render pdf: @something.title.parameterize # value is "People's something"
    orientation: 'Portrait',
    footer: { left: "Date Revised: #{......}", center: @something.title, right: '[page]' }

@something.title in the above example contains a ' so I'm getting this same error. I've tried gsubbing out the ' with ''' as mentioned above, but that didn't seem to work for me.

unixmonkey commented 7 years ago

You can look use shellwords's shellescape to escape as seen in this commit.

You could also potentially replace single quotes with an apostrophes like this:

"foo's gold".gsub("'", "\u2019")

I'm not sure how wkhtmltopdf handles that, though.

Let me know how it goes.