rexml 3.2.5 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rexml might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/NEWS.md +204 -2
- data/README.md +10 -1
- data/doc/rexml/tasks/rdoc/element.rdoc +2 -2
- data/doc/rexml/tutorial.rdoc +1358 -0
- data/lib/rexml/attribute.rb +14 -9
- data/lib/rexml/document.rb +1 -1
- data/lib/rexml/element.rb +3 -3
- data/lib/rexml/entity.rb +25 -15
- data/lib/rexml/formatters/pretty.rb +2 -2
- data/lib/rexml/functions.rb +1 -2
- data/lib/rexml/namespace.rb +8 -4
- data/lib/rexml/node.rb +8 -4
- data/lib/rexml/parseexception.rb +1 -0
- data/lib/rexml/parsers/baseparser.rb +247 -229
- data/lib/rexml/parsers/xpathparser.rb +136 -86
- data/lib/rexml/rexml.rb +3 -1
- data/lib/rexml/source.rb +114 -100
- data/lib/rexml/text.rb +6 -4
- data/lib/rexml/xpath_parser.rb +7 -3
- metadata +12 -38
data/lib/rexml/attribute.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# frozen_string_literal:
|
1
|
+
# frozen_string_literal: true
|
2
2
|
require_relative "namespace"
|
3
3
|
require_relative 'text'
|
4
4
|
|
@@ -13,9 +13,6 @@ module REXML
|
|
13
13
|
|
14
14
|
# The element to which this attribute belongs
|
15
15
|
attr_reader :element
|
16
|
-
# The normalized value of this attribute. That is, the attribute with
|
17
|
-
# entities intact.
|
18
|
-
attr_writer :normalized
|
19
16
|
PATTERN = /\s*(#{NAME_STR})\s*=\s*(["'])(.*?)\2/um
|
20
17
|
|
21
18
|
NEEDS_A_SECOND_CHECK = /(<|&((#{Entity::NAME});|(#0*((?:\d+)|(?:x[a-fA-F0-9]+)));)?)/um
|
@@ -122,10 +119,13 @@ module REXML
|
|
122
119
|
# b = Attribute.new( "ns:x", "y" )
|
123
120
|
# b.to_string # -> "ns:x='y'"
|
124
121
|
def to_string
|
122
|
+
value = to_s
|
125
123
|
if @element and @element.context and @element.context[:attribute_quote] == :quote
|
126
|
-
|
124
|
+
value = value.gsub('"', '"') if value.include?('"')
|
125
|
+
%Q^#@expanded_name="#{value}"^
|
127
126
|
else
|
128
|
-
|
127
|
+
value = value.gsub("'", ''') if value.include?("'")
|
128
|
+
"#@expanded_name='#{value}'"
|
129
129
|
end
|
130
130
|
end
|
131
131
|
|
@@ -141,7 +141,6 @@ module REXML
|
|
141
141
|
return @normalized if @normalized
|
142
142
|
|
143
143
|
@normalized = Text::normalize( @unnormalized, doctype )
|
144
|
-
@unnormalized = nil
|
145
144
|
@normalized
|
146
145
|
end
|
147
146
|
|
@@ -150,10 +149,16 @@ module REXML
|
|
150
149
|
def value
|
151
150
|
return @unnormalized if @unnormalized
|
152
151
|
@unnormalized = Text::unnormalize( @normalized, doctype )
|
153
|
-
@normalized = nil
|
154
152
|
@unnormalized
|
155
153
|
end
|
156
154
|
|
155
|
+
# The normalized value of this attribute. That is, the attribute with
|
156
|
+
# entities intact.
|
157
|
+
def normalized=(new_normalized)
|
158
|
+
@normalized = new_normalized
|
159
|
+
@unnormalized = nil
|
160
|
+
end
|
161
|
+
|
157
162
|
# Returns a copy of this attribute
|
158
163
|
def clone
|
159
164
|
Attribute.new self
|
@@ -190,7 +195,7 @@ module REXML
|
|
190
195
|
end
|
191
196
|
|
192
197
|
def inspect
|
193
|
-
rv = ""
|
198
|
+
rv = +""
|
194
199
|
write( rv )
|
195
200
|
rv
|
196
201
|
end
|
data/lib/rexml/document.rb
CHANGED
@@ -69,7 +69,7 @@ module REXML
|
|
69
69
|
# d.to_s # => "<root><foo>Foo</foo><bar>Bar</bar></root>"
|
70
70
|
#
|
71
71
|
# When argument +document+ is given, it must be an existing
|
72
|
-
# document object, whose context and attributes (but not
|
72
|
+
# document object, whose context and attributes (but not children)
|
73
73
|
# are cloned into the new document:
|
74
74
|
#
|
75
75
|
# d = REXML::Document.new(xml_string)
|
data/lib/rexml/element.rb
CHANGED
@@ -989,7 +989,7 @@ module REXML
|
|
989
989
|
# :call-seq:
|
990
990
|
# has_text? -> true or false
|
991
991
|
#
|
992
|
-
# Returns +true if the element has one or more text noded,
|
992
|
+
# Returns +true+ if the element has one or more text noded,
|
993
993
|
# +false+ otherwise:
|
994
994
|
#
|
995
995
|
# d = REXML::Document.new '<a><b/>text<c/></a>'
|
@@ -1006,7 +1006,7 @@ module REXML
|
|
1006
1006
|
# text(xpath = nil) -> text_string or nil
|
1007
1007
|
#
|
1008
1008
|
# Returns the text string from the first text node child
|
1009
|
-
# in a specified element, if it exists,
|
1009
|
+
# in a specified element, if it exists, +nil+ otherwise.
|
1010
1010
|
#
|
1011
1011
|
# With no argument, returns the text from the first text node in +self+:
|
1012
1012
|
#
|
@@ -1014,7 +1014,7 @@ module REXML
|
|
1014
1014
|
# d.root.text.class # => String
|
1015
1015
|
# d.root.text # => "some text "
|
1016
1016
|
#
|
1017
|
-
# With argument +xpath+, returns text from the
|
1017
|
+
# With argument +xpath+, returns text from the first text node
|
1018
1018
|
# in the element that matches +xpath+:
|
1019
1019
|
#
|
1020
1020
|
# d.root.text(1) # => "this is bold!"
|
data/lib/rexml/entity.rb
CHANGED
@@ -132,24 +132,34 @@ module REXML
|
|
132
132
|
# then:
|
133
133
|
# doctype.entity('yada').value #-> "nanoo bar nanoo"
|
134
134
|
def value
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
135
|
+
@resolved_value ||= resolve_value
|
136
|
+
end
|
137
|
+
|
138
|
+
def parent=(other)
|
139
|
+
@resolved_value = nil
|
140
|
+
super
|
141
|
+
end
|
142
|
+
|
143
|
+
private
|
144
|
+
def resolve_value
|
145
|
+
return nil if @value.nil?
|
146
|
+
return @value unless @value.match?(PEREFERENCE_RE)
|
147
|
+
|
148
|
+
matches = @value.scan(PEREFERENCE_RE)
|
149
|
+
rv = @value.clone
|
150
|
+
if @parent
|
151
|
+
sum = 0
|
152
|
+
matches.each do |entity_reference|
|
153
|
+
entity_value = @parent.entity( entity_reference[0] )
|
154
|
+
if sum + entity_value.bytesize > Security.entity_expansion_text_limit
|
155
|
+
raise "entity expansion has grown too large"
|
156
|
+
else
|
157
|
+
sum += entity_value.bytesize
|
148
158
|
end
|
159
|
+
rv.gsub!( /%#{entity_reference.join};/um, entity_value )
|
149
160
|
end
|
150
|
-
return rv
|
151
161
|
end
|
152
|
-
|
162
|
+
rv
|
153
163
|
end
|
154
164
|
end
|
155
165
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# frozen_string_literal:
|
1
|
+
# frozen_string_literal: true
|
2
2
|
require_relative 'default'
|
3
3
|
|
4
4
|
module REXML
|
@@ -58,7 +58,7 @@ module REXML
|
|
58
58
|
skip = false
|
59
59
|
if compact
|
60
60
|
if node.children.inject(true) {|s,c| s & c.kind_of?(Text)}
|
61
|
-
string = ""
|
61
|
+
string = +""
|
62
62
|
old_level = @level
|
63
63
|
@level = 0
|
64
64
|
node.children.each { |child| write( child, string ) }
|
data/lib/rexml/functions.rb
CHANGED
@@ -262,11 +262,10 @@ module REXML
|
|
262
262
|
string(string).length
|
263
263
|
end
|
264
264
|
|
265
|
-
# UNTESTED
|
266
265
|
def Functions::normalize_space( string=nil )
|
267
266
|
string = string(@@context[:node]) if string.nil?
|
268
267
|
if string.kind_of? Array
|
269
|
-
string.collect{|x|
|
268
|
+
string.collect{|x| x.to_s.strip.gsub(/\s+/um, ' ') if x}
|
270
269
|
else
|
271
270
|
string.to_s.strip.gsub(/\s+/um, ' ')
|
272
271
|
end
|
data/lib/rexml/namespace.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# frozen_string_literal:
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'xmltokens'
|
4
4
|
|
@@ -10,13 +10,17 @@ module REXML
|
|
10
10
|
# The expanded name of the object, valid if name is set
|
11
11
|
attr_accessor :prefix
|
12
12
|
include XMLTokens
|
13
|
+
NAME_WITHOUT_NAMESPACE = /\A#{NCNAME_STR}\z/
|
13
14
|
NAMESPLIT = /^(?:(#{NCNAME_STR}):)?(#{NCNAME_STR})/u
|
14
15
|
|
15
16
|
# Sets the name and the expanded name
|
16
17
|
def name=( name )
|
17
18
|
@expanded_name = name
|
18
|
-
|
19
|
-
|
19
|
+
if name.match?(NAME_WITHOUT_NAMESPACE)
|
20
|
+
@prefix = ""
|
21
|
+
@namespace = ""
|
22
|
+
@name = name
|
23
|
+
elsif name =~ NAMESPLIT
|
20
24
|
if $1
|
21
25
|
@prefix = $1
|
22
26
|
else
|
@@ -24,7 +28,7 @@ module REXML
|
|
24
28
|
@namespace = ""
|
25
29
|
end
|
26
30
|
@name = $2
|
27
|
-
|
31
|
+
elsif name == ""
|
28
32
|
@prefix = nil
|
29
33
|
@namespace = nil
|
30
34
|
@name = nil
|
data/lib/rexml/node.rb
CHANGED
@@ -52,10 +52,14 @@ module REXML
|
|
52
52
|
|
53
53
|
# Visit all subnodes of +self+ recursively
|
54
54
|
def each_recursive(&block) # :yields: node
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
55
|
+
stack = []
|
56
|
+
each { |child| stack.unshift child if child.node_type == :element }
|
57
|
+
until stack.empty?
|
58
|
+
child = stack.pop
|
59
|
+
yield child
|
60
|
+
n = stack.size
|
61
|
+
child.each { |grandchild| stack.insert n, grandchild if grandchild.node_type == :element }
|
62
|
+
end
|
59
63
|
end
|
60
64
|
|
61
65
|
# Find (and return) first subnode (recursively) for which the block
|
data/lib/rexml/parseexception.rb
CHANGED