Class: Cybertrain::SafeString
- Inherits:
-
Object
- Object
- Cybertrain::SafeString
- Defined in:
- cybertrain/html.rb
Overview
A string that has already been through Html.escape (or was built from only safe pieces) and should not be escaped again when rendered.
Templates print it unescaped (raw(x) and x.html_safe make one);
Controller#render html: sends it as it is, where a plain String is
escaped. It is a wrapper, not a String subclass. There is no
String#html_safe in Ruby code: use Html.safe or SafeString.of.
Class Method Summary collapse
-
.of(str) ⇒ SafeString
SafeString.of(str), safe for a String made in the argument itself (
SafeString.of("<a>#{x}</a>")).
Instance Method Summary collapse
-
#+(other) ⇒ SafeString
Concatenating with a plain String escapes it first, so building up a SafeString piece by piece never lets unsafe content slip through.
-
#initialize(str) ⇒ SafeString
constructor
A new instance of SafeString.
-
#to_s ⇒ String
The HTML.
Constructor Details
#initialize(str) ⇒ SafeString
Returns a new instance of SafeString.
106 107 108 |
# File 'cybertrain/html.rb', line 106 def initialize(str) @str = str end |
Class Method Details
.of(str) ⇒ SafeString
SafeString.of(str), safe for a String made in the argument itself
(SafeString.of("<a>#{x}</a>")). Under Spinel 2026.09.12 the generated
new allocates the object before it roots its argument, so a garbage
collection in that allocation frees a String that only the argument
holds (a use-after-free that showed as a rare crash under load). The
parameter of an ordinary method is rooted on entry, so going through
one is enough; bind the String to a local first if you call new.
120 121 122 |
# File 'cybertrain/html.rb', line 120 def self.of(str) SafeString.new(str) end |
Instance Method Details
#+(other) ⇒ SafeString
Concatenating with a plain String escapes it first, so building up a SafeString piece by piece never lets unsafe content slip through.
151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'cybertrain/html.rb', line 151 def +(other) # Built in two steps: a case expression whose branches both construct # a SafeString fails to compile when SafeString gets Spinel's unboxed # value-type layout (every SafeString in the program travelling only # as a keyword argument). piece = case other when SafeString then other.to_s # other.to_s rather than other: in a program that never calls # +, Spinel types the unused parameter as an Integer and passed # that type on to Html.escape's (test/router.rb caught it). else Html.escape(other.to_s) end SafeString.of(@str + piece) end |
#to_s ⇒ String
Returns the HTML.
126 127 128 |
# File 'cybertrain/html.rb', line 126 def to_s @str end |