pdfkit 0.8.7.1 → 0.8.7.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dd9ab1711dcc1f5dc4c9ec2b0f5a203394cc8276291f34bd59230dd832c6b51c
4
- data.tar.gz: 0ec141cfe484aea9ae00488c34da32573f8f84d7ae3a5a3d5c954a0d4acfbee5
3
+ metadata.gz: d5a276883efaa6bba1349d1077bee9ed23e466e48006d7b87a8e6c6ffbbd83bb
4
+ data.tar.gz: 33632dc0ae3a917efe7a4d227ea3f1ef52a2901f125b5102f687d8058c32a135
5
5
  SHA512:
6
- metadata.gz: d8cf1754028c05b1dab1f382c91b86672a8a2808bbabbe66132fdb78501a731b1a651b5d276c0818efba1b537a685d2f55cb2a281935edf8c7b5b58c3aed1f1a
7
- data.tar.gz: 93f26e92cc31dd7f4fdaf1d5a20c2b2c5463d66588bc465bfacbfa4aecbbbe19662b1e605c1ac69593e1974fc0d606ff92298cfdace4c55313d977b87d128fc4
6
+ metadata.gz: 8694cd8411e17b0a960a5a931f84960031a935bfdb2f6fc43b6b460c8434644694e0b8dd764fb151cb722b947c9775c9540bd2b5935a0bbb5021705bbe7f8b52
7
+ data.tar.gz: 55fdc04026f173baa10fc1f349323b243f6ef9d17142a9ab196cdc4302c2444e7a72dcf1ba68c31c3a953ab1559add63c257a1c5c1012e9a3216765ae386457e
@@ -43,6 +43,18 @@ jobs:
43
43
  steps:
44
44
  - uses: actions/checkout@v2
45
45
  - uses: ruby/setup-ruby@v1
46
+ # rubygems-update's latest is no longer compatible with ruby 2.5, so conditionally run ruby-setup setting the
47
+ # rubygem version the most recent valid version for 2.5:
48
+ # https://rubygems.org/gems/rubygems-update/versions/3.3.26
49
+ if: ${{ matrix.ruby == '2.5' }}
50
+ with:
51
+ ruby-version: ${{ matrix.ruby }}
52
+ rubygems: 3.3.26
53
+ bundler: latest
54
+ bundler-cache: true
55
+ - uses: ruby/setup-ruby@v1
56
+ # otherwise, we can use rubygems latest
57
+ if: ${{ matrix.ruby != '2.5' }}
46
58
  with:
47
59
  ruby-version: ${{ matrix.ruby }}
48
60
  rubygems: latest
data/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ 2023-02-27
2
+ =================
3
+ * Bump to 0.8.7.3
4
+ * Allow passing a `Pathname` object to the `path` argument by @yujideveloper in https://github.com/pdfkit/pdfkit/pull/522
5
+ * Update repeatable options by @mguidetti in https://github.com/pdfkit/pdfkit/pull/524
6
+
7
+ 2022-10-18
8
+ =================
9
+ * Bump to 0.8.7.2
10
+ * Call IO.popen with an Array of command arguments (#519)
11
+
1
12
  2022-10-17
2
13
  =================
3
14
  * Bump to 0.8.7.1
@@ -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?
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.to_s : '-')
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.1'
4
+ VERSION = '0.8.7.3'
5
5
  end
@@ -3,9 +3,9 @@
3
3
  class PDFKit
4
4
  class WkHTMLtoPDF
5
5
  attr_reader :options
6
- # Pulled from:
7
- # https://github.com/wkhtmltopdf/wkhtmltopdf/blob/ebf9b6cfc4c58a31349fb94c568b254fac37b3d3/README_WKHTMLTOIMAGE#L27
8
- REPEATABLE_OPTIONS = %w[--allow --cookie --custom-header --post --post-file --run-script].freeze
6
+ # Pulled from:
7
+ # https://github.com/wkhtmltopdf/wkhtmltopdf/blob/6a57c1449797d6cb915921fb747f3ac36199241f/docs/usage/wkhtmltopdf.txt#L104
8
+ REPEATABLE_OPTIONS = %w[--allow --bypass-proxy-for --cookie --custom-header --post --post-file --run-script --replace].freeze
9
9
  SPECIAL_OPTIONS = %w[cover toc].freeze
10
10
 
11
11
  def initialize(options)
@@ -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
 
data/spec/pdfkit_spec.rb CHANGED
@@ -45,8 +45,8 @@ describe PDFKit do
45
45
  end
46
46
 
47
47
  it "transforms complex keys into command-line arguments" do
48
- pdfkit = PDFKit.new('html', :replace => {'value' => 'something else'} )
49
- expect(pdfkit.options).to have_key('--replace')
48
+ pdfkit = PDFKit.new('html', :header_left => {'value' => 'something else'} )
49
+ expect(pdfkit.options).to have_key('--header-left')
50
50
  end
51
51
 
52
52
  it "drops options with false or falsey values" do
@@ -72,8 +72,8 @@ describe PDFKit do
72
72
  end
73
73
 
74
74
  it "parses hash option values into an array" do
75
- pdfkit = PDFKit.new('html', :replace => {'value' => 'something else'} )
76
- expect(pdfkit.options['--replace']).to eql ['value', 'something else']
75
+ pdfkit = PDFKit.new('html', :header_left => {'value' => 'something else'} )
76
+ expect(pdfkit.options['--header-left']).to eql ['value', 'something else']
77
77
  end
78
78
 
79
79
  it "flattens hash options into the key" do
@@ -84,8 +84,8 @@ describe PDFKit do
84
84
  end
85
85
 
86
86
  it "parses array option values into a string" do
87
- pdfkit = PDFKit.new('html', :replace => ['value', 'something else'] )
88
- expect(pdfkit.options['--replace']).to eql ['value', 'something else']
87
+ pdfkit = PDFKit.new('html', :header_left => ['value', 'something else'] )
88
+ expect(pdfkit.options['--header-left']).to eql ['value', 'something else']
89
89
  end
90
90
 
91
91
  it "flattens array options" do
@@ -175,22 +175,36 @@ 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
+ end
183
+
184
+ it "contains a specified by path argument" do
185
+ pdfkit = PDFKit.new('html')
186
+ command = pdfkit.command("/foo/bar")
187
+ expect(command.first).to match(/wkhtmltopdf/)
188
+ expect(command.last).to eq("/foo/bar")
189
+ end
190
+
191
+ it "contains a specified by path argument of Pathname" do
192
+ pdfkit = PDFKit.new('html')
193
+ command = pdfkit.command(Pathname.new("/foo/bar"))
194
+ expect(command.first).to match(/wkhtmltopdf/)
195
+ expect(command.last).to eq("/foo/bar")
182
196
  end
183
197
 
184
198
  it "sets up one cookie when hash has only one cookie" do
185
199
  pdfkit = PDFKit.new('html', cookie: {cookie_name: :cookie_value})
186
200
  command = pdfkit.command
187
- expect(command).to include "--cookie cookie_name cookie_value"
201
+ expect(command).to contain %w[--cookie cookie_name cookie_value]
188
202
  end
189
203
 
190
- it "does not break Windows paths" do
204
+ it "does not split Windows paths that contain spaces" do
191
205
  pdfkit = PDFKit.new('html')
192
206
  allow(PDFKit.configuration).to receive(:wkhtmltopdf).and_return 'c:/Program Files/wkhtmltopdf/wkhtmltopdf.exe'
193
- expect(pdfkit.command).not_to include('Program\ Files')
207
+ expect(pdfkit.command).not_to contain(%w[c:/Program Files/wkhtmltopdf/wkhtmltopdf.exe])
194
208
  end
195
209
 
196
210
  it "does not shell escape source URLs" do
@@ -207,15 +221,15 @@ describe PDFKit do
207
221
  it "sets up multiple cookies when passed multiple cookies" do
208
222
  pdfkit = PDFKit.new('html', :cookie => {:cookie_name1 => :cookie_val1, :cookie_name2 => :cookie_val2})
209
223
  command = pdfkit.command
210
- expect(command).to include "--cookie cookie_name1 cookie_val1"
211
- expect(command).to include "--cookie cookie_name2 cookie_val2"
224
+ expect(command).to contain %w[--cookie cookie_name1 cookie_val1]
225
+ expect(command).to contain %w[--cookie cookie_name2 cookie_val2]
212
226
  end
213
227
 
214
228
  it "sets up multiple cookies when passed an array of tuples" do
215
229
  pdfkit = PDFKit.new('html', :cookie => [[:cookie_name1, :cookie_val1], [:cookie_name2, :cookie_val2]])
216
230
  command = pdfkit.command
217
- expect(command).to include "--cookie cookie_name1 cookie_val1"
218
- expect(command).to include "--cookie cookie_name2 cookie_val2"
231
+ expect(command).to contain %w[--cookie cookie_name1 cookie_val1]
232
+ expect(command).to contain %w[--cookie cookie_name2 cookie_val2]
219
233
  end
220
234
 
221
235
  it "will not include default options it is told to omit" do
@@ -229,48 +243,57 @@ describe PDFKit do
229
243
  expect(pdfkit.command).not_to include('--disable-smart-shrinking')
230
244
  end
231
245
 
232
- it "encapsulates string arguments in quotes" do
246
+ it "must not split string arguments containing spaces" do
233
247
  pdfkit = PDFKit.new('html', :header_center => "foo [page]")
234
- expect(pdfkit.command).to include "--header-center foo\\ \\[page\\]"
248
+ expect(pdfkit.command).to contain ['--header-center', 'foo [page]']
235
249
  end
236
250
 
237
- it "sanitizes string arguments" do
251
+ it "paramatarizes string arguments" do
238
252
  pdfkit = PDFKit.new('html', :header_center => "$(ls)")
239
- expect(pdfkit.command).to include "--header-center \\$\\(ls\\)"
253
+ expect(pdfkit.command).to contain %w[--header-center $(ls)]
240
254
  end
241
255
 
242
256
  it "read the source from stdin if it is html" do
243
257
  pdfkit = PDFKit.new('html')
244
- expect(pdfkit.command).to match(/- -$/)
258
+ command = pdfkit.command
259
+ expect(command[-2]).to eq('-')
260
+ expect(command[-1]).to eq('-')
245
261
  end
246
262
 
247
263
  it "specifies the URL to the source if it is a url" do
248
264
  pdfkit = PDFKit.new('http://google.com')
249
- expect(pdfkit.command).to match(/"http:\/\/google.com" -$/)
265
+ command = pdfkit.command
266
+ expect(command[-2]).to eq("http://google.com")
267
+ expect(command[-1]).to eq("-")
250
268
  end
251
269
 
252
270
  it "does not break Windows paths" do
253
271
  pdfkit = PDFKit.new('html')
254
272
  allow(PDFKit.configuration).to receive(:wkhtmltopdf).and_return 'c:/Program Files/wkhtmltopdf/wkhtmltopdf.exe'
255
- expect(pdfkit.command).not_to include('Program\ Files')
273
+ expect(pdfkit.command).not_to contain ['Program', 'Files']
256
274
  end
257
275
 
258
276
  it "specifies the path to the source if it is a file" do
259
277
  file_path = File.join(SPEC_ROOT,'fixtures','example.html')
260
278
  pdfkit = PDFKit.new(File.new(file_path))
