Skip to content

Commit 349deb8

Browse files
authored
Merge pull request #182 from ruby-docx/fix-127-nil-guards
Guard against nil crashes on malformed documents (#127)
2 parents 56bec8b + 38d3f0e commit 349deb8

5 files changed

Lines changed: 35 additions & 3 deletions

File tree

lib/docx/containers/paragraph.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ def font_size
140140

141141
def font_color
142142
color_tag = @node.xpath('w:r//w:rPr//w:color').first
143-
color_tag ? color_tag.attributes['val'].value : nil
143+
color_tag ? color_tag.attributes['val']&.value : nil
144144
end
145145

146146
def style

lib/docx/document.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,11 @@ def font_size
104104
# Hyperlink targets are extracted from the document.xml.rels file
105105
def hyperlinks
106106
hyperlink_relationships.each_with_object({}) do |rel, hash|
107-
hash[rel.attributes['Id'].value] = rel.attributes['Target'].value
107+
id = rel.attributes['Id']
108+
target = rel.attributes['Target']
109+
next unless id && target
110+
111+
hash[id.value] = target.value
108112
end
109113
end
110114

@@ -184,7 +188,7 @@ def replace_entry(entry_path, file_contents)
184188
end
185189

186190
def default_paragraph_style
187-
@styles.at_xpath("w:styles/w:style[@w:type='paragraph' and @w:default='1']/w:name/@w:val").value
191+
@styles&.at_xpath("w:styles/w:style[@w:type='paragraph' and @w:default='1']/w:name/@w:val")&.value
188192
end
189193

190194
def style_name_of(style_id)

spec/docx/document_spec.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,34 @@
680680
end
681681
end
682682

683+
# Regression tests for #127: malformed documents should not crash with
684+
# internal "undefined method 'value' for nil" errors.
685+
describe 'robustness against malformed documents' do
686+
it 'ignores hyperlink relationships missing an Id or Target' do
687+
doc = Docx::Document.open(@fixtures_path + '/malformed_hyperlink_rels.docx')
688+
expect { doc.hyperlinks }.to_not raise_error
689+
# the well-formed relationships are still returned; the malformed one is skipped
690+
expect(doc.hyperlinks).to be_a(Hash)
691+
end
692+
693+
it 'returns nil for default_paragraph_style when there is no default paragraph style' do
694+
doc = Docx::Document.open(@fixtures_path + '/no_default_paragraph_style.docx')
695+
expect { doc.default_paragraph_style }.to_not raise_error
696+
expect(doc.default_paragraph_style).to be_nil
697+
end
698+
699+
it 'returns nil for a paragraph font_color when the color tag has no value' do
700+
node = Nokogiri::XML(<<~XML).root
701+
<w:p xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
702+
<w:r><w:rPr><w:color/></w:rPr><w:t>x</w:t></w:r>
703+
</w:p>
704+
XML
705+
paragraph = Docx::Elements::Containers::Paragraph.new(node)
706+
expect { paragraph.font_color }.to_not raise_error
707+
expect(paragraph.font_color).to be_nil
708+
end
709+
end
710+
683711
describe 'replacing contents' do
684712
let(:replacement_file_path) { @fixtures_path + '/replacement.png' }
685713
let(:temp_file_path) { Tempfile.new(['docx_gem', '.docx']).path }
13.4 KB
Binary file not shown.
13.4 KB
Binary file not shown.

0 commit comments

Comments
 (0)