erb 4.0.1-java
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 +7 -0
- data/.github/workflows/test.yml +36 -0
- data/.gitignore +12 -0
- data/Gemfile +9 -0
- data/LICENSE.txt +22 -0
- data/NEWS.md +39 -0
- data/README.md +255 -0
- data/Rakefile +26 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/erb.gemspec +38 -0
- data/ext/erb/escape/escape.c +95 -0
- data/ext/erb/escape/extconf.rb +7 -0
- data/lib/erb/compiler.rb +471 -0
- data/lib/erb/def_method.rb +46 -0
- data/lib/erb/util.rb +62 -0
- data/lib/erb/version.rb +5 -0
- data/lib/erb.rb +506 -0
- data/libexec/erb +164 -0
- metadata +81 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5013347602fe04849ab4f30713e5f33c3119e4a8de6f3de31dc2a39108d70a46
|
4
|
+
data.tar.gz: cc71c6d4bdb04f39d35873317b340289e372b27cd343fbb596d2d0d9c18dbbd0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ae29c46417424d5487c271975695ee21d5e437b3d8adbed5303dbb6aeef8d35401255d8527cf6c17bff84001d57112bad69c4272075e9c1251ea26b075662091
|
7
|
+
data.tar.gz: b33d009e86b08846aaeef2652add1251288bcbc245900cde13dd0762bf7c7f74228da036b00732bc7efb50f291c68969c41af70d2ab6debfb1b75f8aa2adeb4b
|
@@ -0,0 +1,36 @@
|
|
1
|
+
name: test
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [master]
|
6
|
+
pull_request:
|
7
|
+
workflow_dispatch:
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
ruby-versions:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
outputs:
|
13
|
+
versions: ${{ steps.versions.outputs.value }}
|
14
|
+
steps:
|
15
|
+
- id: versions
|
16
|
+
run: |
|
17
|
+
versions=$(curl -s 'https://cache.ruby-lang.org/pub/misc/ci_versions/cruby.json' | jq -c '. + ["jruby", "truffleruby-head"]')
|
18
|
+
echo "::set-output name=value::${versions}"
|
19
|
+
test:
|
20
|
+
needs: ruby-versions
|
21
|
+
name: build (${{ matrix.ruby }} / ${{ matrix.os }})
|
22
|
+
strategy:
|
23
|
+
matrix:
|
24
|
+
ruby: ${{ fromJson(needs.ruby-versions.outputs.versions) }}
|
25
|
+
os: [ubuntu-latest]
|
26
|
+
fail-fast: false
|
27
|
+
runs-on: ${{ matrix.os }}
|
28
|
+
steps:
|
29
|
+
- uses: actions/checkout@v2
|
30
|
+
- name: Set up Ruby
|
31
|
+
uses: ruby/setup-ruby@v1
|
32
|
+
with:
|
33
|
+
ruby-version: ${{ matrix.ruby }}
|
34
|
+
bundler-cache: true
|
35
|
+
- name: Run test
|
36
|
+
run: bundle exec rake test
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved.
|
2
|
+
|
3
|
+
Redistribution and use in source and binary forms, with or without
|
4
|
+
modification, are permitted provided that the following conditions
|
5
|
+
are met:
|
6
|
+
1. Redistributions of source code must retain the above copyright
|
7
|
+
notice, this list of conditions and the following disclaimer.
|
8
|
+
2. Redistributions in binary form must reproduce the above copyright
|
9
|
+
notice, this list of conditions and the following disclaimer in the
|
10
|
+
documentation and/or other materials provided with the distribution.
|
11
|
+
|
12
|
+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
13
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
14
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
15
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
16
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
17
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
18
|
+
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
19
|
+
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
20
|
+
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
21
|
+
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
22
|
+
SUCH DAMAGE.
|
data/NEWS.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# Change Log
|
2
|
+
|
3
|
+
## 4.0.1
|
4
|
+
|
5
|
+
* Stop building the C extension for TruffleRuby [#39](https://github.com/ruby/erb/pull/39)
|
6
|
+
|
7
|
+
## 4.0.0
|
8
|
+
|
9
|
+
* Optimize `ERB::Util.html_escape` [#27](https://github.com/ruby/erb/pull/27)
|
10
|
+
* No longer duplicate an argument string when nothing is escaped.
|
11
|
+
* This makes `ERB::Util.html_escape` faster than `CGI.escapeHTML` in no-escape cases.
|
12
|
+
* It skips calling `#to_s` when an argument is already a String.
|
13
|
+
* Define `ERB::Escape.html_escape` as an alias to `ERB::Util.html_escape` [#38](https://github.com/ruby/erb/pull/38)
|
14
|
+
* `ERB::Util.html_escape` is known to be monkey-patched by Rails.
|
15
|
+
`ERB::Escape.html_escape` is useful when you want a non-monkey-patched version.
|
16
|
+
* Drop deprecated `-S` option from `erb` command
|
17
|
+
|
18
|
+
## 3.0.0
|
19
|
+
|
20
|
+
* Bump `required_ruby_version` to Ruby 2.7+ [#23](https://github.com/ruby/erb/pull/23)
|
21
|
+
* `ERB::Util.url_encode` uses a native implementation [#23](https://github.com/ruby/erb/pull/23)
|
22
|
+
* Fix a bug that a magic comment with a wrong format could be detected [#6](https://github.com/ruby/erb/pull/6)
|
23
|
+
|
24
|
+
## 2.2.3
|
25
|
+
|
26
|
+
* Bump `required_ruby_version` from 2.3 to 2.5 as it has never been supported [#3](https://github.com/ruby/erb/pull/3)
|
27
|
+
|
28
|
+
## 2.2.2
|
29
|
+
|
30
|
+
* `ERB.version` returns just a version number
|
31
|
+
* `ERB::Revision` is deprecated
|
32
|
+
|
33
|
+
## 2.2.1
|
34
|
+
|
35
|
+
* `ERB#initialize` warns `safe_level` and later arguments even without -w
|
36
|
+
|
37
|
+
## 2.2.0
|
38
|
+
|
39
|
+
* Ruby 3.0 promoted ERB to a default gem
|
data/README.md
ADDED
@@ -0,0 +1,255 @@
|
|
1
|
+
# ERB
|
2
|
+
|
3
|
+
An easy to use but powerful templating system for Ruby.
|
4
|
+
|
5
|
+
## Introduction
|
6
|
+
|
7
|
+
ERB provides an easy to use but powerful templating system for Ruby. Using
|
8
|
+
ERB, actual Ruby code can be added to any plain text document for the
|
9
|
+
purposes of generating document information details and/or flow control.
|
10
|
+
|
11
|
+
A very simple example is this:
|
12
|
+
|
13
|
+
```rb
|
14
|
+
require 'erb'
|
15
|
+
|
16
|
+
x = 42
|
17
|
+
template = ERB.new <<-EOF
|
18
|
+
The value of x is: <%= x %>
|
19
|
+
EOF
|
20
|
+
puts template.result(binding)
|
21
|
+
```
|
22
|
+
|
23
|
+
Prints: `The value of x is: 42`
|
24
|
+
|
25
|
+
More complex examples are given below.
|
26
|
+
|
27
|
+
## Recognized Tags
|
28
|
+
|
29
|
+
ERB recognizes certain tags in the provided template and converts them based
|
30
|
+
on the rules below:
|
31
|
+
|
32
|
+
```erb
|
33
|
+
<% Ruby code -- inline with output %>
|
34
|
+
<%= Ruby expression -- replace with result %>
|
35
|
+
<%# comment -- ignored -- useful in testing %> (`<% #` doesn't work. Don't use Ruby comments.)
|
36
|
+
% a line of Ruby code -- treated as <% line %> (optional -- see ERB.new)
|
37
|
+
%% replaced with % if first thing on a line and % processing is used
|
38
|
+
<%% or %%> -- replace with <% or %> respectively
|
39
|
+
```
|
40
|
+
|
41
|
+
All other text is passed through ERB filtering unchanged.
|
42
|
+
|
43
|
+
## Options
|
44
|
+
|
45
|
+
There are several settings you can change when you use ERB:
|
46
|
+
* the nature of the tags that are recognized;
|
47
|
+
* the binding used to resolve local variables in the template.
|
48
|
+
|
49
|
+
See the ERB.new and ERB#result methods for more detail.
|
50
|
+
|
51
|
+
## Character encodings
|
52
|
+
|
53
|
+
ERB (or Ruby code generated by ERB) returns a string in the same
|
54
|
+
character encoding as the input string. When the input string has
|
55
|
+
a magic comment, however, it returns a string in the encoding specified
|
56
|
+
by the magic comment.
|
57
|
+
|
58
|
+
```rb
|
59
|
+
# -*- coding: utf-8 -*-
|
60
|
+
require 'erb'
|
61
|
+
|
62
|
+
template = ERB.new <<EOF
|
63
|
+
<%#-*- coding: Big5 -*-%>
|
64
|
+
__ENCODING__ is <%= __ENCODING__ %>.
|
65
|
+
EOF
|
66
|
+
puts template.result
|
67
|
+
```
|
68
|
+
|
69
|
+
Prints: `__ENCODING__ is Big5.`
|
70
|
+
|
71
|
+
## Examples
|
72
|
+
|
73
|
+
### Plain Text
|
74
|
+
|
75
|
+
ERB is useful for any generic templating situation. Note that in this example, we use the
|
76
|
+
convenient "% at start of line" tag, and we quote the template literally with
|
77
|
+
`%q{...}` to avoid trouble with the backslash.
|
78
|
+
|
79
|
+
```rb
|
80
|
+
require "erb"
|
81
|
+
|
82
|
+
# Create template.
|
83
|
+
template = %q{
|
84
|
+
From: James Edward Gray II <james@grayproductions.net>
|
85
|
+
To: <%= to %>
|
86
|
+
Subject: Addressing Needs
|
87
|
+
|
88
|
+
<%= to[/\w+/] %>:
|
89
|
+
|
90
|
+
Just wanted to send a quick note assuring that your needs are being
|
91
|
+
addressed.
|
92
|
+
|
93
|
+
I want you to know that my team will keep working on the issues,
|
94
|
+
especially:
|
95
|
+
|
96
|
+
<%# ignore numerous minor requests -- focus on priorities %>
|
97
|
+
% priorities.each do |priority|
|
98
|
+
* <%= priority %>
|
99
|
+
% end
|
100
|
+
|
101
|
+
Thanks for your patience.
|
102
|
+
|
103
|
+
James Edward Gray II
|
104
|
+
}.gsub(/^ /, '')
|
105
|
+
|
106
|
+
message = ERB.new(template, trim_mode: "%<>")
|
107
|
+
|
108
|
+
# Set up template data.
|
109
|
+
to = "Community Spokesman <spokesman@ruby_community.org>"
|
110
|
+
priorities = [ "Run Ruby Quiz",
|
111
|
+
"Document Modules",
|
112
|
+
"Answer Questions on Ruby Talk" ]
|
113
|
+
|
114
|
+
# Produce result.
|
115
|
+
email = message.result
|
116
|
+
puts email
|
117
|
+
```
|
118
|
+
|
119
|
+
Generates:
|
120
|
+
|
121
|
+
```
|
122
|
+
From: James Edward Gray II <james@grayproductions.net>
|
123
|
+
To: Community Spokesman <spokesman@ruby_community.org>
|
124
|
+
Subject: Addressing Needs
|
125
|
+
|
126
|
+
Community:
|
127
|
+
|
128
|
+
Just wanted to send a quick note assuring that your needs are being addressed.
|
129
|
+
|
130
|
+
I want you to know that my team will keep working on the issues, especially:
|
131
|
+
|
132
|
+
* Run Ruby Quiz
|
133
|
+
* Document Modules
|
134
|
+
* Answer Questions on Ruby Talk
|
135
|
+
|
136
|
+
Thanks for your patience.
|
137
|
+
|
138
|
+
James Edward Gray II
|
139
|
+
```
|
140
|
+
|
141
|
+
### Ruby in HTML
|
142
|
+
|
143
|
+
ERB is often used in .rhtml files (HTML with embedded Ruby). Notice the need in
|
144
|
+
this example to provide a special binding when the template is run, so that the instance
|
145
|
+
variables in the Product object can be resolved.
|
146
|
+
|
147
|
+
```rb
|
148
|
+
require "erb"
|
149
|
+
|
150
|
+
# Build template data class.
|
151
|
+
class Product
|
152
|
+
def initialize( code, name, desc, cost )
|
153
|
+
@code = code
|
154
|
+
@name = name
|
155
|
+
@desc = desc
|
156
|
+
@cost = cost
|
157
|
+
|
158
|
+
@features = [ ]
|
159
|
+
end
|
160
|
+
|
161
|
+
def add_feature( feature )
|
162
|
+
@features << feature
|
163
|
+
end
|
164
|
+
|
165
|
+
# Support templating of member data.
|
166
|
+
def get_binding
|
167
|
+
binding
|
168
|
+
end
|
169
|
+
|
170
|
+
# ...
|
171
|
+
end
|
172
|
+
|
173
|
+
# Create template.
|
174
|
+
template = %{
|
175
|
+
<html>
|
176
|
+
<head><title>Ruby Toys -- <%= @name %></title></head>
|
177
|
+
<body>
|
178
|
+
|
179
|
+
<h1><%= @name %> (<%= @code %>)</h1>
|
180
|
+
<p><%= @desc %></p>
|
181
|
+
|
182
|
+
<ul>
|
183
|
+
<% @features.each do |f| %>
|
184
|
+
<li><b><%= f %></b></li>
|
185
|
+
<% end %>
|
186
|
+
</ul>
|
187
|
+
|
188
|
+
<p>
|
189
|
+
<% if @cost < 10 %>
|
190
|
+
<b>Only <%= @cost %>!!!</b>
|
191
|
+
<% else %>
|
192
|
+
Call for a price, today!
|
193
|
+
<% end %>
|
194
|
+
</p>
|
195
|
+
|
196
|
+
</body>
|
197
|
+
</html>
|
198
|
+
}.gsub(/^ /, '')
|
199
|
+
|
200
|
+
rhtml = ERB.new(template)
|
201
|
+
|
202
|
+
# Set up template data.
|
203
|
+
toy = Product.new( "TZ-1002",
|
204
|
+
"Rubysapien",
|
205
|
+
"Geek's Best Friend! Responds to Ruby commands...",
|
206
|
+
999.95 )
|
207
|
+
toy.add_feature("Listens for verbal commands in the Ruby language!")
|
208
|
+
toy.add_feature("Ignores Perl, Java, and all C variants.")
|
209
|
+
toy.add_feature("Karate-Chop Action!!!")
|
210
|
+
toy.add_feature("Matz signature on left leg.")
|
211
|
+
toy.add_feature("Gem studded eyes... Rubies, of course!")
|
212
|
+
|
213
|
+
# Produce result.
|
214
|
+
rhtml.run(toy.get_binding)
|
215
|
+
```
|
216
|
+
|
217
|
+
Generates (some blank lines removed):
|
218
|
+
|
219
|
+
```html
|
220
|
+
<html>
|
221
|
+
<head><title>Ruby Toys -- Rubysapien</title></head>
|
222
|
+
<body>
|
223
|
+
|
224
|
+
<h1>Rubysapien (TZ-1002)</h1>
|
225
|
+
<p>Geek's Best Friend! Responds to Ruby commands...</p>
|
226
|
+
|
227
|
+
<ul>
|
228
|
+
<li><b>Listens for verbal commands in the Ruby language!</b></li>
|
229
|
+
<li><b>Ignores Perl, Java, and all C variants.</b></li>
|
230
|
+
<li><b>Karate-Chop Action!!!</b></li>
|
231
|
+
<li><b>Matz signature on left leg.</b></li>
|
232
|
+
<li><b>Gem studded eyes... Rubies, of course!</b></li>
|
233
|
+
</ul>
|
234
|
+
|
235
|
+
<p>
|
236
|
+
Call for a price, today!
|
237
|
+
</p>
|
238
|
+
|
239
|
+
</body>
|
240
|
+
</html>
|
241
|
+
```
|
242
|
+
|
243
|
+
## Notes
|
244
|
+
|
245
|
+
There are a variety of templating solutions available in various Ruby projects.
|
246
|
+
For example, RDoc, distributed with Ruby, uses its own template engine, which
|
247
|
+
can be reused elsewhere.
|
248
|
+
|
249
|
+
Other popular engines could be found in the corresponding
|
250
|
+
[Category](https://www.ruby-toolbox.com/categories/template_engines) of
|
251
|
+
The Ruby Toolbox.
|
252
|
+
|
253
|
+
## License
|
254
|
+
|
255
|
+
The gem is available as open source under the terms of the [2-Clause BSD License](https://opensource.org/licenses/BSD-2-Clause).
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rake/testtask'
|
3
|
+
|
4
|
+
Rake::TestTask.new(:test) do |t|
|
5
|
+
t.libs << 'test/lib'
|
6
|
+
t.ruby_opts << '-rhelper'
|
7
|
+
t.test_files = FileList['test/**/test_*.rb']
|
8
|
+
end
|
9
|
+
|
10
|
+
case RUBY_ENGINE
|
11
|
+
when 'jruby', 'truffleruby'
|
12
|
+
# not using C extension
|
13
|
+
else
|
14
|
+
require 'rake/extensiontask'
|
15
|
+
Rake::ExtensionTask.new('erb/escape')
|
16
|
+
task test: :compile
|
17
|
+
end
|
18
|
+
|
19
|
+
task :sync_tool do
|
20
|
+
require 'fileutils'
|
21
|
+
FileUtils.cp '../ruby/tool/lib/core_assertions.rb', './test/lib'
|
22
|
+
FileUtils.cp '../ruby/tool/lib/envutil.rb', './test/lib'
|
23
|
+
FileUtils.cp '../ruby/tool/lib/find_executable.rb', './test/lib'
|
24
|
+
end
|
25
|
+
|
26
|
+
task default: :test
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "erb"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/erb.gemspec
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
begin
|
2
|
+
require_relative 'lib/erb/version'
|
3
|
+
rescue LoadError
|
4
|
+
# for Ruby core repository
|
5
|
+
require_relative 'erb/version'
|
6
|
+
end
|
7
|
+
|
8
|
+
Gem::Specification.new do |spec|
|
9
|
+
spec.name = 'erb'
|
10
|
+
spec.version = ERB.const_get(:VERSION, false)
|
11
|
+
spec.authors = ['Masatoshi SEKI', 'Takashi Kokubun']
|
12
|
+
spec.email = ['seki@ruby-lang.org', 'takashikkbn@gmail.com']
|
13
|
+
|
14
|
+
spec.summary = %q{An easy to use but powerful templating system for Ruby.}
|
15
|
+
spec.description = %q{An easy to use but powerful templating system for Ruby.}
|
16
|
+
spec.homepage = 'https://github.com/ruby/erb'
|
17
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.5.0')
|
18
|
+
spec.licenses = ['Ruby', 'BSD-2-Clause']
|
19
|
+
|
20
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
21
|
+
spec.metadata['source_code_uri'] = spec.homepage
|
22
|
+
|
23
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
24
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
25
|
+
end
|
26
|
+
spec.bindir = 'libexec'
|
27
|
+
spec.executables = ['erb']
|
28
|
+
spec.require_paths = ['lib']
|
29
|
+
|
30
|
+
if RUBY_ENGINE == 'jruby'
|
31
|
+
spec.platform = 'java'
|
32
|
+
else
|
33
|
+
spec.required_ruby_version = '>= 2.7.0'
|
34
|
+
spec.extensions = ['ext/erb/escape/extconf.rb']
|
35
|
+
end
|
36
|
+
|
37
|
+
spec.add_dependency 'cgi', '>= 0.3.3'
|
38
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
#include "ruby.h"
|
2
|
+
#include "ruby/encoding.h"
|
3
|
+
|
4
|
+
static VALUE rb_cERB, rb_mEscape, rb_cCGI;
|
5
|
+
static ID id_escapeHTML;
|
6
|
+
|
7
|
+
#define HTML_ESCAPE_MAX_LEN 6
|
8
|
+
|
9
|
+
static const struct {
|
10
|
+
uint8_t len;
|
11
|
+
char str[HTML_ESCAPE_MAX_LEN+1];
|
12
|
+
} html_escape_table[UCHAR_MAX+1] = {
|
13
|
+
#define HTML_ESCAPE(c, str) [c] = {rb_strlen_lit(str), str}
|
14
|
+
HTML_ESCAPE('\'', "'"),
|
15
|
+
HTML_ESCAPE('&', "&"),
|
16
|
+
HTML_ESCAPE('"', """),
|
17
|
+
HTML_ESCAPE('<', "<"),
|
18
|
+
HTML_ESCAPE('>', ">"),
|
19
|
+
#undef HTML_ESCAPE
|
20
|
+
};
|
21
|
+
|
22
|
+
static inline void
|
23
|
+
preserve_original_state(VALUE orig, VALUE dest)
|
24
|
+
{
|
25
|
+
rb_enc_associate(dest, rb_enc_get(orig));
|
26
|
+
}
|
27
|
+
|
28
|
+
static inline long
|
29
|
+
escaped_length(VALUE str)
|
30
|
+
{
|
31
|
+
const long len = RSTRING_LEN(str);
|
32
|
+
if (len >= LONG_MAX / HTML_ESCAPE_MAX_LEN) {
|
33
|
+
ruby_malloc_size_overflow(len, HTML_ESCAPE_MAX_LEN);
|
34
|
+
}
|
35
|
+
return len * HTML_ESCAPE_MAX_LEN;
|
36
|
+
}
|
37
|
+
|
38
|
+
static VALUE
|
39
|
+
optimized_escape_html(VALUE str)
|
40
|
+
{
|
41
|
+
VALUE vbuf;
|
42
|
+
char *buf = ALLOCV_N(char, vbuf, escaped_length(str));
|
43
|
+
const char *cstr = RSTRING_PTR(str);
|
44
|
+
const char *end = cstr + RSTRING_LEN(str);
|
45
|
+
|
46
|
+
char *dest = buf;
|
47
|
+
while (cstr < end) {
|
48
|
+
const unsigned char c = *cstr++;
|
49
|
+
uint8_t len = html_escape_table[c].len;
|
50
|
+
if (len) {
|
51
|
+
memcpy(dest, html_escape_table[c].str, len);
|
52
|
+
dest += len;
|
53
|
+
}
|
54
|
+
else {
|
55
|
+
*dest++ = c;
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
59
|
+
VALUE escaped = str;
|
60
|
+
if (RSTRING_LEN(str) < (dest - buf)) {
|
61
|
+
escaped = rb_str_new(buf, dest - buf);
|
62
|
+
preserve_original_state(str, escaped);
|
63
|
+
}
|
64
|
+
ALLOCV_END(vbuf);
|
65
|
+
return escaped;
|
66
|
+
}
|
67
|
+
|
68
|
+
// ERB::Util.html_escape is different from CGI.escapeHTML in the following two parts:
|
69
|
+
// * ERB::Util.html_escape converts an argument with #to_s first (only if it's not T_STRING)
|
70
|
+
// * ERB::Util.html_escape does not allocate a new string when nothing needs to be escaped
|
71
|
+
static VALUE
|
72
|
+
erb_escape_html(VALUE self, VALUE str)
|
73
|
+
{
|
74
|
+
if (!RB_TYPE_P(str, T_STRING)) {
|
75
|
+
str = rb_convert_type(str, T_STRING, "String", "to_s");
|
76
|
+
}
|
77
|
+
|
78
|
+
if (rb_enc_str_asciicompat_p(str)) {
|
79
|
+
return optimized_escape_html(str);
|
80
|
+
}
|
81
|
+
else {
|
82
|
+
return rb_funcall(rb_cCGI, id_escapeHTML, 1, str);
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
86
|
+
void
|
87
|
+
Init_escape(void)
|
88
|
+
{
|
89
|
+
rb_cERB = rb_define_class("ERB", rb_cObject);
|
90
|
+
rb_mEscape = rb_define_module_under(rb_cERB, "Escape");
|
91
|
+
rb_define_module_function(rb_mEscape, "html_escape", erb_escape_html, 1);
|
92
|
+
|
93
|
+
rb_cCGI = rb_define_class("CGI", rb_cObject);
|
94
|
+
id_escapeHTML = rb_intern("escapeHTML");
|
95
|
+
}
|