261
- expect(pdfkit.command).to match(/#{file_path} -$/)
279
+ command = pdfkit.command
280
+ expect(command[-2]).to eq(file_path)
281
+ expect(command[-1]).to eq('-')
262
282
  end
263
283
 
264
284
  it "specifies the path to the source if it is a tempfile" do
265
285
  file_path = File.join(SPEC_ROOT,'fixtures','example.html')
266
286
  pdfkit = PDFKit.new(Tempfile.new(file_path))
267
- expect(pdfkit.command).to match(/#{Dir.tmpdir}\S+ -$/)
287
+ command = pdfkit.command
288
+ expect(command[-2]).to start_with(Dir.tmpdir)
289
+ expect(command[-1]).to eq('-')
268
290
  end
269
291
 
270
292
  it "specifies the path for the ouput if a path is given" do
271
293
  file_path = "/path/to/output.pdf"
272
294
  pdfkit = PDFKit.new("html")
273
- expect(pdfkit.command(file_path)).to match(/#{file_path}$/)
295
+ command = pdfkit.command(file_path)
296
+ expect(command.last).to eq(file_path)
274
297
  end
275
298
 
276
299
  it "detects special pdfkit meta tags" do
@@ -284,8 +307,8 @@ describe PDFKit do
284
307
  }
285
308
  pdfkit = PDFKit.new(body)
286
309
  command = pdfkit.command
287
- expect(command).to include "--page-size Legal"
288
- expect(command).to include "--orientation Landscape"
310
+ expect(command).to contain %w[--page-size Legal]
311
+ expect(command).to contain %w[--orientation Landscape]
289
312
  end
290
313
 
291
314
  it "detects cookies meta tag" do
@@ -299,7 +322,7 @@ describe PDFKit do
299
322
  }
300
323
  pdfkit = PDFKit.new(body)
301
324
  command = pdfkit.command
302
- expect(command).to include "--cookie rails_session rails_session_value --cookie cookie_variable cookie_variable_value"
325
+ expect(command).to contain %w[--cookie rails_session rails_session_value --cookie cookie_variable cookie_variable_value]
303
326
  end
304
327
 
305
328
  it "detects disable_smart_shrinking meta tag" do
@@ -313,7 +336,7 @@ describe PDFKit do
313
336
  pdfkit = PDFKit.new(body)
314
337
  command = pdfkit.command
315
338
  expect(command).to include "--disable-smart-shrinking"
316
- expect(command).not_to include "--disable-smart-shrinking true"
339
+ expect(command).not_to contain %w[--disable-smart-shrinking true]
317
340
  end
318
341
 
319
342
  it "detects names with hyphens instead of underscores" do
@@ -342,8 +365,8 @@ describe PDFKit do
342
365
  }
343
366
  pdfkit = PDFKit.new(body)
344
367
  command = pdfkit.command
345
- expect(command).to include "--page-size Legal"
346
- expect(command).to include "--orientation Landscape"
368
+ expect(command).to contain %w[--page-size Legal]
369
+ expect(command).to contain %w[--orientation Landscape]
347
370
  end
348
371
 
349
372
  it "skips non-pdfkit meta tags" do
@@ -358,8 +381,8 @@ describe PDFKit do
358
381
  }
359
382
  pdfkit = PDFKit.new(body)
360
383
  command = pdfkit.command
361
- expect(command).not_to include "--page-size Legal"
362
- expect(command).to include "--orientation Landscape"
384
+ expect(command).not_to contain %w[--page-size Legal]
385
+ expect(command).to contain %w[--orientation Landscape]
363
386
  end
364
387
 
365
388
  it "does not use quiet when told to" do
@@ -422,14 +445,9 @@ describe PDFKit do
422
445
  allow(PDFKit::OS).to receive(:host_is_windows?).and_return(true)
423
446
  end
424
447
 
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
448
  it "quotes spaces in options" do
431
449
  pdf = PDFKit.new('html', :title => 'hello world')
432
- expect(pdf.command).to include "--title 'hello world'"
450
+ expect(pdf.command).to contain ['--title', "hello world"]
433
451
  end
434
452
  end
435
453
  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.1
4
+ version: 0.8.7.3
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-17 00:00:00.000000000 Z
12
+ date: 2023-05-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport