erb 2.2.3 → 4.0.0
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 +4 -4
- data/.github/workflows/test.yml +21 -14
- data/.gitignore +3 -0
- data/Gemfile +5 -2
- data/NEWS.md +25 -4
- data/README.md +1 -1
- data/Rakefile +13 -0
- data/erb.gemspec +10 -3
- data/ext/erb/escape/escape.c +95 -0
- data/ext/erb/escape/extconf.rb +2 -0
- data/lib/erb/compiler.rb +471 -0
- data/lib/erb/def_method.rb +46 -0
- data/lib/erb/util.rb +59 -0
- data/lib/erb/version.rb +1 -1
- data/lib/erb.rb +4 -577
- data/libexec/erb +1 -11
- metadata +18 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7b2863be9c08d529339d060f45fe14a92ddc56e5107c4e96d96f62c5bb3891ef
|
4
|
+
data.tar.gz: 5bedf59f948afda25ce5a9b34ffeba0ec9c8d69cce09ee20a00f63ab0f468363
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f3c5db15f023dd2cca0c76a9fad16746f98d44adc41284308c6baad9eebb75ac3aa54a7a89f3457f9e82ddc62cf7c42ddf1050cd5aef7811b74ab7513822a92f
|
7
|
+
data.tar.gz: dfb6828690e0e3ea9572692534f676d07a952d2db47726f7c3de7da38ca8a970ed4d26525698b56de04bc4956bbd032bf7b2f15515a9f649cc3c0c4dbb02a067
|
data/.github/workflows/test.yml
CHANGED
@@ -1,29 +1,36 @@
|
|
1
1
|
name: test
|
2
2
|
|
3
|
-
on:
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [master]
|
6
|
+
pull_request:
|
7
|
+
workflow_dispatch:
|
4
8
|
|
5
9
|
jobs:
|
6
|
-
|
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
|
7
21
|
name: build (${{ matrix.ruby }} / ${{ matrix.os }})
|
8
22
|
strategy:
|
9
23
|
matrix:
|
10
|
-
ruby:
|
11
|
-
- '2.5'
|
12
|
-
- '2.6'
|
13
|
-
- '2.7'
|
14
|
-
- '3.0'
|
15
|
-
- head
|
24
|
+
ruby: ${{ fromJson(needs.ruby-versions.outputs.versions) }}
|
16
25
|
os: [ubuntu-latest]
|
26
|
+
fail-fast: false
|
17
27
|
runs-on: ${{ matrix.os }}
|
18
28
|
steps:
|
19
|
-
- uses: actions/checkout@
|
29
|
+
- uses: actions/checkout@v2
|
20
30
|
- name: Set up Ruby
|
21
31
|
uses: ruby/setup-ruby@v1
|
22
32
|
with:
|
23
33
|
ruby-version: ${{ matrix.ruby }}
|
24
|
-
|
25
|
-
run: |
|
26
|
-
gem install bundler --no-document
|
27
|
-
bundle install
|
34
|
+
bundler-cache: true
|
28
35
|
- name: Run test
|
29
|
-
run: rake test
|
36
|
+
run: bundle exec rake test
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/NEWS.md
CHANGED
@@ -1,14 +1,35 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 4.0.0
|
4
|
+
|
5
|
+
* Optimize `ERB::Util.html_escape`
|
6
|
+
* No longer duplicate an argument string when nothing is escaped.
|
7
|
+
* This makes `ERB::Util.html_escape` faster than `CGI.escapeHTML` in no-escape cases.
|
8
|
+
* It skips calling `#to_s` when an argument is already a String.
|
9
|
+
* Define `ERB::Escape.html_escape` as an alias to `ERB::Util.html_escape`
|
10
|
+
* `ERB::Util.html_escape` is known to be monkey-patched by Rails.
|
11
|
+
`ERB::Escape.html_escape` is useful when you want a non-monkey-patched version.
|
12
|
+
* Drop deprecated `-S` option from `erb` command
|
13
|
+
|
14
|
+
## 3.0.0
|
15
|
+
|
16
|
+
* Bump `required_ruby_version` to Ruby 2.7+ [#23](https://github.com/ruby/erb/pull/23)
|
17
|
+
* `ERB::Util.url_encode` uses a native implementation [#23](https://github.com/ruby/erb/pull/23)
|
18
|
+
* Fix a bug that a magic comment with a wrong format could be detected [#6](https://github.com/ruby/erb/pull/6)
|
19
|
+
|
20
|
+
## 2.2.3
|
21
|
+
|
22
|
+
* Bump `required_ruby_version` from 2.3 to 2.5 as it has never been supported [#3](https://github.com/ruby/erb/pull/3)
|
23
|
+
|
3
24
|
## 2.2.2
|
4
25
|
|
5
|
-
|
6
|
-
|
26
|
+
* `ERB.version` returns just a version number
|
27
|
+
* `ERB::Revision` is deprecated
|
7
28
|
|
8
29
|
## 2.2.1
|
9
30
|
|
10
|
-
|
31
|
+
* `ERB#initialize` warns `safe_level` and later arguments even without -w
|
11
32
|
|
12
33
|
## 2.2.0
|
13
34
|
|
14
|
-
|
35
|
+
* Ruby 3.0 promoted ERB to a default gem
|
data/README.md
CHANGED
@@ -32,7 +32,7 @@ on the rules below:
|
|
32
32
|
```erb
|
33
33
|
<% Ruby code -- inline with output %>
|
34
34
|
<%= Ruby expression -- replace with result %>
|
35
|
-
<%# comment -- ignored -- useful in testing %>
|
35
|
+
<%# comment -- ignored -- useful in testing %> (`<% #` doesn't work. Don't use Ruby comments.)
|
36
36
|
% a line of Ruby code -- treated as <% line %> (optional -- see ERB.new)
|
37
37
|
%% replaced with % if first thing on a line and % processing is used
|
38
38
|
<%% or %%> -- replace with <% or %> respectively
|
data/Rakefile
CHANGED
@@ -7,4 +7,17 @@ Rake::TestTask.new(:test) do |t|
|
|
7
7
|
t.test_files = FileList['test/**/test_*.rb']
|
8
8
|
end
|
9
9
|
|
10
|
+
if RUBY_ENGINE != 'jruby'
|
11
|
+
require 'rake/extensiontask'
|
12
|
+
Rake::ExtensionTask.new('erb/escape')
|
13
|
+
task test: :compile
|
14
|
+
end
|
15
|
+
|
16
|
+
task :sync_tool do
|
17
|
+
require 'fileutils'
|
18
|
+
FileUtils.cp '../ruby/tool/lib/core_assertions.rb', './test/lib'
|
19
|
+
FileUtils.cp '../ruby/tool/lib/envutil.rb', './test/lib'
|
20
|
+
FileUtils.cp '../ruby/tool/lib/find_executable.rb', './test/lib'
|
21
|
+
end
|
22
|
+
|
10
23
|
task default: :test
|
data/erb.gemspec
CHANGED
@@ -8,8 +8,8 @@ end
|
|
8
8
|
Gem::Specification.new do |spec|
|
9
9
|
spec.name = 'erb'
|
10
10
|
spec.version = ERB.const_get(:VERSION, false)
|
11
|
-
spec.authors = ['Masatoshi SEKI']
|
12
|
-
spec.email = ['seki@ruby-lang.org']
|
11
|
+
spec.authors = ['Masatoshi SEKI', 'Takashi Kokubun']
|
12
|
+
spec.email = ['seki@ruby-lang.org', 'takashikkbn@gmail.com']
|
13
13
|
|
14
14
|
spec.summary = %q{An easy to use but powerful templating system for Ruby.}
|
15
15
|
spec.description = %q{An easy to use but powerful templating system for Ruby.}
|
@@ -27,5 +27,12 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.executables = ['erb']
|
28
28
|
spec.require_paths = ['lib']
|
29
29
|
|
30
|
-
|
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'
|
31
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
|
+
}
|