rexml 3.3.9 → 3.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9d8de4465de1e9548d66ad026772932f724b9747dc8b1c62960d8efeaeaa8412
4
- data.tar.gz: 1cb29aaa36dcef98ba8bd4e9fa249959405f67fdb6bed54d12b466fdf43f57af
3
+ metadata.gz: a9dc6a26dcc5ba93c112d65fa910e49ca970108c726cdce28324d7771a0831a3
4
+ data.tar.gz: b03ad34d3180aeeaa1ecc7ab21bf5ffe5f2845107a2c35ca3198653f80b932fa
5
5
  SHA512:
6
- metadata.gz: 78c881a10f12e46e1b6710d6ec75e42e4311c233376a7587756bc098063d21f52a4d82bcac8201001bf7e39079b3db4015482dae5b4ba46e561ef75fa15b15a0
7
- data.tar.gz: 8d7a4b94937ce7b0bdf6ed83152fe207098dfe45333498a64e50d5fe9a686dffa2f66913c1edf265470b2b6a04cfae20857f1cffa404c278249784eeb533d594
6
+ metadata.gz: c0d493943fab795f3c8fc8490a40750382e3c4cf38c73532b1f850612384795c2bb916afc70ebff0bd26e9e2f304ea6a22299a0481523bd0322d5655df05edbd
7
+ data.tar.gz: bfb02a2bfadb24cbdeed951e06e113e17b123015271cabfffacc3ecc4bbb1bd7c7f56e358d42173feb8b333309f725d57b76f155fea814d70c6decae3b791165
data/NEWS.md CHANGED
@@ -1,5 +1,58 @@
1
1
  # News
2
2
 
3
+ ## 3.4.1 - 2025-02-16 {#version-3-4-1}
4
+
5
+ ### Improvement
6
+
7
+ * Improved performance.
8
+ * GH-226
9
+ * GH-227
10
+ * GH-237
11
+ * Patch by NAITOH Jun
12
+
13
+ ### Fixes
14
+
15
+ * Fix serialization of ATTLIST is incorrect
16
+ * GH-233
17
+ * GH-234
18
+ * Patch by OlofKalufs
19
+ * Reported by OlofKalufs
20
+
21
+ ### Thanks
22
+
23
+ * NAITOH Jun
24
+
25
+ * OlofKalufs
26
+
27
+ ## 3.4.0 - 2024-12-15 {#version-3-4-0}
28
+
29
+ ### Improvement
30
+
31
+ * Improved performance.
32
+ * GH-216
33
+ * Patch by NAITOH Jun
34
+
35
+ * JRuby: Improved parse performance.
36
+ * GH-219
37
+ * Patch by João Duarte
38
+
39
+ * Added support for reusing pull parser.
40
+ * GH-214
41
+ * GH-220
42
+ * Patch by Dmitry Pogrebnoy
43
+
44
+ * Improved error handling when source is `IO`.
45
+ * GH-221
46
+ * Patch by NAITOH Jun
47
+
48
+ ### Thanks
49
+
50
+ * NAITOH Jun
51
+
52
+ * João Duarte
53
+
54
+ * Dmitry Pogrebnoy
55
+
3
56
  ## 3.3.9 - 2024-10-24 {#version-3-3-9}
4
57
 
5
58
  ### Improvements
@@ -181,6 +181,10 @@ module REXML
181
181
 
182
182
  def stream=( source )
183
183
  @source = SourceFactory.create_from( source )
184
+ reset
185
+ end
186
+
187
+ def reset
184
188
  @closed = nil
185
189
  @have_root = false
186
190
  @document_status = nil
@@ -269,10 +273,10 @@ module REXML
269
273
  @source.ensure_buffer
270
274
  if @document_status == nil
271
275
  start_position = @source.position
272
- if @source.match("<?", true)
276
+ if @source.match?("<?", true)
273
277
  return process_instruction
274
- elsif @source.match("<!", true)
275
- if @source.match("--", true)
278
+ elsif @source.match?("<!", true)
279
+ if @source.match?("--", true)
276
280
  md = @source.match(/(.*?)-->/um, true)
277
281
  if md.nil?
278
282
  raise REXML::ParseException.new("Unclosed comment", @source)
@@ -281,10 +285,10 @@ module REXML
281
285
  raise REXML::ParseException.new("Malformed comment", @source)
282
286
  end
283
287
  return [ :comment, md[1] ]
