Fix entity encoding of attribute values
This ensures that single and double quotes are also encoded, previously they would be left as is. Fixes #113
This commit is contained in:
parent
e0837fd44e
commit
074b53c18c
|
@ -101,7 +101,11 @@ module Oga
|
||||||
full_name = name
|
full_name = name
|
||||||
end
|
end
|
||||||
|
|
||||||
enc_value = value ? Entities.encode(value) : nil
|
if value
|
||||||
|
enc_value = Entities.encode_attribute(value)
|
||||||
|
else
|
||||||
|
enc_value = nil
|
||||||
|
end
|
||||||
|
|
||||||
%Q(#{full_name}="#{enc_value}")
|
%Q(#{full_name}="#{enc_value}")
|
||||||
end
|
end
|
||||||
|
|
|
@ -32,6 +32,20 @@ module Oga
|
||||||
'<' => '<',
|
'<' => '<',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
##
|
||||||
|
# Hash containing characters and the corresponding XML entities to use
|
||||||
|
# when encoding XML/HTML attribute values.
|
||||||
|
#
|
||||||
|
# @return [Hash]
|
||||||
|
#
|
||||||
|
ENCODE_ATTRIBUTE_MAPPING = {
|
||||||
|
'&' => '&',
|
||||||
|
'>' => '>',
|
||||||
|
'<' => '<',
|
||||||
|
"'" => ''',
|
||||||
|
'"' => '"'
|
||||||
|
}
|
||||||
|
|
||||||
##
|
##
|
||||||
# @return [String]
|
# @return [String]
|
||||||
#
|
#
|
||||||
|
@ -56,6 +70,12 @@ module Oga
|
||||||
#
|
#
|
||||||
ENCODE_REGEXP = Regexp.new(ENCODE_MAPPING.keys.join('|'))
|
ENCODE_REGEXP = Regexp.new(ENCODE_MAPPING.keys.join('|'))
|
||||||
|
|
||||||
|
##
|
||||||
|
# @return [Regexp]
|
||||||
|
#
|
||||||
|
ENCODE_ATTRIBUTE_REGEXP =
|
||||||
|
Regexp.new(ENCODE_ATTRIBUTE_MAPPING.keys.join('|'))
|
||||||
|
|
||||||
##
|
##
|
||||||
# Decodes XML entities.
|
# Decodes XML entities.
|
||||||
#
|
#
|
||||||
|
@ -87,6 +107,16 @@ module Oga
|
||||||
def self.encode(input, mapping = ENCODE_MAPPING)
|
def self.encode(input, mapping = ENCODE_MAPPING)
|
||||||
input.gsub(ENCODE_REGEXP, mapping)
|
input.gsub(ENCODE_REGEXP, mapping)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Encodes special characters in an XML attribute value.
|
||||||
|
#
|
||||||
|
# @param [String] input
|
||||||
|
# @return [String]
|
||||||
|
#
|
||||||
|
def self.encode_attribute(input)
|
||||||
|
input.gsub(ENCODE_ATTRIBUTE_REGEXP, ENCODE_ATTRIBUTE_MAPPING)
|
||||||
|
end
|
||||||
end # Entities
|
end # Entities
|
||||||
end # XML
|
end # XML
|
||||||
end # Oga
|
end # Oga
|
||||||
|
|
|
@ -139,10 +139,10 @@ describe Oga::XML::Attribute do
|
||||||
attr.to_xml.should == 'xmlns:class=""'
|
attr.to_xml.should == 'xmlns:class=""'
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'converts special characters to XML entities' do
|
it 'decodes XML entities' do
|
||||||
attr = described_class.new(:name => 'href', :value => '&<>')
|
attr = described_class.new(:name => 'href', :value => %q{&<>'"})
|
||||||
|
|
||||||
attr.to_xml.should == 'href="&<>"'
|
attr.to_xml.should == 'href="&<>'""'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -104,4 +104,26 @@ describe Oga::XML::Entities do
|
||||||
described_class.encode('<').should == '&lt;'
|
described_class.encode('<').should == '&lt;'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'encode_attribute' do
|
||||||
|
it 'encodes & as &' do
|
||||||
|
described_class.encode_attribute('&').should == '&'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'encodes > as >' do
|
||||||
|
described_class.encode_attribute('>').should == '>'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'encodes < as >' do
|
||||||
|
described_class.encode_attribute('<').should == '<'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'encodes a single quote as '' do
|
||||||
|
described_class.encode_attribute("'").should == '''
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'encodes a double quote as "' do
|
||||||
|
described_class.encode_attribute('"').should == '"'
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue