phlex 2.1.2 → 2.1.3

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: bec8e4750b58937139e2cd64d5890a406f537b925995588c23d336340e998f46
4
- data.tar.gz: 722c0d77adc2cf4d3110bc2653a7e5dced17554f8d0b102acb8e178a873b5d1d
3
+ metadata.gz: 58ef5e091c9feed2677149231356e32305898a8d2bb271a0e603bcc208ead0fd
4
+ data.tar.gz: bab9a697db8f529f0221afb1fd491e30d2f4b0c702a253f7a0446f8a075ddc82
5
5
  SHA512:
6
- metadata.gz: a2a6ea6722f8576a413d60f4918c7505069c24a5f1c26a0ff2514d5a1b03206b64688d8ba41b7457f51070ac710dfe0dabe7f5818e139c0cfffde1e513da1244
7
- data.tar.gz: 52f9f64241f7d957b7e25dabb8598a4bd1c2a343a3c2a0dd2264bc23dc6d057c272d2b1bae772b80d9dbe071af3cc46f21b1480dabf414c154f17789dbda368d
6
+ metadata.gz: 1e92858e2c2a177a120579e7cbb4c7489456a8faa0a40ecbce9fe6070f7ef01ace1e4f13baf72a9f9baf841ed57ea9b74f9cf2aa262fc774eaa95178a9248b63
7
+ data.tar.gz: 8040edc5a9640fb638280bccb4e879ab97d855b739f5eab04fc7ffcf7fcb7d7ca50a06ae808c31e67f9fdb7c286062c35ff40483abfaf42ac9637e2abe32c67e
data/lib/phlex/html.rb CHANGED
@@ -58,7 +58,7 @@ class Phlex::HTML < Phlex::SGML
58
58
  raise Phlex::ArgumentError.new("Expected the tag name to be a Symbol.")
59
59
  end
60
60
 
61
- if (tag = StandardElements.__registered_elements__[name]) || (tag = name.name.tr("_", "-")).include?("-")
61
+ if (tag = StandardElements.__registered_elements__[name]) || ((tag = name.name.tr("_", "-")).include?("-") && tag.match?(/\A[a-z0-9-]+\z/))
62
62
  if attributes.length > 0 # with attributes
63
63
  if block_given # with content block
64
64
  buffer << "<#{tag}" << (Phlex::ATTRIBUTE_CACHE[attributes] ||= __attributes__(attributes)) << ">"
data/lib/phlex/sgml.rb CHANGED
@@ -3,7 +3,13 @@
3
3
  # **Standard Generalized Markup Language** for behaviour common to {HTML} and {SVG}.
4
4
  class Phlex::SGML
5
5
  UNSAFE_ATTRIBUTES = Set.new(%w[srcdoc sandbox http-equiv]).freeze
6
- REF_ATTRIBUTES = Set.new(%w[href src action formaction lowsrc dynsrc background ping]).freeze
6
+ REF_ATTRIBUTES = Set.new(%w[href src action formaction lowsrc dynsrc background ping xlinkhref]).freeze
7
+ NAMED_CHARACTER_REFERENCES = {
8
+ "colon" => ":",
9
+ "tab" => "\t",
10
+ "newline" => "\n",
11
+ }.freeze
12
+ UNSAFE_ATTRIBUTE_NAME_CHARS = %r([<>&"'/=\s\x00])
7
13
 
8
14
  ERBCompiler = ERB::Compiler.new("<>").tap do |compiler|
9
15
  compiler.pre_cmd = [""]
@@ -523,7 +529,9 @@ class Phlex::SGML
523
529
  if value != true && REF_ATTRIBUTES.include?(normalized_name)
524
530
  case value
525
531
  when String
526
- if value.downcase.delete("^a-z:").start_with?("javascript:")
532
+ decoded_value = decode_html_character_references(value)
533
+
534
+ if decoded_value.downcase.delete("^a-z:").start_with?("javascript:")
527
535
  # We just ignore these because they were likely not specified by the developer.
528
536
  next
529
537
  end
@@ -541,7 +549,7 @@ class Phlex::SGML
541
549
  end
542
550
  end
543
551
 
544
- if name.match?(/[<>&"']/)
552
+ if name.match?(UNSAFE_ATTRIBUTE_NAME_CHARS)
545
553
  raise Phlex::ArgumentError.new("Unsafe attribute name detected: #{k}.")
546
554
  end
547
555
 
@@ -572,7 +580,7 @@ class Phlex::SGML
572
580
  else raise Phlex::ArgumentError.new("Attribute keys should be Strings or Symbols")
573
581
  end
574
582
 
575
- if name.match?(/[<>&"']/)
583
+ if name.match?(UNSAFE_ATTRIBUTE_NAME_CHARS)
576
584
  raise Phlex::ArgumentError.new("Unsafe attribute name detected: #{k}.")
577
585
  end
578
586
 
@@ -648,6 +656,27 @@ class Phlex::SGML
648
656
  buffer.gsub('"', "&quot;")
649
657
  end
650
658
 
659
+ private def decode_html_character_references(value)
660
+ value
661
+ .gsub(/&#x([0-9a-f]+);?/i) {
662
+ begin
663
+ [$1.to_i(16)].pack("U*")
664
+ rescue
665
+ ""
666
+ end
667
+ }
668
+ .gsub(/&#(\d+);?/) {
669
+ begin
670
+ [$1.to_i].pack("U*")
671
+ rescue
672
+ ""
673
+ end
674
+ }
675
+ .gsub(/&([a-z][a-z0-9]+);?/i) {
676
+ NAMED_CHARACTER_REFERENCES[$1.downcase] || ""
677
+ }
678
+ end
679
+
651
680
  # Result is **unsafe**, so it should be escaped!
652
681
  def __styles__(styles)
653
682
  case styles
data/lib/phlex/svg.rb CHANGED
@@ -43,7 +43,7 @@ class Phlex::SVG < Phlex::SGML
43
43
  raise Phlex::ArgumentError.new("Expected the tag name to be a Symbol.")
44
44
  end
45
45
 
46
- if (tag = StandardElements.__registered_elements__[name]) || (tag = name.name.tr("_", "-")).include?("-")
46
+ if (tag = StandardElements.__registered_elements__[name]) || ((tag = name.name.tr("_", "-")).include?("-") && tag.match?(/\A[a-z0-9-]+\z/))
47
47
  if attributes.length > 0 # with attributes
48
48
  if block_given # with content block
49
49
  buffer << "<#{tag}" << (Phlex::ATTRIBUTE_CACHE[attributes] ||= __attributes__(attributes)) << ">"
data/lib/phlex/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Phlex
4
- VERSION = "2.1.2"
4
+ VERSION = "2.1.3"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: phlex
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.2
4
+ version: 2.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joel Drapper
8
8
  - Will Cosgrove
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-03-18 00:00:00.000000000 Z
11
+ date: 2026-02-06 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Build HTML, SVG and CSV views with Ruby classes.
14
14
  email:
@@ -64,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
64
64
  - !ruby/object:Gem::Version
65
65
  version: '0'
66
66
  requirements: []
67
- rubygems_version: 3.6.2
67
+ rubygems_version: 3.6.6
68
68
  specification_version: 4
69
69
  summary: Object-oriented views in Ruby.
70
70
  test_files: []