rexml 3.2.4 → 3.2.6

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.

@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: false
2
+
2
3
  require_relative '../namespace'
3
4
  require_relative '../xmltokens'
4
5
 
@@ -22,7 +23,13 @@ module REXML
22
23
  path.gsub!(/([\(\[])\s+/, '\1') # Strip ignorable spaces
23
24
  path.gsub!( /\s+([\]\)])/, '\1')
24
25
  parsed = []
25
- OrExpr(path, parsed)
26
+ rest = OrExpr(path, parsed)
27
+ if rest
28
+ unless rest.strip.empty?
29
+ raise ParseException.new("Garbage component exists at the end: " +
30
+ "<#{rest}>: <#{path}>")
31
+ end
32
+ end
26
33
  parsed
27
34
  end
28
35
 
@@ -32,108 +39,143 @@ module REXML
32
39
  parsed
33
40
  end
34
41
 
35
- def abbreviate( path )
36
- path = path.kind_of?(String) ? parse( path ) : path
37
- string = ""
38
- document = false
39
- while path.size > 0
40
- op = path.shift
42
+ def abbreviate(path_or_parsed)
43
+ if path_or_parsed.kind_of?(String)
44
+ parsed = parse(path_or_parsed)
45
+ else
46
+ parsed = path_or_parsed
47
+ end
48
+ components = []
49
+ component = nil
50
+ while parsed.size > 0
51
+ op = parsed.shift
41
52
  case op
42
53
  when :node
54
+ component << "node()"
43
55
  when :attribute
44
- string << "/" if string.size > 0
45
- string << "@"
56
+ component = "@"
57
+ components << component
46
58
  when :child
47
- string << "/" if string.size > 0
59
+ component = ""
60
+ components << component
48
61
  when :descendant_or_self
49
- string << "/"
62
+ next_op = parsed[0]
63
+ if next_op == :node
64
+ parsed.shift
65
+ component = ""
66
+ components << component
67
+ else
68
+ component = "descendant-or-self::"
69
+ components << component
70
+ end
50
71
  when :self
51
- string << "."
72
+ next_op = parsed[0]
73
+ if next_op == :node
74
+ parsed.shift
75
+ components << "."
76
+ else
77
+ component = "self::"
78
+ components << component
79
+ end
52
80
  when :parent
53
- string << ".."
81
+ next_op = parsed[0]
82
+ if next_op == :node
83
+ parsed.shift
84
+ components << ".."
85
+ else
86
+ component = "parent::"
87
+ components << component
88
+ end
54
89
  when :any
55
- string << "*"
90
+ component << "*"
56
91
  when :text
57
- string << "text()"
92
+ component << "text()"
58
93
  when :following, :following_sibling,
59
94
  :ancestor, :ancestor_or_self, :descendant,
60
95
  :namespace, :preceding, :preceding_sibling
61
- string << "/" unless string.size == 0
62
- string << op.to_s.tr("_", "-")
63
- string << "::"
96
+ component = op.to_s.tr("_", "-") << "::"
97
+ components << component
64
98
  when :qname
65
- prefix = path.shift
66
- name = path.shift
67
- string << prefix+":" if prefix.size > 0
68
- string << name
99
+ prefix = parsed.shift
100
+ name = parsed.shift
101
+ component << prefix+":" if prefix.size > 0
102
+ component << name
69
103
  when :predicate
70
- string << '['
71
- string << predicate_to_string( path.shift ) {|x| abbreviate( x ) }
72
- string << ']'
104
+ component << '['
105
+ component << predicate_to_path(parsed.shift) {|x| abbreviate(x)}
106
+ component << ']'
73
107
  when :document
74
- document = true
108
+ components << ""
75
109
  when :function