284
- elsif @source.match("DOCTYPE", true)
288
+ elsif @source.match?("DOCTYPE", true)
285
289
  base_error_message = "Malformed DOCTYPE"
286
- unless @source.match(/\s+/um, true)
287
- if @source.match(">")
290
+ unless @source.match?(/\s+/um, true)
291
+ if @source.match?(">")
288
292
  message = "#{base_error_message}: name is missing"
289
293
  else
290
294
  message = "#{base_error_message}: invalid name"
@@ -293,10 +297,11 @@ module REXML
293
297
  raise REXML::ParseException.new(message, @source)
294
298
  end
295
299
  name = parse_name(base_error_message)
296
- if @source.match(/\s*\[/um, true)
300
+ @source.match?(/\s*/um, true) # skip spaces
301
+ if @source.match?("[", true)
297
302
  id = [nil, nil, nil]
298
303
  @document_status = :in_doctype
299
- elsif @source.match(/\s*>/um, true)
304
+ elsif @source.match?(">", true)
300
305
  id = [nil, nil, nil]
301
306
  @document_status = :after_doctype
302
307
  @source.ensure_buffer
@@ -308,9 +313,10 @@ module REXML
308
313
  # For backward compatibility
309
314
  id[1], id[2] = id[2], nil
310
315
  end
311
- if @source.match(/\s*\[/um, true)
316
+ @source.match?(/\s*/um, true) # skip spaces
317
+ if @source.match?("[", true)
312
318
  @document_status = :in_doctype
313
- elsif @source.match(/\s*>/um, true)
319
+ elsif @source.match?(">", true)
314
320
  @document_status = :after_doctype
315
321
  @source.ensure_buffer
316
322
  else
@@ -320,7 +326,7 @@ module REXML
320
326
  end
321
327
  args = [:start_doctype, name, *id]
322
328
  if @document_status == :after_doctype
323
- @source.match(/\s*/um, true)
329
+ @source.match?(/\s*/um, true)
324
330
  @stack << [ :end_doctype ]
325
331
  end
326
332
  return args
@@ -331,14 +337,14 @@ module REXML
331
337
  end
332
338
  end
333
339
  if @document_status == :in_doctype
334
- @source.match(/\s*/um, true) # skip spaces
340
+ @source.match?(/\s*/um, true) # skip spaces
335
341
  start_position = @source.position
336
- if @source.match("<!", true)
337
- if @source.match("ELEMENT", true)
342
+ if @source.match?("<!", true)
343
+ if @source.match?("ELEMENT", true)
338
344
  md = @source.match(/(.*?)>/um, true)
339
345
  raise REXML::ParseException.new( "Bad ELEMENT declaration!", @source ) if md.nil?
340
346
  return [ :elementdecl, "<!ELEMENT" + md[1] ]
341
- elsif @source.match("ENTITY", true)
347
+ elsif @source.match?("ENTITY", true)
342
348
  match_data = @source.match(Private::ENTITYDECL_PATTERN, true)
343
349
  unless match_data
344
350
  raise REXML::ParseException.new("Malformed entity declaration", @source)
@@ -370,11 +376,11 @@ module REXML
370
376
  end
371
377
  match << '%' if ref
372
378
  return match
373
- elsif @source.match("ATTLIST", true)
379
+ elsif @source.match?("ATTLIST", true)
374
380
  md = @source.match(Private::ATTLISTDECL_END, true)
375
381
  raise REXML::ParseException.new( "Bad ATTLIST declaration!", @source ) if md.nil?
376
382
  element = md[1]
377
- contents = md[0]
383
+ contents = "<!ATTLIST" + md[0]
378
384
 
379
385
  pairs = {}
380
386
  values = md[0].strip.scan( ATTDEF_RE )
@@ -390,10 +396,10 @@ module REXML
390
396
  end
391
397
  end
392
398
  return [ :attlistdecl, element, pairs, contents ]
393
- elsif @source.match("NOTATION", true)
399
+ elsif @source.match?("NOTATION", true)
394
400
  base_error_message = "Malformed notation declaration"
395
- unless @source.match(/\s+/um, true)
396
- if @source.match(">")
401
+ unless @source.match?(/\s+/um, true)
402
+ if @source.match?(">")
397
403
  message = "#{base_error_message}: name is missing"
398
404
  else
399
405
  message = "#{base_error_message}: invalid name"
@@ -405,7 +411,8 @@ module REXML
405
411
  id = parse_id(base_error_message,
406
412
  accept_external_id: true,
407
413
  accept_public_id: true)
408
- unless @source.match(/\s*>/um, true)
414
+ @source.match?(/\s*/um, true) # skip spaces
415
+ unless @source.match?(">", true)
409
416
  message = "#{base_error_message}: garbage before end >"
410
417
  raise REXML::ParseException.new(message, @source)
411
418
  end
@@ -419,7 +426,7 @@ module REXML
419
426
  end
420
427
  elsif match = @source.match(/(%.*?;)\s*/um, true)
421
428
  return [ :externalentity, match[1] ]
422
- elsif @source.match(/\]\s*>/um, true)
429
+ elsif @source.match?(/\]\s*>/um, true)
423
430
  @document_status = :after_doctype
424
431
  return [ :end_doctype ]
425
432
  end
@@ -428,16 +435,16 @@ module REXML
428
435
  end
429
436
  end
430
437
  if @document_status == :after_doctype
431
- @source.match(/\s*/um, true)
438
+ @source.match?(/\s*/um, true)
432
439
  end
433
440
  begin
434
441
  start_position = @source.position
435
- if @source.match("<", true)
442
+ if @source.match?("<", true)
436
443
  # :text's read_until may remain only "<" in buffer. In the
437
444
  # case, buffer is empty here. So we need to fill buffer
438
445
  # here explicitly.
439
446
  @source.ensure_buffer
440
- if @source.match("/", true)
447
+ if @source.match?("/", true)
441
448
  @namespaces_restore_stack.pop
442
449
  last_tag = @tags.pop
443
450
  md = @source.match(Private::CLOSE_PATTERN, true)
@@ -452,7 +459,7 @@ module REXML
452
459
  raise REXML::ParseException.new(message, @source)
453
460
  end
454
461
  return [ :end_element, last_tag ]
455
- elsif @source.match("!", true)
462
+ elsif @source.match?("!", true)
456
463
  md = @source.match(/([^>]*>)/um)
457
464
  #STDERR.puts "SOURCE BUFFER = #{source.buffer}, #{source.buffer.size}"
458
465
  raise REXML::ParseException.new("Malformed node", @source) unless md
@@ -470,7 +477,7 @@ module REXML
470
477
  end
471
478
  raise REXML::ParseException.new( "Declarations can only occur "+
472
479
  "in the doctype declaration.", @source)
473
- elsif @source.match("?", true)
480
+ elsif @source.match?("?", true)
474
481
  return process_instruction
475
482
  else
476
483
  # Get the next tag
@@ -651,7 +658,7 @@ module REXML
651
658
  def parse_name(base_error_message)
652
659
  md = @source.match(Private::NAME_PATTERN, true)
653
660
  unless md
654
- if @source.match(/\S/um)
661
+ if @source.match?(/\S/um)
655
662
  message = "#{base_error_message}: invalid name"
656
663
  else
657
664
  message = "#{base_error_message}: name is missing"
@@ -693,34 +700,34 @@ module REXML
693
700
  accept_public_id:)
694
701
  public = /\A\s*PUBLIC/um
695
702
  system = /\A\s*SYSTEM/um
696
- if (accept_external_id or accept_public_id) and @source.match(/#{public}/um)
697
- if @source.match(/#{public}(?:\s+[^'"]|\s*[\[>])/um)
703
+ if (accept_external_id or accept_public_id) and @source.match?(/#{public}/um)
704
+ if @source.match?(/#{public}(?:\s+[^'"]|\s*[\[>])/um)
698
705
  return "public ID literal is missing"
699
706
  end
700
- unless @source.match(/#{public}\s+#{PUBIDLITERAL}/um)
707
+ unless @source.match?(/#{public}\s+#{PUBIDLITERAL}/um)
701
708
  return "invalid public ID literal"
702
709
  end
703
710
  if accept_public_id
704
- if @source.match(/#{public}\s+#{PUBIDLITERAL}\s+[^'"]/um)
711
+ if @source.match?(/#{public}\s+#{PUBIDLITERAL}\s+[^'"]/um)
705
712
  return "system ID literal is missing"
706
713
  end
707
- unless @source.match(/#{public}\s+#{PUBIDLITERAL}\s+#{SYSTEMLITERAL}/um)
714
+ unless @source.match?(/#{public}\s+#{PUBIDLITERAL}\s+#{SYSTEMLITERAL}/um)
708
715
  return "invalid system literal"
709
716
  end
710
717
  "garbage after system literal"
711
718
  else
712
719
  "garbage after public ID literal"
713
720
  end
714
- elsif accept_external_id and @source.match(/#{system}/um)
715
- if @source.match(/#{system}(?:\s+[^'"]|\s*[\[>])/um)
721
+ elsif accept_external_id and @source.match?(/#{system}/um)
722
+ if @source.match?(/#{system}(?:\s+[^'"]|\s*[\[>])/um)
716
723
  return "system literal is missing"
717
724
  end
718
- unless @source.match(/#{system}\s+#{SYSTEMLITERAL}/um)
725
+ unless @source.match?(/#{system}\s+#{SYSTEMLITERAL}/um)
719
726
  return "invalid system literal"
720
727
  end
721
728
  "garbage after system literal"
722
729
  else
723
- unless @source.match(/\A\s*(?:PUBLIC|SYSTEM)\s/um)
730
+ unless @source.match?(/\A\s*(?:PUBLIC|SYSTEM)\s/um)
724
731
  return "invalid ID type"
725
732
  end
726
733
  "ID type is missing"
@@ -729,7 +736,7 @@ module REXML
729
736
 
730
737
  def process_instruction
731
738
  name = parse_name("Malformed XML: Invalid processing instruction node")
732
- if @source.match(/\s+/um, true)
739
+ if @source.match?(/\s+/um, true)
733
740
  match_data = @source.match(/(.*?)\?>/um, true)
734
741
  unless match_data
735
742
  raise ParseException.new("Malformed XML: Unclosed processing instruction", @source)
@@ -737,7 +744,7 @@ module REXML
737
744
  content = match_data[1]
738
745
  else
739
746
  content = nil
740
- unless @source.match("?>", true)
747
+ unless @source.match?("?>", true)
741
748
  raise ParseException.new("Malformed XML: Unclosed processing instruction", @source)
742
749
  end
743
750
  end
@@ -762,14 +769,33 @@ module REXML
762
769
  [:processing_instruction, name, content]
763
770
  end
764
771
 
772
+ if StringScanner::Version < "3.1.1"
773
+ def scan_quote
774
+ @source.match(/(['"])/, true)&.[](1)
775
+ end
776
+ else
777
+ def scan_quote
778
+ case @source.peek_byte
779
+ when 34 # '"'.ord
780
+ @source.scan_byte
781
+ '"'
782
+ when 39 # "'".ord
783
+ @source.scan_byte
784
+ "'"
785
+ else
786
+ nil
787
+ end
788
+ end
789
+ end
790
+
765
791
  def parse_attributes(prefixes)
766
792
  attributes = {}
767
793
  expanded_names = {}
768
794
  closed = false
769
795
  while true
770
- if @source.match(">", true)
796
+ if @source.match?(">", true)
771
797
  return attributes, closed
772
- elsif @source.match("/>", true)
798
+ elsif @source.match?("/>", true)
773
799
  closed = true
774
800
  return attributes, closed
775
801
  elsif match = @source.match(QNAME, true)
@@ -777,15 +803,14 @@ module REXML
777
803
  prefix = match[2]
778
804
  local_part = match[3]
779
805
 
780
- unless @source.match(/\s*=\s*/um, true)
806
+ unless @source.match?(/\s*=\s*/um, true)
781
807
  message = "Missing attribute equal: <#{name}>"
782
808
  raise REXML::ParseException.new(message, @source)
783
809
  end
784
- unless match = @source.match(/(['"])/, true)
810
+ unless quote = scan_quote
785
811
  message = "Missing attribute value start quote: <#{name}>"
786
812
  raise REXML::ParseException.new(message, @source)
787
813
  end
788
- quote = match[1]
789
814
  start_position = @source.position
790
815
  value = @source.read_until(quote)
791
816
  unless value.chomp!(quote)
@@ -793,7 +818,7 @@ module REXML
793
818
  message = "Missing attribute value end quote: <#{name}>: <#{quote}>"
794
819
  raise REXML::ParseException.new(message, @source)
795
820
  end
796
- @source.match(/\s*/um, true)
821
+ @source.match?(/\s*/um, true)
797
822
  if prefix == "xmlns"
798
823
  if local_part == "xml"
799
824
  if value != Private::XML_PREFIXED_NAMESPACE
@@ -93,6 +93,10 @@ module REXML
93
93
  def unshift token
94
94
  @my_stack.unshift token
95
95
  end
96
+
97
+ def reset
98
+ @parser.reset
99
+ end
96
100
  end
97
101
 
98
102
  # A parsing event. The contents of the event are accessed as an +Array?,
data/lib/rexml/rexml.rb CHANGED
@@ -31,7 +31,7 @@
31
31
  module REXML
32
32
  COPYRIGHT = "Copyright © 2001-2008 Sean Russell <ser@germane-software.com>"
33
33
  DATE = "2008/019"
34
- VERSION = "3.3.9"
34
+ VERSION = "3.4.1"
35
35
  REVISION = ""
36
36
 
37
37
  Copyright = COPYRIGHT
data/lib/rexml/source.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # coding: US-ASCII
2
2
  # frozen_string_literal: false
3
3
 
4
+ require "stringio"
4
5
  require "strscan"
5
6
 
6
7
  require_relative 'encoding'
@@ -18,6 +19,16 @@ module REXML
18
19
  pattern = /#{Regexp.escape(pattern)}/ if pattern.is_a?(String)
19
20
  super(pattern)
20
21
  end
22
+
23
+ def match?(pattern)
24
+ pattern = /#{Regexp.escape(pattern)}/ if pattern.is_a?(String)
25
+ super(pattern)
26
+ end
27
+
28
+ def skip(pattern)
29
+ pattern = /#{Regexp.escape(pattern)}/ if pattern.is_a?(String)
30
+ super(pattern)
31
+ end
21
32
  end
22
33
  end
23
34
  using StringScannerCheckScanString
@@ -35,7 +46,6 @@ module REXML
35
46
  arg.respond_to? :eof?
36
47
  IOSource.new(arg)
37
48
  elsif arg.respond_to? :to_str
38
- require 'stringio'
39
49
  IOSource.new(StringIO.new(arg))
40
50
  elsif arg.kind_of? Source
41
51
  arg
@@ -58,8 +68,14 @@ module REXML
58
68
  SCANNER_RESET_SIZE = 100000
59
69
  PRE_DEFINED_TERM_PATTERNS = {}
60
70
  pre_defined_terms = ["'", '"', "<"]
61
- pre_defined_terms.each do |term|
62
- PRE_DEFINED_TERM_PATTERNS[term] = /#{Regexp.escape(term)}/
71
+ if StringScanner::Version < "3.1.1"
72
+ pre_defined_terms.each do |term|
73
+ PRE_DEFINED_TERM_PATTERNS[term] = /#{Regexp.escape(term)}/
74
+ end
75
+ else
76
+ pre_defined_terms.each do |term|
77
+ PRE_DEFINED_TERM_PATTERNS[term] = term
78
+ end
63
79
  end
64
80
  end
65
81
  private_constant :Private
@@ -77,7 +93,7 @@ module REXML
77
93
  detect_encoding
78
94
  end
79
95
  @line = 0
80
- @term_encord = {}
96
+ @encoded_terms = {}
81
97
  end
82
98
 
83
99
  # The current buffer (what we're going to read next)
@@ -126,6 +142,14 @@ module REXML
126
142
  end
127
143
  end
128
144
 
145
+ def match?(pattern, cons=false)
146
+ if cons
147
+ !@scanner.skip(pattern).nil?
148
+ else
149
+ !@scanner.match?(pattern).nil?
150
+ end
151
+ end
152
+
129
153
  def position
130
154
  @scanner.pos
131
155
  end
@@ -134,6 +158,14 @@ module REXML
134
158
  @scanner.pos = pos
135
159
  end
136
160
 
161
+ def peek_byte
162
+ @scanner.peek_byte
163
+ end
164
+
165
+ def scan_byte
166
+ @scanner.scan_byte
167
+ end
168
+
137
169
  # @return true if the Source is exhausted
138
170
  def empty?
139
171
  @scanner.eos?
@@ -228,7 +260,7 @@ module REXML
228
260
 
229
261
  def read_until(term)
230
262
  pattern = Private::PRE_DEFINED_TERM_PATTERNS[term] || /#{Regexp.escape(term)}/
231
- term = @term_encord[term] ||= encode(term)
263
+ term = @encoded_terms[term] ||= encode(term)
232
264
  until str = @scanner.scan_until(pattern)
233
265
  break if @source.nil?
234
266
  break if @source.eof?
@@ -267,6 +299,23 @@ module REXML
267
299
  md.nil? ? nil : @scanner
268
300
  end
269
301
 
302
+ def match?( pattern, cons=false )
303
+ # To avoid performance issue, we need to increase bytes to read per scan
304
+ min_bytes = 1
305
+ while true
306
+ if cons
307
+ n_matched_bytes = @scanner.skip(pattern)
308
+ else
309
+ n_matched_bytes = @scanner.match?(pattern)
310
+ end
311
+ return true if n_matched_bytes
312
+ return false if pattern.is_a?(String)
313
+ return false if @source.nil?
314
+ return false unless read(nil, min_bytes)
315
+ min_bytes *= 2
316
+ end
317
+ end
318
+
270
319
  def empty?
271
320
  super and ( @source.nil? || @source.eof? )
272
321
  end
@@ -286,7 +335,7 @@ module REXML
286
335
  rescue
287
336
  end
288
337
  @er_source.seek(pos)
289
- rescue IOError
338
+ rescue IOError, SystemCallError
290
339
  pos = -1
291
340
  line = -1
292
341
  end
data/lib/rexml/text.rb CHANGED
@@ -29,31 +29,16 @@ module REXML
29
29
  (0x10000..0x10FFFF)
30
30
  ]
31
31
 
32
- if String.method_defined? :encode
33
- VALID_XML_CHARS = Regexp.new('^['+
34
- VALID_CHAR.map { |item|
35
- case item
36
- when Integer
37
- [item].pack('U').force_encoding('utf-8')
38
- when Range
39
- [item.first, '-'.ord, item.last].pack('UUU').force_encoding('utf-8')
40
- end
41
- }.join +
42
- ']*$')
43
- else
44
- VALID_XML_CHARS = /^(
45
- [\x09\x0A\x0D\x20-\x7E] # ASCII
46
- | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
47
- | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
48
- | [\xE1-\xEC\xEE][\x80-\xBF]{2} # straight 3-byte
49
- | \xEF[\x80-\xBE]{2} #
50
- | \xEF\xBF[\x80-\xBD] # excluding U+fffe and U+ffff
51
- | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
52
- | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
53
- | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
54
- | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
55
- )*$/nx;
56
- end
32
+ VALID_XML_CHARS = Regexp.new('^['+
33
+ VALID_CHAR.map { |item|
34
+ case item
35
+ when Integer
36
+ [item].pack('U').force_encoding('utf-8')
37
+ when Range
38
+ [item.first, '-'.ord, item.last].pack('UUU').force_encoding('utf-8')
39
+ end
40
+ }.join +
41
+ ']*$')
57
42
 
58
43
  # Constructor
59
44
  # +arg+ if a String, the content is set to the String. If a Text,
@@ -132,21 +117,11 @@ module REXML
132
117
 
133
118
  # illegal anywhere
134
119
  if !string.match?(VALID_XML_CHARS)
135
- if String.method_defined? :encode
136
- string.chars.each do |c|
137
- case c.ord
138
- when *VALID_CHAR
139
- else
140
- raise "Illegal character #{c.inspect} in raw string #{string.inspect}"
141
- end
142
- end
143
- else
144
- string.scan(/[\x00-\x7F]|[\x80-\xBF][\xC0-\xF0]*|[\xC0-\xF0]/n) do |c|
145
- case c.unpack('U')
146
- when *VALID_CHAR
147
- else
148
- raise "Illegal character #{c.inspect} in raw string #{string.inspect}"
149
- end
120
+ string.chars.each do |c|
121
+ case c.ord
122
+ when *VALID_CHAR
123
+ else
124
+ raise "Illegal character #{c.inspect} in raw string #{string.inspect}"
150
125
  end
151
126
  end
152
127
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rexml
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.9
4
+ version: 3.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kouhei Sutou
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2024-10-24 00:00:00.000000000 Z
10
+ date: 2025-02-16 00:00:00.000000000 Z
11
11
  dependencies: []
12
12
  description: An XML toolkit for Ruby
13
13
  email:
@@ -102,7 +102,7 @@ homepage: https://github.com/ruby/rexml
102
102
  licenses:
103
103
  - BSD-2-Clause
104
104
  metadata:
105
- changelog_uri: https://github.com/ruby/rexml/releases/tag/v3.3.9
105
+ changelog_uri: https://github.com/ruby/rexml/releases/tag/v3.4.1
106
106
  rdoc_options:
107
107
  - "--main"
108
108
  - README.md
@@ -119,7 +119,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
119
119
  - !ruby/object:Gem::Version
120
120
  version: '0'
121
121
  requirements: []
122
- rubygems_version: 3.6.0.dev
122
+ rubygems_version: 3.6.2
123
123
  specification_version: 4
124
124
  summary: An XML toolkit for Ruby
125
125
  test_files: []