pdfkit 0.8.0 → 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of pdfkit might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/CHANGELOG.md +7 -1
- data/lib/pdfkit/pdfkit.rb +23 -9
- data/lib/pdfkit/source.rb +29 -7
- data/lib/pdfkit/version.rb +1 -1
- data/spec/middleware_spec.rb +11 -11
- data/spec/pdfkit_spec.rb +87 -48
- data/spec/source_spec.rb +35 -13
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 104694d613ddecebcd67c5373e1309d9da1322d0
|
4
|
+
data.tar.gz: eed2d02a43b9fb425508a4b978a24ffc53191c99
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1463a8202d9b64d4d90a018b998015f1f6b70fa630994b27ba9cc7ad4f749b285a14fc455058a0b90f9626ecb648daccaa31fc547ca613d59d5efabde816e772
|
7
|
+
data.tar.gz: 9392e87f053d898c9e49cc96f8630e5056f9f58b2cddbc7db95cffd87424e8f1670a9fb0b572b38df81e6901140efb97f09d61564a975c79caf9cb8aa64948be
|
data/.travis.yml
CHANGED
@@ -8,5 +8,5 @@ before_script:
|
|
8
8
|
- "export DISPLAY=:99.0"
|
9
9
|
- "sh -e /etc/init.d/xvfb start"
|
10
10
|
- "sudo apt-get -qq -y install fontconfig libxrender1"
|
11
|
-
- "wget http://
|
11
|
+
- "wget http://download.gna.org/wkhtmltopdf/0.12/0.12.1/wkhtmltox-0.12.1_linux-precise-amd64.deb"
|
12
12
|
- "sudo dpkg -i wkhtmltox-0.12.1_linux-precise-amd64.deb"
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,12 @@
|
|
1
|
+
2015-08-20
|
2
|
+
=================
|
3
|
+
* Bump to 0.8.1
|
4
|
+
* Fix shell escaping issues for Windows (thanks muness)
|
5
|
+
* Fix shell escaping issues for URLs, introduced in 0.5.3 release
|
6
|
+
|
1
7
|
2015-07-08
|
2
8
|
=================
|
3
|
-
* Bump to 0.
|
9
|
+
* Bump to 0.8.0
|
4
10
|
* Support Cover and Table Of Contents options (thanks @nicpillinger)
|
5
11
|
* Fix repeatings keys with string values
|
6
12
|
* Fix caching bug (thanks @jocranford)
|
data/lib/pdfkit/pdfkit.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'shellwords'
|
2
|
+
require 'rbconfig'
|
2
3
|
|
3
4
|
class PDFKit
|
4
5
|
class NoExecutableError < StandardError
|
@@ -33,16 +34,15 @@ class PDFKit
|
|
33
34
|
|
34
35
|
def command(path = nil)
|
35
36
|
args = @options.to_a.flatten.compact
|
37
|
+
shell_escaped_command = [executable, shell_escape_for_os(args)].join ' '
|
36
38
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
args << (path || '-') # Write to file or stdout
|
39
|
+
# In order to allow for URL parameters (e.g. https://www.google.com/search?q=pdfkit) we do
|
40
|
+
# not escape the source. The user is responsible for ensuring that no vulnerabilities exist
|
41
|
+
# in the source. Please see https://github.com/pdfkit/pdfkit/issues/164.
|
42
|
+
input_for_command = @source.to_input_for_command
|
43
|
+
output_for_command = path ? Shellwords.shellescape(path) : '-'
|
44
44
|
|
45
|
-
|
45
|
+
"#{shell_escaped_command} #{input_for_command} #{output_for_command}"
|
46
46
|
end
|
47
47
|
|
48
48
|
def executable
|
@@ -161,7 +161,7 @@ class PDFKit
|
|
161
161
|
when Array
|
162
162
|
value.flatten.collect{|x| x.to_s}
|
163
163
|
else
|
164
|
-
value.to_s
|
164
|
+
(host_is_windows? && value.to_s.index(' ')) ? "'#{ value.to_s }'" : value.to_s
|
165
165
|
end
|
166
166
|
end
|
167
167
|
|
@@ -196,4 +196,18 @@ class PDFKit
|
|
196
196
|
# https://code.google.com/p/wkhtmltopdf/issues/detail?id=55
|
197
197
|
%w(skip ignore).include?(@options['--load-error-handling'])
|
198
198
|
end
|
199
|
+
|
200
|
+
def host_is_windows?
|
201
|
+
@host_is_windows ||= !(RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|cygwin|bccwin|wince/).nil?
|
202
|
+
end
|
203
|
+
|
204
|
+
def shell_escape_for_os(args)
|
205
|
+
if (host_is_windows?)
|
206
|
+
# Windows reserved shell characters are: & | ( ) < > ^
|
207
|
+
# See http://technet.microsoft.com/en-us/library/cc723564.aspx#XSLTsection123121120120
|
208
|
+
args.map { |arg| arg.gsub(/([&|()<>^])/,'^\1') }.join(" ")
|
209
|
+
else
|
210
|
+
args.shelljoin
|
211
|
+
end
|
212
|
+
end
|
199
213
|
end
|
data/lib/pdfkit/source.rb
CHANGED
@@ -1,23 +1,45 @@
|
|
1
1
|
class PDFKit
|
2
2
|
class Source
|
3
|
+
SOURCE_FROM_STDIN = '-'
|
4
|
+
|
3
5
|
def initialize(url_file_or_html)
|
4
6
|
@source = url_file_or_html
|
5
7
|
end
|
6
|
-
|
8
|
+
|
7
9
|
def url?
|
8
|
-
@source.is_a?(String) && @source.match(/\Ahttp/)
|
10
|
+
@is_url ||= @source.is_a?(String) && @source.match(/\Ahttp/)
|
9
11
|
end
|
10
|
-
|
12
|
+
|
11
13
|
def file?
|
12
|
-
@source.kind_of?(File)
|
14
|
+
@is_file ||= @source.kind_of?(File)
|
13
15
|
end
|
14
|
-
|
16
|
+
|
15
17
|
def html?
|
16
|
-
!(url? || file?)
|
18
|
+
@is_html ||= !(url? || file?)
|
17
19
|
end
|
18
|
-
|
20
|
+
|
21
|
+
def to_input_for_command
|
22
|
+
if file?
|
23
|
+
@source.path
|
24
|
+
elsif url?
|
25
|
+
%{"#{shell_safe_url}"}
|
26
|
+
else
|
27
|
+
SOURCE_FROM_STDIN
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
19
31
|
def to_s
|
20
32
|
file? ? @source.path : @source
|
21
33
|
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def shell_safe_url
|
38
|
+
url_needs_escaping? ? URI::escape(@source) : @source
|
39
|
+
end
|
40
|
+
|
41
|
+
def url_needs_escaping?
|
42
|
+
URI::decode(@source) == @source
|
43
|
+
end
|
22
44
|
end
|
23
45
|
end
|
data/lib/pdfkit/version.rb
CHANGED
data/spec/middleware_spec.rb
CHANGED
@@ -243,14 +243,14 @@ describe PDFKit::Middleware do
|
|
243
243
|
end
|
244
244
|
|
245
245
|
context "when header PDFKit-save-pdf is present" do
|
246
|
-
it "
|
246
|
+
it "saves the .pdf to disk" do
|
247
247
|
headers = { 'PDFKit-save-pdf' => 'spec/test_save.pdf' }
|
248
248
|
mock_app({}, {only: '/public'}, headers)
|
249
249
|
get 'http://www.example.org/public/test_save.pdf'
|
250
250
|
expect(File.exists?('spec/test_save.pdf')).to eq(true)
|
251
251
|
end
|
252
252
|
|
253
|
-
it "
|
253
|
+
it "does not raise when target directory does not exist" do
|
254
254
|
headers = { 'PDFKit-save-pdf' => '/this/dir/does/not/exist/spec/test_save.pdf' }
|
255
255
|
mock_app({}, {only: '/public'}, headers)
|
256
256
|
expect {
|
@@ -260,7 +260,7 @@ describe PDFKit::Middleware do
|
|
260
260
|
end
|
261
261
|
|
262
262
|
context "when header PDFKit-save-pdf is not present" do
|
263
|
-
it "
|
263
|
+
it "does not saved the .pdf to disk" do
|
264
264
|
mock_app({}, {only: '/public'}, {} )
|
265
265
|
get 'http://www.example.org/public/test_save.pdf'
|
266
266
|
expect(File.exists?('spec/test_save.pdf')).to eq(false)
|
@@ -325,31 +325,31 @@ describe PDFKit::Middleware do
|
|
325
325
|
@env = { 'REQUEST_URI' => 'http://example.com/document.pdf', 'rack.url_scheme' => 'http', 'HTTP_HOST' => 'example.com' }
|
326
326
|
end
|
327
327
|
|
328
|
-
it "
|
328
|
+
it "correctly parses relative url with single quotes" do
|
329
329
|
@body = %{<html><head><link href='/stylesheets/application.css' media='screen' rel='stylesheet' type='text/css' /></head><body><img alt='test' src="/test.png" /></body></html>}
|
330
330
|
body = @pdf.send :translate_paths, @body, @env
|
331
331
|
expect(body).to eq("<html><head><link href='http://example.com/stylesheets/application.css' media='screen' rel='stylesheet' type='text/css' /></head><body><img alt='test' src=\"http://example.com/test.png\" /></body></html>")
|
332
332
|
end
|
333
333
|
|
334
|
-
it "
|
334
|
+
it "correctly parses relative url with double quotes" do
|
335
335
|
@body = %{<link href="/stylesheets/application.css" media="screen" rel="stylesheet" type="text/css" />}
|
336
336
|
body = @pdf.send :translate_paths, @body, @env
|
337
337
|
expect(body).to eq("<link href=\"http://example.com/stylesheets/application.css\" media=\"screen\" rel=\"stylesheet\" type=\"text/css\" />")
|
338
338
|
end
|
339
339
|
|
340
|
-
it "
|
340
|
+
it "correctly parses relative url with double quotes" do
|
341
341
|
@body = %{<link href='//fonts.googleapis.com/css?family=Open+Sans:400,600' rel='stylesheet' type='text/css'>}
|
342
342
|
body = @pdf.send :translate_paths, @body, @env
|
343
343
|
expect(body).to eq("<link href='http://fonts.googleapis.com/css?family=Open+Sans:400,600' rel='stylesheet' type='text/css'>")
|
344
344
|
end
|
345
345
|
|
346
|
-
it "
|
346
|
+
it "correctly parses multiple tags where first one is root url" do
|
347
347
|
@body = %{<a href='/'><img src='/logo.jpg' ></a>}
|
348
348
|
body = @pdf.send :translate_paths, @body, @env
|
349
|
-
body.
|
349
|
+
expect(body).to eq "<a href='http://example.com/'><img src='http://example.com/logo.jpg' ></a>"
|
350
350
|
end
|
351
351
|
|
352
|
-
it "
|
352
|
+
it "returns the body even if there are no valid substitutions found" do
|
353
353
|
@body = "NO MATCH"
|
354
354
|
body = @pdf.send :translate_paths, @body, @env
|
355
355
|
expect(body).to eq("NO MATCH")
|
@@ -365,7 +365,7 @@ describe PDFKit::Middleware do
|
|
365
365
|
end
|
366
366
|
end
|
367
367
|
|
368
|
-
it "
|
368
|
+
it "adds the root_url" do
|
369
369
|
@body = %{<html><head><link href='/stylesheets/application.css' media='screen' rel='stylesheet' type='text/css' /></head><body><img alt='test' src="/test.png" /></body></html>}
|
370
370
|
body = @pdf.send :translate_paths, @body, @env
|
371
371
|
expect(body).to eq("<html><head><link href='http://example.net/stylesheets/application.css' media='screen' rel='stylesheet' type='text/css' /></head><body><img alt='test' src=\"http://example.net/test.png\" /></body></html>")
|
@@ -378,7 +378,7 @@ describe PDFKit::Middleware do
|
|
378
378
|
end
|
379
379
|
end
|
380
380
|
|
381
|
-
it "
|
381
|
+
it "does not get stuck rendering each request as pdf" do
|
382
382
|
mock_app
|
383
383
|
# false by default. No requests.
|
384
384
|
expect(@app.send(:rendering_pdf?)).to eq(false)
|
data/spec/pdfkit_spec.rb
CHANGED
@@ -4,19 +4,19 @@ require 'spec_helper'
|
|
4
4
|
describe PDFKit do
|
5
5
|
describe "initialization" do
|
6
6
|
# Source
|
7
|
-
it "
|
7
|
+
it "accepts HTML as the source" do
|
8
8
|
pdfkit = PDFKit.new('<h1>Oh Hai</h1>')
|
9
9
|
expect(pdfkit.source).to be_html
|
10
10
|
expect(pdfkit.source.to_s).to eq('<h1>Oh Hai</h1>')
|
11
11
|
end
|
12
12
|
|
13
|
-
it "
|
13
|
+
it "accepts a URL as the source" do
|
14
14
|
pdfkit = PDFKit.new('http://google.com')
|
15
15
|
expect(pdfkit.source).to be_url
|
16
16
|
expect(pdfkit.source.to_s).to eq('http://google.com')
|
17
17
|
end
|
18
18
|
|
19
|
-
it "
|
19
|
+
it "accepts a File as the source" do
|
20
20
|
file_path = File.join(SPEC_ROOT,'fixtures','example.html')
|
21
21
|
pdfkit = PDFKit.new(File.new(file_path))
|
22
22
|
expect(pdfkit.source).to be_file
|
@@ -126,26 +126,26 @@ describe PDFKit do
|
|
126
126
|
expect(pdfkit.options[['--allow', 'http://google.com']]).to eql nil
|
127
127
|
end
|
128
128
|
|
129
|
-
|
130
|
-
it "has no stylesheet by default" do
|
131
|
-
pdfkit = PDFKit.new('<h1>Oh Hai</h1>')
|
132
|
-
expect(pdfkit.stylesheets).to be_empty
|
133
|
-
end
|
134
|
-
|
135
|
-
it "should not prepend cover with --" do
|
129
|
+
it "does not prepend cover option with --" do
|
136
130
|
pdfkit = PDFKit.new('html', "cover" => 'http://google.com')
|
137
131
|
expect(pdfkit.options).to have_key('cover')
|
138
132
|
end
|
139
133
|
|
140
|
-
it "
|
134
|
+
it "does not prepend the toc option with --" do
|
141
135
|
pdfkit = PDFKit.new('html', 'toc' => '')
|
142
136
|
expect(pdfkit.options).to have_key('toc')
|
143
137
|
end
|
144
138
|
|
145
|
-
it "
|
139
|
+
it "handles cover and toc params passed as symbols" do
|
146
140
|
pdfkit = PDFKit.new('html', {toc: true})
|
147
141
|
expect(pdfkit.options).to have_key('toc')
|
148
142
|
end
|
143
|
+
|
144
|
+
# Stylesheets
|
145
|
+
it "has no stylesheet by default" do
|
146
|
+
pdfkit = PDFKit.new('<h1>Oh Hai</h1>')
|
147
|
+
expect(pdfkit.stylesheets).to be_empty
|
148
|
+
end
|
149
149
|
end
|
150
150
|
|
151
151
|
describe "#options" do
|
@@ -163,7 +163,7 @@ describe PDFKit do
|
|
163
163
|
end
|
164
164
|
|
165
165
|
describe "#command" do
|
166
|
-
it "
|
166
|
+
it "constructs the correct command" do
|
167
167
|
pdfkit = PDFKit.new('html', :page_size => 'Letter', :toc_l1_font_size => 12, :replace => {'foo' => 'bar'})
|
168
168
|
command = pdfkit.command
|
169
169
|
expect(command).to include "wkhtmltopdf"
|
@@ -172,26 +172,37 @@ describe PDFKit do
|
|
172
172
|
expect(command).to include "--replace foo bar"
|
173
173
|
end
|
174
174
|
|
175
|
-
it "
|
175
|
+
it "sets up one cookie when hash has only one cookie" do
|
176
176
|
pdfkit = PDFKit.new('html', cookie: {cookie_name: :cookie_value})
|
177
177
|
command = pdfkit.command
|
178
178
|
expect(command).to include "--cookie cookie_name cookie_value"
|
179
179
|
end
|
180
180
|
|
181
|
-
it "
|
181
|
+
it "does not break Windows paths" do
|
182
182
|
pdfkit = PDFKit.new('html')
|
183
183
|
allow(PDFKit.configuration).to receive(:wkhtmltopdf).and_return 'c:/Program Files/wkhtmltopdf/wkhtmltopdf.exe'
|
184
184
|
expect(pdfkit.command).not_to include('Program\ Files')
|
185
185
|
end
|
186
186
|
|
187
|
-
it "
|
187
|
+
it "does not shell escape source URLs" do
|
188
|
+
pdfkit = PDFKit.new('https://www.google.com/search?q=pdfkit')
|
189
|
+
expect(pdfkit.command).to include "https://www.google.com/search?q=pdfkit"
|
190
|
+
end
|
191
|
+
|
192
|
+
it "formats source for the command" do
|
193
|
+
pdfkit = PDFKit.new('https://www.google.com/search?q=pdfkit')
|
194
|
+
expect(pdfkit.source).to receive(:to_input_for_command)
|
195
|
+
pdfkit.command
|
196
|
+
end
|
197
|
+
|
198
|
+
it "sets up multiple cookies when passed multiple cookies" do
|
188
199
|
pdfkit = PDFKit.new('html', :cookie => {:cookie_name1 => :cookie_val1, :cookie_name2 => :cookie_val2})
|
189
200
|
command = pdfkit.command
|
190
201
|
expect(command).to include "--cookie cookie_name1 cookie_val1"
|
191
202
|
expect(command).to include "--cookie cookie_name2 cookie_val2"
|
192
203
|
end
|
193
204
|
|
194
|
-
it "
|
205
|
+
it "sets up multiple cookies when passed an array of tuples" do
|
195
206
|
pdfkit = PDFKit.new('html', :cookie => [[:cookie_name1, :cookie_val1], [:cookie_name2, :cookie_val2]])
|
196
207
|
command = pdfkit.command
|
197
208
|
expect(command).to include "--cookie cookie_name1 cookie_val1"
|
@@ -209,12 +220,12 @@ describe PDFKit do
|
|
209
220
|
expect(pdfkit.command).not_to include('--disable-smart-shrinking')
|
210
221
|
end
|
211
222
|
|
212
|
-
it "
|
223
|
+
it "encapsulates string arguments in quotes" do
|
213
224
|
pdfkit = PDFKit.new('html', :header_center => "foo [page]")
|
214
225
|
expect(pdfkit.command).to include "--header-center foo\\ \\[page\\]"
|
215
226
|
end
|
216
227
|
|
217
|
-
it "
|
228
|
+
it "sanitizes string arguments" do
|
218
229
|
pdfkit = PDFKit.new('html', :header_center => "$(ls)")
|
219
230
|
expect(pdfkit.command).to include "--header-center \\$\\(ls\\)"
|
220
231
|
end
|
@@ -224,24 +235,30 @@ describe PDFKit do
|
|
224
235
|
expect(pdfkit.command).to match /- -$/
|
225
236
|
end
|
226
237
|
|
227
|
-
it "
|
238
|
+
it "specifies the URL to the source if it is a url" do
|
228
239
|
pdfkit = PDFKit.new('http://google.com')
|
229
|
-
expect(pdfkit.command).to match /http:\/\/google.com -$/
|
240
|
+
expect(pdfkit.command).to match /"http:\/\/google.com" -$/
|
230
241
|
end
|
231
242
|
|
232
|
-
it "
|
243
|
+
it "does not break Windows paths" do
|
244
|
+
pdfkit = PDFKit.new('html')
|
245
|
+
allow(PDFKit.configuration).to receive(:wkhtmltopdf).and_return 'c:/Program Files/wkhtmltopdf/wkhtmltopdf.exe'
|
246
|
+
expect(pdfkit.command).not_to include('Program\ Files')
|
247
|
+
end
|
248
|
+
|
249
|
+
it "specifies the path to the source if it is a file" do
|
233
250
|
file_path = File.join(SPEC_ROOT,'fixtures','example.html')
|
234
251
|
pdfkit = PDFKit.new(File.new(file_path))
|
235
252
|
expect(pdfkit.command).to match /#{file_path} -$/
|
236
253
|
end
|
237
254
|
|
238
|
-
it "
|
255
|
+
it "specifies the path for the ouput if a path is given" do
|
239
256
|
file_path = "/path/to/output.pdf"
|
240
257
|
pdfkit = PDFKit.new("html")
|
241
258
|
expect(pdfkit.command(file_path)).to match /#{file_path}$/
|
242
259
|
end
|
243
260
|
|
244
|
-
it "
|
261
|
+
it "detects special pdfkit meta tags" do
|
245
262
|
body = %{
|
246
263
|
<html>
|
247
264
|
<head>
|
@@ -256,7 +273,7 @@ describe PDFKit do
|
|
256
273
|
expect(command).to include "--orientation Landscape"
|
257
274
|
end
|
258
275
|
|
259
|
-
it "
|
276
|
+
it "detects cookies meta tag" do
|
260
277
|
body = %{
|
261
278
|
<html>
|
262
279
|
<head>
|
@@ -270,7 +287,7 @@ describe PDFKit do
|
|
270
287
|
expect(command).to include "--cookie rails_session rails_session_value --cookie cookie_variable cookie_variable_value"
|
271
288
|
end
|
272
289
|
|
273
|
-
it "
|
290
|
+
it "detects disable_smart_shrinking meta tag" do
|
274
291
|
body = %{
|
275
292
|
<html>
|
276
293
|
<head>
|
@@ -284,7 +301,7 @@ describe PDFKit do
|
|
284
301
|
expect(command).not_to include "--disable-smart-shrinking true"
|
285
302
|
end
|
286
303
|
|
287
|
-
it "
|
304
|
+
it "detects names with hyphens instead of underscores" do
|
288
305
|
body = %{
|
289
306
|
<html>
|
290
307
|
<head>
|
@@ -298,7 +315,7 @@ describe PDFKit do
|
|
298
315
|
expect(pdfkit.command).not_to include 'name\='
|
299
316
|
end
|
300
317
|
|
301
|
-
it "
|
318
|
+
it "detects special pdfkit meta tags despite bad markup" do
|
302
319
|
body = %{
|
303
320
|
<html>
|
304
321
|
<head>
|
@@ -314,7 +331,7 @@ describe PDFKit do
|
|
314
331
|
expect(command).to include "--orientation Landscape"
|
315
332
|
end
|
316
333
|
|
317
|
-
it "
|
334
|
+
it "skips non-pdfkit meta tags" do
|
318
335
|
body = %{
|
319
336
|
<html>
|
320
337
|
<head>
|
@@ -330,17 +347,17 @@ describe PDFKit do
|
|
330
347
|
expect(command).to include "--orientation Landscape"
|
331
348
|
end
|
332
349
|
|
333
|
-
it "
|
350
|
+
it "does not use quiet when told to" do
|
334
351
|
pdfkit = PDFKit.new('html', quiet: false)
|
335
352
|
expect(pdfkit.command).not_to include '--quiet'
|
336
353
|
end
|
337
354
|
|
338
|
-
it "
|
355
|
+
it "uses quiet option by default" do
|
339
356
|
pdfkit = PDFKit.new('html')
|
340
357
|
expect(pdfkit.command).to include '--quiet'
|
341
358
|
end
|
342
359
|
|
343
|
-
it "
|
360
|
+
it "does not use quiet option in verbose mode" do
|
344
361
|
PDFKit.configure do |config|
|
345
362
|
config.verbose = true
|
346
363
|
end
|
@@ -353,7 +370,7 @@ describe PDFKit do
|
|
353
370
|
end
|
354
371
|
end
|
355
372
|
|
356
|
-
it "
|
373
|
+
it "does not use quiet option in verbose mode when option of quiet is configured" do
|
357
374
|
PDFKit.configure do |config|
|
358
375
|
config.verbose = true
|
359
376
|
config.default_options[:quiet] = true
|
@@ -366,10 +383,26 @@ describe PDFKit do
|
|
366
383
|
config.verbose = false
|
367
384
|
end
|
368
385
|
end
|
386
|
+
|
387
|
+
context "on windows" do
|
388
|
+
before do
|
389
|
+
allow_any_instance_of(PDFKit).to receive(:host_is_windows?).and_return(true)
|
390
|
+
end
|
391
|
+
|
392
|
+
it "escapes special windows characters" do
|
393
|
+
pdf = PDFKit.new('html', :title => 'hello(world)')
|
394
|
+
expect(pdf.command).to include 'hello^(world^)'
|
395
|
+
end
|
396
|
+
|
397
|
+
it "quotes spaces in options" do
|
398
|
+
pdf = PDFKit.new('html', :title => 'hello world')
|
399
|
+
expect(pdf.command).to include "--title 'hello world'"
|
400
|
+
end
|
401
|
+
end
|
369
402
|
end
|
370
403
|
|
371
404
|
describe "#to_pdf" do
|
372
|
-
it "
|
405
|
+
it "does not read the contents of the pdf when saving it as a file" do
|
373
406
|
file_path = "/my/file/path.pdf"
|
374
407
|
pdfkit = PDFKit.new('html', :page_size => 'Letter')
|
375
408
|
|
@@ -388,25 +421,25 @@ describe PDFKit do
|
|
388
421
|
pdfkit.to_pdf(file_path)
|
389
422
|
end
|
390
423
|
|
391
|
-
it "
|
424
|
+
it "generates a PDF of the HTML" do
|
392
425
|
pdfkit = PDFKit.new('html', :page_size => 'Letter')
|
393
426
|
pdf = pdfkit.to_pdf
|
394
427
|
expect(pdf[0...4]).to eq("%PDF") # PDF Signature at beginning of file
|
395
428
|
end
|
396
429
|
|
397
|
-
it "
|
430
|
+
it "generates a PDF with a numerical parameter" do
|
398
431
|
pdfkit = PDFKit.new('html', :header_spacing => 1)
|
399
432
|
pdf = pdfkit.to_pdf
|
400
433
|
expect(pdf[0...4]).to eq("%PDF") # PDF Signature at beginning of file
|
401
434
|
end
|
402
435
|
|
403
|
-
it "
|
436
|
+
it "generates a PDF with a symbol parameter" do
|
404
437
|
pdfkit = PDFKit.new('html', :page_size => :Letter)
|
405
438
|
pdf = pdfkit.to_pdf
|
406
439
|
expect(pdf[0...4]).to eq("%PDF") # PDF Signature at beginning of file
|
407
440
|
end
|
408
441
|
|
409
|
-
it "
|
442
|
+
it "adds the stylesheet to the head tag if it has a head tag" do
|
410
443
|
pdfkit = PDFKit.new("<html><head></head><body>Hai!</body></html>")
|
411
444
|
css = File.join(SPEC_ROOT,'fixtures','example.css')
|
412
445
|
pdfkit.stylesheets << css
|
@@ -414,7 +447,7 @@ describe PDFKit do
|
|
414
447
|
expect(pdfkit.source.to_s).to include("<style>#{File.read(css)}</style>")
|
415
448
|
end
|
416
449
|
|
417
|
-
it "
|
450
|
+
it "prepends style tags if the HTML doesn't have a head tag" do
|
418
451
|
pdfkit = PDFKit.new("<html><body>Hai!</body></html>")
|
419
452
|
css = File.join(SPEC_ROOT,'fixtures','example.css')
|
420
453
|
pdfkit.stylesheets << css
|
@@ -422,14 +455,14 @@ describe PDFKit do
|
|
422
455
|
expect(pdfkit.source.to_s).to include("<style>#{File.read(css)}</style><html>")
|
423
456
|
end
|
424
457
|
|
425
|
-
it "
|
458
|
+
it "throws an error if the source is not html and stylesheets have been added" do
|
426
459
|
pdfkit = PDFKit.new('http://google.com')
|
427
460
|
css = File.join(SPEC_ROOT,'fixtures','example.css')
|
428
461
|
pdfkit.stylesheets << css
|
429
462
|
expect { pdfkit.to_pdf }.to raise_error(PDFKit::ImproperSourceError)
|
430
463
|
end
|
431
464
|
|
432
|
-
it "
|
465
|
+
it "can deal with ActiveSupport::SafeBuffer" do
|
433
466
|
pdfkit = PDFKit.new(ActiveSupport::SafeBuffer.new "<html><head></head><body>Hai!</body></html>")
|
434
467
|
css = File.join(SPEC_ROOT,'fixtures','example.css')
|
435
468
|
pdfkit.stylesheets << css
|
@@ -437,7 +470,7 @@ describe PDFKit do
|
|
437
470
|
expect(pdfkit.source.to_s).to include("<style>#{File.read(css)}</style></head>")
|
438
471
|
end
|
439
472
|
|
440
|
-
it "
|
473
|
+
it "escapes \\X in stylesheets" do
|
441
474
|
pdfkit = PDFKit.new("<html><head></head><body>Hai!</body></html>")
|
442
475
|
css = File.join(SPEC_ROOT,'fixtures','example_with_hex_symbol.css')
|
443
476
|
pdfkit.stylesheets << css
|
@@ -446,22 +479,28 @@ describe PDFKit do
|
|
446
479
|
end
|
447
480
|
|
448
481
|
#NOTICE: This test is failed if use wkhtmltopdf-binary (0.9.9.1)
|
449
|
-
it "
|
482
|
+
it "throws an error if it is unable to connect" do
|
450
483
|
pdfkit = PDFKit.new("http://google.com/this-should-not-be-found/404.html")
|
451
484
|
expect { pdfkit.to_pdf }.to raise_error /exitstatus=1/
|
452
485
|
end
|
453
486
|
|
454
|
-
it "
|
487
|
+
it "does not throw an error if it is unable to connect", pending: 'this test works for wkhtmltopdf-binary (0.9.9.1)' do
|
455
488
|
pdfkit = PDFKit.new("http://localhost/this-should-not-be-found/404.html")
|
456
489
|
pdf = pdfkit.to_pdf
|
457
490
|
expect(pdf[0...4]).to eq("%PDF") # PDF Signature at the beginning
|
458
491
|
end
|
459
492
|
|
460
|
-
it "
|
493
|
+
it "generates a PDF if there are missing assets" do
|
461
494
|
pdfkit = PDFKit.new("<html><body><img alt='' src='http://example.com/surely-it-doesnt-exist.gif' /></body></html>")
|
462
495
|
pdf = pdfkit.to_pdf
|
463
496
|
expect(pdf[0...4]).to eq("%PDF") # PDF Signature at the beginning
|
464
497
|
end
|
498
|
+
|
499
|
+
it "can handle ampersands in URLs" do
|
500
|
+
pdfkit = PDFKit.new('https://www.google.com/search?q=pdfkit&sort=ASC')
|
501
|
+
pdf = pdfkit.to_pdf
|
502
|
+
expect(pdf[0...4]).to eq("%PDF") # PDF Signature at the beginning
|
503
|
+
end
|
465
504
|
end
|
466
505
|
|
467
506
|
describe "#to_file" do
|
@@ -474,14 +513,14 @@ describe PDFKit do
|
|
474
513
|
File.delete(@file_path)
|
475
514
|
end
|
476
515
|
|
477
|
-
it "
|
516
|
+
it "creates a file with the PDF as content" do
|
478
517
|
pdfkit = PDFKit.new('html', :page_size => 'Letter')
|
479
518
|
file = pdfkit.to_file(@file_path)
|
480
519
|
expect(file).to be_instance_of(File)
|
481
520
|
expect(File.read(file.path)[0...4]).to eq("%PDF") # PDF Signature at beginning of file
|
482
521
|
end
|
483
522
|
|
484
|
-
it "
|
523
|
+
it "does not truncate data (in Ruby 1.8.6)" do
|
485
524
|
file_path = File.join(SPEC_ROOT,'fixtures','example.html')
|
486
525
|
pdfkit = PDFKit.new(File.new(file_path))
|
487
526
|
pdf_data = pdfkit.to_pdf
|
@@ -501,7 +540,7 @@ describe PDFKit do
|
|
501
540
|
File.delete(@test_path) if File.exist?(@test_path)
|
502
541
|
end
|
503
542
|
|
504
|
-
it "
|
543
|
+
it "does not allow shell injection in options" do
|
505
544
|
pdfkit = PDFKit.new('html', :header_center => "a title\"; touch #{@test_path} #")
|
506
545
|
pdfkit.to_pdf
|
507
546
|
expect(File.exist?(@test_path)).to eq(false)
|
data/spec/source_spec.rb
CHANGED
@@ -2,73 +2,95 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe PDFKit::Source do
|
4
4
|
describe "#url?" do
|
5
|
-
it "
|
5
|
+
it "returns true if passed a url like string" do
|
6
6
|
source = PDFKit::Source.new('http://google.com')
|
7
7
|
expect(source).to be_url
|
8
8
|
end
|
9
9
|
|
10
|
-
it "
|
10
|
+
it "returns false if passed a file" do
|
11
11
|
source = PDFKit::Source.new(File.new(__FILE__))
|
12
12
|
expect(source).not_to be_url
|
13
13
|
end
|
14
14
|
|
15
|
-
it "
|
15
|
+
it "returns false if passed HTML" do
|
16
16
|
source = PDFKit::Source.new('<blink>Oh Hai!</blink>')
|
17
17
|
expect(source).not_to be_url
|
18
18
|
end
|
19
19
|
|
20
|
-
it "
|
20
|
+
it "returns false if passed HTML with embedded urls at the beginning of a line" do
|
21
21
|
source = PDFKit::Source.new("<blink>Oh Hai!</blink>\nhttp://www.google.com")
|
22
22
|
expect(source).not_to be_url
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
26
|
describe "#file?" do
|
27
|
-
it "
|
27
|
+
it "returns true if passed a file" do
|
28
28
|
source = PDFKit::Source.new(::File.new(__FILE__))
|
29
29
|
expect(source).to be_file
|
30
30
|
end
|
31
31
|
|
32
|
-
it "
|
32
|
+
it "returns false if passed a url like string" do
|
33
33
|
source = PDFKit::Source.new('http://google.com')
|
34
34
|
expect(source).not_to be_file
|
35
35
|
end
|
36
36
|
|
37
|
-
it "
|
37
|
+
it "returns false if passed HTML" do
|
38
38
|
source = PDFKit::Source.new('<blink>Oh Hai!</blink>')
|
39
39
|
expect(source).not_to be_file
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
43
|
describe "#html?" do
|
44
|
-
it "
|
44
|
+
it "returns true if passed HTML" do
|
45
45
|
source = PDFKit::Source.new('<blink>Oh Hai!</blink>')
|
46
46
|
expect(source).to be_html
|
47
47
|
end
|
48
48
|
|
49
|
-
it "
|
49
|
+
it "returns false if passed a file" do
|
50
50
|
source = PDFKit::Source.new(::File.new(__FILE__))
|
51
51
|
expect(source).not_to be_html
|
52
52
|
end
|
53
53
|
|
54
|
-
it "
|
54
|
+
it "returns false if passed a url like string" do
|
55
55
|
source = PDFKit::Source.new('http://google.com')
|
56
56
|
expect(source).not_to be_html
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
+
describe "#to_input_for_command" do
|
61
|
+
it "URI escapes source URLs and encloses them in quotes to accomodate ampersands" do
|
62
|
+
source = PDFKit::Source.new("https://www.google.com/search?q='cat<dev/zero>/dev/null'")
|
63
|
+
expect(source.to_input_for_command).to eq "\"https://www.google.com/search?q='cat%3Cdev/zero%3E/dev/null'\""
|
64
|
+
end
|
65
|
+
|
66
|
+
it "does not URI escape previously escaped source URLs" do
|
67
|
+
source = PDFKit::Source.new("https://www.google.com/search?q='cat%3Cdev/zero%3E/dev/null'")
|
68
|
+
expect(source.to_input_for_command).to eq "\"https://www.google.com/search?q='cat%3Cdev/zero%3E/dev/null'\""
|
69
|
+
end
|
70
|
+
|
71
|
+
it "returns a '-' for HTML strings to indicate that we send that content through STDIN" do
|
72
|
+
source = PDFKit::Source.new('<blink>Oh Hai!</blink>')
|
73
|
+
expect(source.to_input_for_command).to eq '-'
|
74
|
+
end
|
75
|
+
|
76
|
+
it "returns the file path for file sources" do
|
77
|
+
source = PDFKit::Source.new(::File.new(__FILE__))
|
78
|
+
expect(source.to_input_for_command).to match 'spec/source_spec.rb'
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
60
82
|
describe "#to_s" do
|
61
|
-
it "
|
83
|
+
it "returns the HTML if passed HTML" do
|
62
84
|
source = PDFKit::Source.new('<blink>Oh Hai!</blink>')
|
63
85
|
expect(source.to_s).to eq('<blink>Oh Hai!</blink>')
|
64
86
|
end
|
65
87
|
|
66
|
-
it "
|
88
|
+
it "returns a path if passed a file" do
|
67
89
|
source = PDFKit::Source.new(::File.new(__FILE__))
|
68
90
|
expect(source.to_s).to eq(__FILE__)
|
69
91
|
end
|
70
92
|
|
71
|
-
it "
|
93
|
+
it "returns the url if passed a url like string" do
|
72
94
|
source = PDFKit::Source.new('http://google.com')
|
73
95
|
expect(source.to_s).to eq('http://google.com')
|
74
96
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pdfkit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jared Pace
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-08-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|