76
- string << path.shift
77
- string << "( "
78
- string << predicate_to_string( path.shift[0] ) {|x| abbreviate( x )}
79
- string << " )"
110
+ component << parsed.shift
111
+ component << "( "
112
+ component << predicate_to_path(parsed.shift[0]) {|x| abbreviate(x)}
113
+ component << " )"
80
114
  when :literal
81
- string << %Q{ "#{path.shift}" }
115
+ component << quote_literal(parsed.shift)
82
116
  else
83
- string << "/" unless string.size == 0
84
- string << "UNKNOWN("
85
- string << op.inspect
86
- string << ")"
117
+ component << "UNKNOWN("
118
+ component << op.inspect
119
+ component << ")"
87
120
  end
88
121
  end
89
- string = "/"+string if document
90
- return string
122
+ case components
123
+ when [""]
124
+ "/"
125
+ when ["", ""]
126
+ "//"
127
+ else
128
+ components.join("/")
129
+ end
91
130
  end
92
131
 
93
- def expand( path )
94
- path = path.kind_of?(String) ? parse( path ) : path
95
- string = ""
132
+ def expand(path_or_parsed)
133
+ if path_or_parsed.kind_of?(String)
134
+ parsed = parse(path_or_parsed)
135
+ else
136
+ parsed = path_or_parsed
137
+ end
138
+ path = ""
96
139
  document = false
97
- while path.size > 0
98
- op = path.shift
140
+ while parsed.size > 0
141
+ op = parsed.shift
99
142
  case op
100
143
  when :node
101
- string << "node()"
144
+ path << "node()"
102
145
  when :attribute, :child, :following, :following_sibling,
103
146
  :ancestor, :ancestor_or_self, :descendant, :descendant_or_self,
104
147
  :namespace, :preceding, :preceding_sibling, :self, :parent
105
- string << "/" unless string.size == 0
106
- string << op.to_s.tr("_", "-")
107
- string << "::"
148
+ path << "/" unless path.size == 0
149
+ path << op.to_s.tr("_", "-")
150
+ path << "::"
108
151
  when :any
109
- string << "*"
152
+ path << "*"
110
153
  when :qname
111
- prefix = path.shift
112
- name = path.shift
113
- string << prefix+":" if prefix.size > 0
114
- string << name
154
+ prefix = parsed.shift
155
+ name = parsed.shift
156
+ path << prefix+":" if prefix.size > 0
157
+ path << name
115
158
  when :predicate
116
- string << '['
117
- string << predicate_to_string( path.shift ) { |x| expand(x) }
118
- string << ']'
159
+ path << '['
160
+ path << predicate_to_path( parsed.shift ) { |x| expand(x) }
161
+ path << ']'
119
162
  when :document
120
163
  document = true
121
164
  else
122
- string << "/" unless string.size == 0
123
- string << "UNKNOWN("
124
- string << op.inspect
125
- string << ")"
165
+ path << "UNKNOWN("
166
+ path << op.inspect
167
+ path << ")"
126
168
  end
127
169
  end
128
- string = "/"+string if document
129
- return string
170
+ path = "/"+path if document
171
+ path
130
172
  end
131
173
 
132
- def predicate_to_string( path, &block )
133
- string = ""
134
- case path[0]
174
+ def predicate_to_path(parsed, &block)
175
+ path = ""
176
+ case parsed[0]
135
177
  when :and, :or, :mult, :plus, :minus, :neq, :eq, :lt, :gt, :lteq, :gteq, :div, :mod, :union
136
- op = path.shift
178
+ op = parsed.shift
137
179
  case op
138
180
  when :eq
139
181
  op = "="
@@ -150,36 +192,50 @@ module REXML
150
192
  when :union
151
193
  op = "|"
152
194
  end
153
- left = predicate_to_string( path.shift, &block )
154
- right = predicate_to_string( path.shift, &block )
155
- string << " "
156
- string << left
157
- string << " "
158
- string << op.to_s
159
- string << " "
160
- string << right
161
- string << " "
195
+ left = predicate_to_path( parsed.shift, &block )
196
+ right = predicate_to_path( parsed.shift, &block )
197
+ path << left
198
+ path << " "
199
+ path << op.to_s
200
+ path << " "
201
+ path << right
162
202
  when :function
