pdfkit 0.8.7 → 0.8.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 824738b3d4f198d080bb590e5db7489da39ffb40f5f8c24b97652793160ac0d9
4
- data.tar.gz: 963701136ddf00dd42502b2d564135c675ae1ae313c6cd40d8dd92761a70b3af
3
+ metadata.gz: b5277a9f3eef01b48a25763e16c1f2ebb1bd84e9868ad0c5dbd7a09aa1e4b1dc
4
+ data.tar.gz: '05039a31dc9ec5927c2dbcc7ba106e590d9e104e390f4740e5106a039120db37'
5
5
  SHA512:
6
- metadata.gz: 6340e287849a0c43b8883cc1f2b78138fc5628fd2da4670c5f5d8a150632b56dbf27c9716bea49c1007cc2359148a4b3c1af1fed8c264ff89cf3d379976bfe30
7
- data.tar.gz: b1b4f6d302ec4c407ebac2dfcc6bf3d72d7882520ba407bdb0d2b0316684ddcc09d3eecf0967305976292210a21304dc9b399fa39a9c4055ced27c5b7b8c1677
6
+ metadata.gz: d2faea1df102a9429d63d210f36f6a029f233d236f8bc496bf67c2f737592516d5ddd963039e6069e422a62abbc7d2eff41dbf3657a6de520c2ffd5bc92c874f
7
+ data.tar.gz: aae487ef8e56463a37a576bc6eeb8ab42ccd74b4912a1b79e027879481e773b340fd9d6802d4d929200debf5b9634bd121eae0fd9551d449ab0e732d020a3aae
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ 2022-10-18
2
+ =================
3
+ * Bump to 0.8.7.2
4
+ * Call IO.popen with an Array of command arguments (#519)
5
+
6
+ 2022-10-17
7
+ =================
8
+ * Bump to 0.8.7.1
9
+ * Support non-lower-case Content-Type header provided by app (#516)
10
+
1
11
  2022-10-02
2
12
  =================
3
13
  * Bump to 0.8.7
@@ -45,7 +45,7 @@ class PDFKit
45
45
  end
46
46
 
47
47
  def executable
48
- using_xvfb? ? "xvfb-run #{wkhtmltopdf}" : wkhtmltopdf
48
+ using_xvfb? ? ['xvfb-run', wkhtmltopdf] : wkhtmltopdf
49
49
  end
50
50
 
51
51
  def using_xvfb?
@@ -22,7 +22,8 @@ class PDFKit
22
22
  status, headers, response = @app.call(env)
23
23
 
24
24
  begin
25
- if rendering_pdf? && headers['content-type'] =~ /text\/html|application\/xhtml\+xml/
25
+ content_type_header = headers.has_key?('Content-Type') ? 'Content-Type' : 'content-type'
26
+ if rendering_pdf? && headers[content_type_header] =~ /text\/html|application\/xhtml\+xml/
26
27
  body = response.respond_to?(:body) ? response.body : response.join
27
28
  body = body.join if body.is_a?(Array)
28
29
 
@@ -49,7 +50,7 @@ class PDFKit
49
50
  end
50
51
 
51
52
  headers['content-length'] = (body.respond_to?(:bytesize) ? body.bytesize : body.size).to_s
52
- headers['content-type'] = 'application/pdf'
53
+ headers[content_type_header] = 'application/pdf'
53
54
  headers['content-disposition'] ||= @conditions[:disposition] || 'inline'
54
55
  end
55
56
  rescue StandardError => e
data/lib/pdfkit/pdfkit.rb CHANGED
@@ -46,16 +46,11 @@ class PDFKit
46
46
  end
47
47
 
48
48
  def command(path = nil)
49
- args = @renderer.options_for_command
50
- shell_escaped_command = [executable, OS::shell_escape_for_os(args)].join ' '
51
-
52
- # In order to allow for URL parameters (e.g. https://www.google.com/search?q=pdfkit) we do
53
- # not escape the source. The user is responsible for ensuring that no vulnerabilities exist
54
- # in the source. Please see https://github.com/pdfkit/pdfkit/issues/164.
55
- input_for_command = @source.to_input_for_command
56
- output_for_command = path ? Shellwords.shellescape(path) : '-'
57
-
58
- "#{shell_escaped_command} #{input_for_command} #{output_for_command}"
49
+ args = [*executable]
50
+ args.concat(@renderer.options_for_command)
51
+ args << @source.to_input_for_command
52
+ args << (path ? path : '-')
53
+ args
59
54
  end
60
55
 
61
56
  def options
data/lib/pdfkit/source.rb CHANGED
@@ -29,7 +29,7 @@ class PDFKit
29
29
  if file?
30
30
  @source.path
31
31
  elsif url?
32
- %{"#{shell_safe_url}"}
32
+ escaped_url
33
33
  else
34
34
  SOURCE_FROM_STDIN
35
35
  end
@@ -41,7 +41,7 @@ class PDFKit
41
41
 
42
42
  private
43
43
 
44
- def shell_safe_url
44
+ def escaped_url
45
45
  url_needs_escaping? ? URI::DEFAULT_PARSER.escape(@source) : @source
46
46
  end
47
47
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class PDFKit
4
- VERSION = '0.8.7'
4
+ VERSION = '0.8.7.2'
5
5
  end
@@ -64,7 +64,7 @@ class PDFKit
64
64
  when Array
65
65
  value.flatten.collect{|x| x.to_s}
66
66
  else
67
- (OS::host_is_windows? && value.to_s.index(' ')) ? "'#{ value.to_s }'" : value.to_s
67
+ value.to_s
68
68
  end
69
69
  end
70
70
 
@@ -422,6 +422,29 @@ describe PDFKit::Middleware do
422
422
  end
423
423
  end
424
424
 
425
+ describe "content type header" do
426
+ before { mock_app }
427
+
428
+ context "lower case" do
429
+ specify "header gets correctly updated" do
430
+ get 'http://www.example.org/public/test.pdf'
431
+ expect(last_response.headers["content-type"]).to eq("application/pdf")
432
+ end
433
+ end
434
+
435
+ context "mixed case" do
436
+ let(:headers) do
437
+ {'Content-Type' => "text/html"}
438
+ end
439
+
440
+ specify "header gets correctly updated" do
441
+ pending("this test only applies to rack 2.x and is rejected by rack 3.x") if Rack.release >= "3.0.0"
442
+ get 'http://www.example.org/public/test.pdf'
443
+ expect(last_response.headers["Content-Type"]).to eq("application/pdf")
444
+ end
445
+ end
446
+ end
447
+
425
448
  describe "remove .pdf from PATH_INFO and REQUEST_URI" do
426
449
  before { mock_app }
427
450
 
data/spec/pdfkit_spec.rb CHANGED
@@ -175,22 +175,22 @@ describe PDFKit do
175
175
  it "constructs the correct command" do
176
176
  pdfkit = PDFKit.new('html', :page_size => 'Letter', :toc_l1_font_size => 12, :replace => {'foo' => 'bar'})
177
177
  command = pdfkit.command
178
- expect(command).to include "wkhtmltopdf"
179
- expect(command).to include "--page-size Letter"
180
- expect(command).to include "--toc-l1-font-size 12"
181
- expect(command).to include "--replace foo bar"
178
+ expect(command.first).to match(/wkhtmltopdf/)
179
+ expect(command).to contain %w[--page-size Letter]
180
+ expect(command).to contain %w[--toc-l1-font-size 12]
181
+ expect(command).to contain %w[--replace foo bar]
182
182
  end
183
183
 
184
184
  it "sets up one cookie when hash has only one cookie" do
185
185
  pdfkit = PDFKit.new('html', cookie: {cookie_name: :cookie_value})
186
186
  command = pdfkit.command
187
- expect(command).to include "--cookie cookie_name cookie_value"
187
+ expect(command).to contain %w[--cookie cookie_name cookie_value]
188
188
  end
189
189
 
190
- it "does not break Windows paths" do
190
+ it "does not split Windows paths that contain spaces" do
191
191
  pdfkit = PDFKit.new('html')
192
192
  allow(PDFKit.configuration).to receive(:wkhtmltopdf).and_return 'c:/Program Files/wkhtmltopdf/wkhtmltopdf.exe'
193
- expect(pdfkit.command).not_to include('Program\ Files')
193
+ expect(pdfkit.command).not_to contain(%w[c:/Program Files/wkhtmltopdf/wkhtmltopdf.exe])
194
194
  end
195
195
 
196
196
  it "does not shell escape source URLs" do
@@ -207,15 +207,15 @@ describe PDFKit do
207
207
  it "sets up multiple cookies when passed multiple cookies" do
208
208
  pdfkit = PDFKit.new('html', :cookie => {:cookie_name1 => :cookie_val1, :cookie_name2 => :cookie_val2})
209
209
  command = pdfkit.command
210
- expect(command).to include "--cookie cookie_name1 cookie_val1"
211
- expect(command).to include "--cookie cookie_name2 cookie_val2"
210
+ expect(command).to contain %w[--cookie cookie_name1 cookie_val1]
211
+ expect(command).to contain %w[--cookie cookie_name2 cookie_val2]
212
212
  end
213
213
 
214
214
  it "sets up multiple cookies when passed an array of tuples" do
215
215
  pdfkit = PDFKit.new('html', :cookie => [[:cookie_name1, :cookie_val1], [:cookie_name2, :cookie_val2]])
216
216
  command = pdfkit.command
217
- expect(command).to include "--cookie cookie_name1 cookie_val1"
218
- expect(command).to include "--cookie cookie_name2 cookie_val2"
217
+ expect(command).to contain %w[--cookie cookie_name1 cookie_val1]
218
+ expect(command).to contain %w[--cookie cookie_name2 cookie_val2]
219
219
  end
220
220
 
221
221
  it "will not include default options it is told to omit" do
@@ -229,48 +229,57 @@ describe PDFKit do
229
229
  expect(pdfkit.command).not_to include('--disable-smart-shrinking')
230
230
  end
231
231
 
232
- it "encapsulates string arguments in quotes" do
232
+ it "must not split string arguments containing spaces" do
233
233
  pdfkit = PDFKit.new('html', :header_center => "foo [page]")
234
- expect(pdfkit.command).to include "--header-center foo\\ \\[page\\]"
234
+ expect(pdfkit.command).to contain ['--header-center', 'foo [page]']
235
235
  end
236
236
 
237
- it "sanitizes string arguments" do
237
+ it "paramatarizes string arguments" do
238
238
  pdfkit = PDFKit.new('html', :header_center => "$(ls)")
239
- expect(pdfkit.command).to include "--header-center \\$\\(ls\\)"
239
+ expect(pdfkit.command).to contain %w[--header-center $(ls)]
240
240
  end
241
241
 
242
242
  it "read the source from stdin if it is html" do
243
243
  pdfkit = PDFKit.new('html')
244
- expect(pdfkit.command).to match(/- -$/)
244
+ command = pdfkit.command
245
+ expect(command[-2]).to eq('-')
246
+ expect(command[-1]).to eq('-')
245
247
  end
246
248
 
247
249
  it "specifies the URL to the source if it is a url" do
248
250
  pdfkit = PDFKit.new('http://google.com')
249
- expect(pdfkit.command).to match(/"http:\/\/google.com" -$/)
251
+ command = pdfkit.command
252
+ expect(command[-2]).to eq("http://google.com")
253
+ expect(command[-1]).to eq("-")
250
254
  end
251
255
 
252
256
  it "does not break Windows paths" do
253
257
  pdfkit = PDFKit.new('html')
254
258
  allow(PDFKit.configuration).to receive(:wkhtmltopdf).and_return 'c:/Program Files/wkhtmltopdf/wkhtmltopdf.exe'
255
- expect(pdfkit.command).not_to include('Program\ Files')
259
+ expect(pdfkit.command).not_to contain ['Program', 'Files']
256
260
  end
257
261
 
258
262
  it "specifies the path to the source if it is a file" do
259
263
  file_path = File.join(SPEC_ROOT,'fixtures','example.html')
260
264
  pdfkit = PDFKit.new(File.new(file_path))
261
- expect(pdfkit.command).to match(/#{file_path} -$/)
265
+ command = pdfkit.command
266
+ expect(command[-2]).to eq(file_path)
267
+ expect(command[-1]).to eq('-')
262
268
  end
263
269
 
264
270
  it "specifies the path to the source if it is a tempfile" do
265
271
  file_path = File.join(SPEC_ROOT,'fixtures','example.html')
266
272
  pdfkit = PDFKit.new(Tempfile.new(file_path))
267
- expect(pdfkit.command).to match(/#{Dir.tmpdir}\S+ -$/)
273
+ command = pdfkit.command
274
+ expect(command[-2]).to start_with(Dir.tmpdir)
275
+ expect(command[-1]).to eq('-')
268
276
  end
269
277
 
270
278
  it "specifies the path for the ouput if a path is given" do
271
279
  file_path = "/path/to/output.pdf"
272
280
  pdfkit = PDFKit.new("html")
273
- expect(pdfkit.command(file_path)).to match(/#{file_path}$/)
281
+ command = pdfkit.command(file_path)
282
+ expect(command.last).to eq(file_path)
274
283
  end
275
284
 
276
285
  it "detects special pdfkit meta tags" do
@@ -284,8 +293,8 @@ describe PDFKit do
284
293
  }
285
294
  pdfkit = PDFKit.new(body)
286
295
  command = pdfkit.command
287
- expect(command).to include "--page-size Legal"
288
- expect(command).to include "--orientation Landscape"
296
+ expect(command).to contain %w[--page-size Legal]
297
+ expect(command).to contain %w[--orientation Landscape]
289
298
  end
290
299
 
291
300
  it "detects cookies meta tag" do
@@ -299,7 +308,7 @@ describe PDFKit do
299
308
  }
300
309
  pdfkit = PDFKit.new(body)
301
310
  command = pdfkit.command
302
- expect(command).to include "--cookie rails_session rails_session_value --cookie cookie_variable cookie_variable_value"
311
+ expect(command).to contain %w[--cookie rails_session rails_session_value --cookie cookie_variable cookie_variable_value]
303
312
  end
304
313
 
305
314
  it "detects disable_smart_shrinking meta tag" do
@@ -313,7 +322,7 @@ describe PDFKit do
313
322
  pdfkit = PDFKit.new(body)
314
323
  command = pdfkit.command
315
324
  expect(command).to include "--disable-smart-shrinking"
316
- expect(command).not_to include "--disable-smart-shrinking true"
325
+ expect(command).not_to contain %w[--disable-smart-shrinking true]
317
326
  end
318
327
 
319
328
  it "detects names with hyphens instead of underscores" do
@@ -342,8 +351,8 @@ describe PDFKit do
342
351
  }
343
352
  pdfkit = PDFKit.new(body)
344
353
  command = pdfkit.command
345
- expect(command).to include "--page-size Legal"
346
- expect(command).to include "--orientation Landscape"
354
+ expect(command).to contain %w[--page-size Legal]
355
+ expect(command).to contain %w[--orientation Landscape]
347
356
  end
348
357
 
349
358
  it "skips non-pdfkit meta tags" do
@@ -358,8 +367,8 @@ describe PDFKit do
358
367
  }
359
368
  pdfkit = PDFKit.new(body)
360
369
  command = pdfkit.command
361
- expect(command).not_to include "--page-size Legal"
362
- expect(command).to include "--orientation Landscape"
370
+ expect(command).not_to contain %w[--page-size Legal]
371
+ expect(command).to contain %w[--orientation Landscape]
363
372
  end
364
373
 
365
374
  it "does not use quiet when told to" do
@@ -422,14 +431,9 @@ describe PDFKit do
422
431
  allow(PDFKit::OS).to receive(:host_is_windows?).and_return(true)
423
432
  end
424
433
 
425
- it "escapes special windows characters" do
426
- pdf = PDFKit.new('html', :title => 'hello(world)')
427
- expect(pdf.command).to include 'hello^(world^)'
428
- end
429
-
430
434
  it "quotes spaces in options" do
431
435
  pdf = PDFKit.new('html', :title => 'hello world')
432
- expect(pdf.command).to include "--title 'hello world'"
436
+ expect(pdf.command).to contain ['--title', "hello world"]
433
437
  end
434
438
  end
435
439
  end
data/spec/source_spec.rb CHANGED
@@ -75,19 +75,14 @@ describe PDFKit::Source do
75
75
  end
76
76
 
77
77
  describe "#to_input_for_command" do
78
- it "URI escapes source URLs and encloses them in quotes to accomodate ampersands" do
79
- source = PDFKit::Source.new("https://www.google.com/search?q='cat<dev/zero>/dev/null'")
80
- expect(source.to_input_for_command).to eq "\"https://www.google.com/search?q='cat%3Cdev/zero%3E/dev/null'\""
81
- end
82
-
83
- it "URI escapes source URI only escape part of it" do
84
- source = PDFKit::Source.new("https://www.google.com/search?q='%20 sleep 5'")
85
- expect(source.to_input_for_command).to eq "\"https://www.google.com/search?q='%2520%20sleep%205'\""
78
+ it "URI escapes source URI" do
79
+ source = PDFKit::Source.new("https://www.google.com/search?q=foo bar")
80
+ expect(source.to_input_for_command).to eq "https://www.google.com/search?q=foo%20bar"
86
81
  end
87
82
 
88
83
  it "does not URI escape previously escaped source URLs" do
89
- source = PDFKit::Source.new("https://www.google.com/search?q='cat%3Cdev/zero%3E/dev/null'")
90
- expect(source.to_input_for_command).to eq "\"https://www.google.com/search?q='cat%3Cdev/zero%3E/dev/null'\""
84
+ source = PDFKit::Source.new("https://www.google.com/search?q=foo%20bar")
85
+ expect(source.to_input_for_command).to eq "https://www.google.com/search?q=foo%20bar"
91
86
  end
92
87
 
93
88
  it "returns a '-' for HTML strings to indicate that we send that content through STDIN" do
data/spec/spec_helper.rb CHANGED
@@ -21,3 +21,13 @@ require 'custom_wkhtmltopdf_path' if File.exist?(File.join(SPEC_ROOT, 'custom_wk
21
21
  RSpec.configure do |config|
22
22
  include Rack::Test::Methods
23
23
  end
24
+
25
+ RSpec::Matchers.define :contain do |expected|
26
+ match do |actual|
27
+ (0..(actual.length - expected.length)).any? do |base_index|
28
+ expected.each_with_index.all? do |expected_element,index|
29
+ actual[base_index+index] == expected_element
30
+ end
31
+ end
32
+ end
33
+ 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.7
4
+ version: 0.8.7.2
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: 2022-10-02 00:00:00.000000000 Z
12
+ date: 2022-10-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport