pdfkit 0.8.7.1 → 0.8.7.3

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: 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