163
- path.shift
164
- name = path.shift
165
- string << name
166
- string << "( "
167
- string << predicate_to_string( path.shift, &block )
168
- string << " )"
203
+ parsed.shift
204
+ name = parsed.shift
205
+ path << name
206
+ path << "("
207
+ parsed.shift.each_with_index do |argument, i|
208
+ path << ", " if i > 0
209
+ path << predicate_to_path(argument, &block)
210
+ end
211
+ path << ")"
169
212
  when :literal
170
- path.shift
171
- string << " "
172
- string << path.shift.inspect
173
- string << " "
213
+ parsed.shift
214
+ path << quote_literal(parsed.shift)
174
215
  else
175
- string << " "
176
- string << yield( path )
177
- string << " "
216
+ path << yield( parsed )
178
217
  end
179
- return string.squeeze(" ")
218
+ return path.squeeze(" ")
180
219
  end
220
+ # For backward compatibility
221
+ alias_method :preciate_to_string, :predicate_to_path
181
222
 
182
223
  private
224
+ def quote_literal( literal )
225
+ case literal
226
+ when String
227
+ # XPath 1.0 does not support escape characters.
228
+ # Assumes literal does not contain both single and double quotes.
229
+ if literal.include?("'")
230
+ "\"#{literal}\""
231
+ else
232
+ "'#{literal}'"
233
+ end
234
+ else
235
+ literal.inspect
236
+ end
237
+ end
238
+
183
239
  #LocationPath
184
240
  # | RelativeLocationPath
185
241
  # | '/' RelativeLocationPath?
@@ -229,24 +285,28 @@ module REXML
229
285
  path = path[1..-1]
230
286
  end
231
287
  else
288
+ path_before_axis_specifier = path
289
+ parsed_not_abberviated = []
232
290
  if path[0] == ?@
233
- parsed << :attribute
291
+ parsed_not_abberviated << :attribute
234
292
  path = path[1..-1]
235
293
  # Goto Nodetest
236
294
  elsif path =~ AXIS
237
- parsed << $1.tr('-','_').intern
295
+ parsed_not_abberviated << $1.tr('-','_').intern
238
296
  path = $'
239
297
  # Goto Nodetest
240
298
  else
241
- parsed << :child
299
+ parsed_not_abberviated << :child
242
300
  end
243
301
 
244
- n = []
245
- path = NodeTest( path, n)
246
-
247
- path = Predicate( path, n )
302
+ path_before_node_test = path
303
+ path = NodeTest(path, parsed_not_abberviated)
304
+ if path == path_before_node_test
305
+ return path_before_axis_specifier
306
+ end
307
+ path = Predicate(path, parsed_not_abberviated)
248
308
 
249
- parsed.concat(n)
309
+ parsed.concat(parsed_not_abberviated)
250
310
  end
251
311
 
252
312
  original_path = path
@@ -301,7 +361,9 @@ module REXML
301
361
  when PI
302
362
  path = $'
303
363
  literal = nil
304
- if path !~ /^\s*\)/
364
+ if path =~ /^\s*\)/
365
+ path = $'
366
+ else
305
367
  path =~ LITERAL
306
368
  literal = $1
307
369
  path = $'
@@ -545,7 +607,9 @@ module REXML
545
607
  #| PrimaryExpr
546
608
  def FilterExpr path, parsed
547
609
  n = []
548
- path = PrimaryExpr( path, n )
610
+ path_before_primary_expr = path
611
+ path = PrimaryExpr(path, n)
612
+ return path_before_primary_expr if path == path_before_primary_expr
549
613
  path = Predicate(path, n)
550
614
  parsed.concat(n)
551
615
  path
