phlex 2.0.2 → 2.0.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: e84eae72307b1f6e6bf3337cd74d1208d3c2fb58f11e7c08eaf6dd0272fbc702
4
- data.tar.gz: a2edd58bd5a1c5185bf9b4222cb0f674fcd488243b4a33c140c92577cd74cbb8
3
+ metadata.gz: ecf456b3eda7d172d484d81175dbb08c80c9c2387cab5e534cb0f7c31293df88
4
+ data.tar.gz: 402dd5813b07b2a5dbd6120808d3bfca5fe1241704d414339a44e8cddf130639
5
5
  SHA512:
6
- metadata.gz: 22c542f19b5121666bca2f3bf661ff05488c21d5b593578f704dbe9f69643d48b839deddd9898214638a21dc7fb9de56dcb750f7401082710a13a5544668a643
7
- data.tar.gz: a81c55fb957fa70907fac519b08c072521701908385227f93284219de34e0338a48276faff36ef54ba60d552511a579a734725fcbfea7b6d302edbaaf9e94c54
6
+ metadata.gz: 816fe5523cb3ba2ec4bb953cbcefda9aa2901bd781feb8f0fbcf74f69410606118311aaa893c9c4f7e781e2b2e1a754d07f6df24ba5f80966fe6b12b2dbcf3e4
7
+ data.tar.gz: cbab8596e518be9be3c6cc4496dafb4f3e5862be778fec2aeb619f4866b323e6b65c26db5a8355ceb98084410c7fbab20ed6b00515a567877c8352c06e02a0c7
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
  autoload :Elements, "phlex/sgml/elements"
9
15
  autoload :SafeObject, "phlex/sgml/safe_object"
@@ -477,7 +483,9 @@ class Phlex::SGML
477
483
  if value != true && REF_ATTRIBUTES.include?(normalized_name)
478
484
  case value
479
485
  when String
480
- if value.downcase.delete("^a-z:").start_with?("javascript:")
486
+ decoded_value = decode_html_character_references(value)
487
+
488
+ if decoded_value.downcase.delete("^a-z:").start_with?("javascript:")
481
489
  # We just ignore these because they were likely not specified by the developer.
482
490
  next
483
491
  end
@@ -495,7 +503,7 @@ class Phlex::SGML
495
503
  end
496
504
  end
497
505
 
498
- if name.match?(/[<>&"']/)
506
+ if name.match?(UNSAFE_ATTRIBUTE_NAME_CHARS)
499
507
  raise Phlex::ArgumentError.new("Unsafe attribute name detected: #{k}.")
500
508
  end
501
509
 
@@ -526,7 +534,7 @@ class Phlex::SGML
526
534
  else raise Phlex::ArgumentError.new("Attribute keys should be Strings or Symbols")
527
535
  end
528
536
 
529
- if name.match?(/[<>&"']/)
537
+ if name.match?(UNSAFE_ATTRIBUTE_NAME_CHARS)
530
538
  raise Phlex::ArgumentError.new("Unsafe attribute name detected: #{k}.")
531
539
  end
532
540
 
@@ -602,6 +610,27 @@ class Phlex::SGML
602
610
  buffer.gsub('"', "&quot;")
603
611
  end
604
612
 
613
+ private def decode_html_character_references(value)
614
+ value
615
+ .gsub(/&#x([0-9a-f]+);?/i) {
616
+ begin
617
+ [$1.to_i(16)].pack("U*")
618
+ rescue
619
+ ""
620
+ end
621
+ }
622
+ .gsub(/&#(\d+);?/) {
623
+ begin
624
+ [$1.to_i].pack("U*")
625
+ rescue
626
+ ""
627
+ end
628
+ }
629
+ .gsub(/&([a-z][a-z0-9]+);?/i) {
630
+ NAMED_CHARACTER_REFERENCES[$1.downcase] || ""
631
+ }
632
+ end
633
+
605
634
  # Result is **unsafe**, so it should be escaped!
606
635
  def __styles__(styles)
607
636
  case styles
data/lib/phlex/svg.rb CHANGED
@@ -29,7 +29,7 @@ class Phlex::SVG < Phlex::SGML
29
29
  raise Phlex::ArgumentError.new("Expected the tag name to be a Symbol.")
30
30
  end
31
31
 
32
- if (tag = StandardElements.__registered_elements__[name]) || (tag = name.name.tr("_", "-")).include?("-")
32
+ if (tag = StandardElements.__registered_elements__[name]) || ((tag = name.name.tr("_", "-")).include?("-") && tag.match?(/\A[a-z0-9-]+\z/))
33
33
  if attributes.length > 0 # with attributes
34
34
  if block_given # with content block
35
35
  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.0.2"
4
+ VERSION = "2.0.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.0.2
4
+ version: 2.0.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-02-16 00:00:00.000000000 Z
11
+ date: 2026-02-06 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Build HTML & SVG view components with Ruby classes.
14
14
  email:
@@ -65,7 +65,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
65
65
  - !ruby/object:Gem::Version
66
66
  version: '0'
67
67
  requirements: []
68
- rubygems_version: 3.6.2
68
+ rubygems_version: 3.6.6
69
69
  specification_version: 4
70
70
  summary: Object-oriented views in Ruby.
71
71
  test_files: []