data/lib/rexml/rexml.rb CHANGED
@@ -1,30 +1,37 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # frozen_string_literal: false
3
- # REXML is an XML toolkit for Ruby[http://www.ruby-lang.org], in Ruby.
4
- #
5
- # REXML is a _pure_ Ruby, XML 1.0 conforming,
6
- # non-validating[http://www.w3.org/TR/2004/REC-xml-20040204/#sec-conformance]
7
- # toolkit with an intuitive API. REXML passes 100% of the non-validating Oasis
8
- # tests[http://www.oasis-open.org/committees/xml-conformance/xml-test-suite.shtml],
9
- # and provides tree, stream, SAX2, pull, and lightweight APIs. REXML also
10
- # includes a full XPath[http://www.w3c.org/tr/xpath] 1.0 implementation. Since
11
- # Ruby 1.8, REXML is included in the standard Ruby distribution.
12
- #
13
- # Main page:: http://www.germane-software.com/software/rexml
14
- # Author:: Sean Russell <serATgermaneHYPHENsoftwareDOTcom>
15
- # Date:: 2008/019
16
- # Version:: 3.1.7.3
17
- #
18
- # This API documentation can be downloaded from the REXML home page, or can
19
- # be accessed online[http://www.germane-software.com/software/rexml_doc]
20
- #
21
- # A tutorial is available in the REXML distribution in docs/tutorial.html,
22
- # or can be accessed
23
- # online[http://www.germane-software.com/software/rexml/docs/tutorial.html]
3
+ #
4
+ # \Module \REXML provides classes and methods for parsing,
5
+ # editing, and generating XML.
6
+ #
7
+ # == Implementation
8
+ #
9
+ # \REXML:
10
+ # - Is pure Ruby.
11
+ # - Provides tree, stream, SAX2, pull, and lightweight APIs.
12
+ # - Conforms to {XML version 1.0}[https://www.w3.org/TR/REC-xml/].
13
+ # - Fully implements {XPath version 1.0}[http://www.w3c.org/tr/xpath].
14
+ # - Is {non-validating}[https://www.w3.org/TR/xml/].
15
+ # - Passes 100% of the non-validating {Oasis tests}[http://www.oasis-open.org/committees/xml-conformance/xml-test-suite.shtml].
16
+ #
17
+ # == In a Hurry?
18
+ #
19
+ # If you're somewhat familiar with XML
20
+ # and have a particular task in mind,
21
+ # you may want to see {the tasks pages}[doc/rexml/tasks/tocs/master_toc_rdoc.html].
22
+ #
23
+ # == API
24
+ #
25
+ # Among the most important classes for using \REXML are:
26
+ # - REXML::Document.
27
+ # - REXML::Element.
28
+ #
29
+ # There's also an {REXML tutorial}[doc/rexml/tutorial_rdoc.html].
30
+ #
24
31
  module REXML
25
32
  COPYRIGHT = "Copyright © 2001-2008 Sean Russell <ser@germane-software.com>"
26
33
  DATE = "2008/019"
27
- VERSION = "3.2.4"
34
+ VERSION = "3.2.6"
28
35
  REVISION = ""
29
36
 
30
37
  Copyright = COPYRIGHT
data/lib/rexml/text.rb CHANGED
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  require_relative 'security'
3
3
  require_relative 'entity'
4
4
  require_relative 'doctype'
@@ -131,7 +131,7 @@ module REXML
131
131
  def Text.check string, pattern, doctype
132
132
 
133
133
  # illegal anywhere
134
- if string !~ VALID_XML_CHARS
134
+ if !string.match?(VALID_XML_CHARS)
135
135
  if String.method_defined? :encode
136
136
  string.chars.each do |c|
137
137
  case c.ord
@@ -371,7 +371,7 @@ module REXML
371
371
  copy = input.to_s
372
372
  # Doing it like this rather than in a loop improves the speed
373
373
  #copy = copy.gsub( EREFERENCE, '&amp;' )
374
- copy = copy.gsub( "&", "&amp;" )
374
+ copy = copy.gsub( "&", "&amp;" ) if copy.include?("&")
375
375
  if doctype
376
376
  # Replace all ampersands that aren't part of an entity
377
377
  doctype.entities.each_value do |entity|
@@ -382,7 +382,9 @@ module REXML
382
382
  else
383
383
  # Replace all ampersands that aren't part of an entity
384
384
  DocType::DEFAULT_ENTITIES.each_value do |entity|
385
- copy = copy.gsub(entity.value, "&#{entity.name};" )
385
+ if copy.include?(entity.value)
386
+ copy = copy.gsub(entity.value, "&#{entity.name};" )
387
+ end
386
388
  end
387
389
  end
388
390
  copy
@@ -7,39 +7,45 @@ require_relative 'xmltokens'
7
7
  require_relative 'attribute'
8
8
  require_relative 'parsers/xpathparser'
9
9
 
10
- class Object
11
- # provides a unified +clone+ operation, for REXML::XPathParser
12
- # to use across multiple Object types
13
- def dclone
14
- clone
15
- end
16
- end
17
- class Symbol
18
- # provides a unified +clone+ operation, for REXML::XPathParser
19
- # to use across multiple Object types
20
- def dclone ; self ; end
21
- end
22
- class Integer
23
- # provides a unified +clone+ operation, for REXML::XPathParser
24
- # to use across multiple Object types
25
- def dclone ; self ; end
26
- end
27
- class Float
28
- # provides a unified +clone+ operation, for REXML::XPathParser
29
- # to use across multiple Object types
30
- def dclone ; self ; end
31
- end
32
- class Array
33
- # provides a unified +clone+ operation, for REXML::XPathParser
34
- # to use across multiple Object+ types
35
- def dclone
36
- klone = self.clone
37
- klone.clear
38
- self.each{|v| klone << v.dclone}
39
- klone
10
+ module REXML
11
+ module DClonable
12
+ refine Object do
13
+ # provides a unified +clone+ operation, for REXML::XPathParser
14
+ # to use across multiple Object types
15
+ def dclone
16
+ clone
17
+ end
18
+ end
19
+ refine Symbol do
20
+ # provides a unified +clone+ operation, for REXML::XPathParser
21
+ # to use across multiple Object types
22
+ def dclone ; self ; end
23
+ end
24
+ refine Integer do
25
+ # provides a unified +clone+ operation, for REXML::XPathParser
26
+ # to use across multiple Object types
27
+ def dclone ; self ; end
28
+ end
29
+ refine Float do
30
+ # provides a unified +clone+ operation, for REXML::XPathParser
31
+ # to use across multiple Object types
32
+ def dclone ; self ; end
33
+ end
34
+ refine Array do
35
+ # provides a unified +clone+ operation, for REXML::XPathParser
36
+ # to use across multiple Object+ types
37
+ def dclone
38
+ klone = self.clone
39
+ klone.clear
40
+ self.each{|v| klone << v.dclone}
41
+ klone
42
+ end
43
+ end
40
44
  end
41
45
  end
42
46
 
47
+ using REXML::DClonable
48
+
43
49
  module REXML
44
50
  # You don't want to use this class. Really. Use XPath, which is a wrapper
45
51
  # for this class. Believe me. You don't want to poke around in here.
data/lib/rexml.rb ADDED
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "rexml/document"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rexml
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.4
4
+ version: 3.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kouhei Sutou
8
- autorequire:
9
- bindir: exe
8
+ autorequire:
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-31 00:00:00.000000000 Z
11
+ date: 2023-07-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,20 +38,60 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: test-unit
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  description: An XML toolkit for Ruby
42
56
  email:
43
57
  - kou@cozmixng.org
44
58
  executables: []
45
59
  extensions: []
46
- extra_rdoc_files: []
60
+ extra_rdoc_files:
61
+ - LICENSE.txt
62
+ - NEWS.md
63
+ - README.md
64
+ - doc/rexml/context.rdoc
65
+ - doc/rexml/tasks/rdoc/child.rdoc
66
+ - doc/rexml/tasks/rdoc/document.rdoc
67
+ - doc/rexml/tasks/rdoc/element.rdoc
68
+ - doc/rexml/tasks/rdoc/node.rdoc
69
+ - doc/rexml/tasks/rdoc/parent.rdoc
70
+ - doc/rexml/tasks/tocs/child_toc.rdoc
71
+ - doc/rexml/tasks/tocs/document_toc.rdoc
72
+ - doc/rexml/tasks/tocs/element_toc.rdoc
73
+ - doc/rexml/tasks/tocs/master_toc.rdoc
74
+ - doc/rexml/tasks/tocs/node_toc.rdoc
75
+ - doc/rexml/tasks/tocs/parent_toc.rdoc
76
+ - doc/rexml/tutorial.rdoc
47
77
  files:
48
- - ".gitignore"
49
- - ".travis.yml"
50
- - Gemfile
51
78
  - LICENSE.txt
52
79
  - NEWS.md
53
80
  - README.md
54
- - Rakefile
81
+ - doc/rexml/context.rdoc
82
+ - doc/rexml/tasks/rdoc/child.rdoc
83
+ - doc/rexml/tasks/rdoc/document.rdoc
84
+ - doc/rexml/tasks/rdoc/element.rdoc
85
+ - doc/rexml/tasks/rdoc/node.rdoc
86
+ - doc/rexml/tasks/rdoc/parent.rdoc
87
+ - doc/rexml/tasks/tocs/child_toc.rdoc
88
+ - doc/rexml/tasks/tocs/document_toc.rdoc
89
+ - doc/rexml/tasks/tocs/element_toc.rdoc
90
+ - doc/rexml/tasks/tocs/master_toc.rdoc
91
+ - doc/rexml/tasks/tocs/node_toc.rdoc
92
+ - doc/rexml/tasks/tocs/parent_toc.rdoc
93
+ - doc/rexml/tutorial.rdoc
94
+ - lib/rexml.rb
55
95
  - lib/rexml/attlistdecl.rb
56
96
  - lib/rexml/attribute.rb
57
97
  - lib/rexml/cdata.rb
@@ -101,29 +141,29 @@ files:
101
141
  - lib/rexml/xmltokens.rb
102
142
  - lib/rexml/xpath.rb
103
143
  - lib/rexml/xpath_parser.rb
104
- - rexml.gemspec
105
144
  homepage: https://github.com/ruby/rexml
106
145
  licenses:
107
146
  - BSD-2-Clause
108
147
  metadata: {}
109
- post_install_message:
110
- rdoc_options: []
148
+ post_install_message:
149
+ rdoc_options:
150
+ - "--main"
151
+ - README.md
111
152
  require_paths:
112
153
  - lib
113
154
  required_ruby_version: !ruby/object:Gem::Requirement
114
155
  requirements:
115
156
  - - ">="
116
157
  - !ruby/object:Gem::Version
117
- version: '0'
158
+ version: 2.5.0
118
159
  required_rubygems_version: !ruby/object:Gem::Requirement
119
160
  requirements:
120
161
  - - ">="
121
162
  - !ruby/object:Gem::Version
122
163
  version: '0'
123
164
  requirements: []
124
- rubyforge_project:
125
- rubygems_version: 2.7.6.2
126
- signing_key:
165
+ rubygems_version: 3.5.0.dev
166
+ signing_key:
127
167
  specification_version: 4
128
168
  summary: An XML toolkit for Ruby
129
169
  test_files: []
data/.gitignore DELETED
@@ -1,9 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
- /coverage/
5
- /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
9
- Gemfile.lock