re2 2.6.0-x86_64-darwin → 2.7.0-x86_64-darwin
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +1 -0
- data/README.md +10 -8
- data/ext/re2/re2.cc +63 -30
- data/lib/2.6/re2.bundle +0 -0
- data/lib/2.7/re2.bundle +0 -0
- data/lib/3.0/re2.bundle +0 -0
- data/lib/3.1/re2.bundle +0 -0
- data/lib/3.2/re2.bundle +0 -0
- data/lib/3.3/re2.bundle +0 -0
- data/lib/re2/version.rb +1 -1
- data/spec/kernel_spec.rb +6 -0
- data/spec/re2/match_data_spec.rb +31 -1
- data/spec/re2/regexp_spec.rb +52 -0
- data/spec/re2/scanner_spec.rb +22 -0
- data/spec/re2/set_spec.rb +8 -0
- data/spec/re2_spec.rb +28 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b3d561ebca37b0f52e12e7261e0c2ce5ea111b5c8284aa5f96c5df8d803c537f
|
4
|
+
data.tar.gz: d8c00938e828728f92733b909bc1b9dbac548fe5d99c58e4e1b8afa856d993dc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 823450f5a1bfe418695ca313676576a5c8f9a57d63b3dc44b52390eb1d81236fafc3073341810bc03255384181f929101c2e896304d79e3d05a034aafaf7f456
|
7
|
+
data.tar.gz: e233c08e0b6a7fd71ee22286aa9ee1066a4659f244537c537e99307cef7bd5db618ff9f1942912f71f8ac0e82b8e3a6fc3f5535b5bfe7e8fc5e8dbdc1334841b
|
data/.rspec
CHANGED
data/README.md
CHANGED
@@ -6,7 +6,7 @@ Python".
|
|
6
6
|
|
7
7
|
[![Build Status](https://github.com/mudge/re2/actions/workflows/tests.yml/badge.svg?branch=main)](https://github.com/mudge/re2/actions)
|
8
8
|
|
9
|
-
**Current version:** 2.
|
9
|
+
**Current version:** 2.7.0
|
10
10
|
**Bundled RE2 version:** libre2.11 (2023-11-01)
|
11
11
|
|
12
12
|
```ruby
|
@@ -279,18 +279,18 @@ Where possible, a pre-compiled native gem will be provided for the following pla
|
|
279
279
|
SHA256 checksums are included in the [release notes](https://github.com/mudge/re2/releases) for each version and can be checked with `sha256sum`, e.g.
|
280
280
|
|
281
281
|
```console
|
282
|
-
$ gem fetch re2 -v 2.
|
283
|
-
Fetching re2-2.
|
284
|
-
Downloaded re2-2.
|
285
|
-
$ sha256sum re2-2.
|
286
|
-
|
282
|
+
$ gem fetch re2 -v 2.6.0
|
283
|
+
Fetching re2-2.6.0-arm64-darwin.gem
|
284
|
+
Downloaded re2-2.6.0-arm64-darwin
|
285
|
+
$ sha256sum re2-2.6.0-arm64-darwin.gem
|
286
|
+
ba6fda7a29cd16179d5401c1b4917ba204c92e5ca9d25df80d840ed76fca439f re2-2.6.0-arm64-darwin.gem
|
287
287
|
```
|
288
288
|
|
289
289
|
[GPG](https://www.gnupg.org/) signatures are attached to each release (the assets ending in `.sig`) and can be verified if you import [our signing key `0x39AC3530070E0F75`](https://mudge.name/39AC3530070E0F75.asc) (or fetch it from a public keyserver, e.g. `gpg --keyserver keyserver.ubuntu.com --recv-key 0x39AC3530070E0F75`):
|
290
290
|
|
291
291
|
```console
|
292
|
-
$ gpg --verify re2-2.
|
293
|
-
gpg: Signature made
|
292
|
+
$ gpg --verify re2-2.6.0-arm64-darwin.gem.sig re2-2.6.0-arm64-darwin.gem
|
293
|
+
gpg: Signature made Wed 27 Dec 19:26:53 2023 GMT
|
294
294
|
gpg: using RSA key 702609D9C790F45B577D7BEC39AC3530070E0F75
|
295
295
|
gpg: Good signature from "Paul Mucur <mudge@mudge.name>" [unknown]
|
296
296
|
gpg: aka "Paul Mucur <paul@ghostcassette.com>" [unknown]
|
@@ -373,6 +373,8 @@ Alternatively, you can set the `RE2_USE_SYSTEM_LIBRARIES` environment variable i
|
|
373
373
|
* Thanks to [Jean Boussier](https://github.com/byroot) for contributing the
|
374
374
|
switch to Ruby's `TypedData` API and the resulting garbage collection
|
375
375
|
improvements in 2.4.0.
|
376
|
+
* Thanks to [Manuel Jacob](https://github.com/manueljacob) for reporting a bug
|
377
|
+
when passing strings with null bytes.
|
376
378
|
|
377
379
|
## Contact
|
378
380
|
|
data/ext/re2/re2.cc
CHANGED
@@ -336,7 +336,8 @@ static VALUE re2_scanner_rewind(VALUE self) {
|
|
336
336
|
TypedData_Get_Struct(self, re2_scanner, &re2_scanner_data_type, c);
|
337
337
|
|
338
338
|
delete c->input;
|
339
|
-
c->input = new(std::nothrow) re2::StringPiece(
|
339
|
+
c->input = new(std::nothrow) re2::StringPiece(
|
340
|
+
RSTRING_PTR(c->text), RSTRING_LEN(c->text));
|
340
341
|
c->eof = false;
|
341
342
|
|
342
343
|
return self;
|
@@ -425,10 +426,20 @@ static re2::StringPiece *re2_matchdata_find_match(VALUE idx, const VALUE self) {
|
|
425
426
|
|
426
427
|
if (FIXNUM_P(idx)) {
|
427
428
|
id = FIX2INT(idx);
|
429
|
+
} else if (SYMBOL_P(idx)) {
|
430
|
+
const std::map<std::string, int>& groups = p->pattern->NamedCapturingGroups();
|
431
|
+
std::map<std::string, int>::const_iterator search = groups.find(rb_id2name(SYM2ID(idx)));
|
432
|
+
|
433
|
+
if (search != groups.end()) {
|
434
|
+
id = search->second;
|
435
|
+
} else {
|
436
|
+
return NULL;
|
437
|
+
}
|
428
438
|
} else {
|
429
|
-
|
439
|
+
StringValue(idx);
|
440
|
+
|
430
441
|
const std::map<std::string, int>& groups = p->pattern->NamedCapturingGroups();
|
431
|
-
std::map<std::string, int>::const_iterator search = groups.find(
|
442
|
+
std::map<std::string, int>::const_iterator search = groups.find(std::string(RSTRING_PTR(idx), RSTRING_LEN(idx)));
|
432
443
|
|
433
444
|
if (search != groups.end()) {
|
434
445
|
id = search->second;
|
@@ -611,7 +622,7 @@ static VALUE re2_matchdata_nth_match(int nth, const VALUE self) {
|
|
611
622
|
}
|
612
623
|
}
|
613
624
|
|
614
|
-
static VALUE re2_matchdata_named_match(const
|
625
|
+
static VALUE re2_matchdata_named_match(const std::string &name, const VALUE self) {
|
615
626
|
re2_matchdata *m;
|
616
627
|
re2_pattern *p;
|
617
628
|
|
@@ -678,7 +689,8 @@ static VALUE re2_matchdata_aref(int argc, VALUE *argv, const VALUE self) {
|
|
678
689
|
rb_scan_args(argc, argv, "11", &idx, &rest);
|
679
690
|
|
680
691
|
if (TYPE(idx) == T_STRING) {
|
681
|
-
return re2_matchdata_named_match(
|
692
|
+
return re2_matchdata_named_match(
|
693
|
+
std::string(RSTRING_PTR(idx), RSTRING_LEN(idx)), self);
|
682
694
|
} else if (SYMBOL_P(idx)) {
|
683
695
|
return re2_matchdata_named_match(rb_id2name(SYM2ID(idx)), self);
|
684
696
|
} else if (!NIL_P(rest) || !FIXNUM_P(idx) || FIX2INT(idx) < 0) {
|
@@ -731,7 +743,8 @@ static VALUE re2_matchdata_inspect(const VALUE self) {
|
|
731
743
|
if (match == Qnil) {
|
732
744
|
output << "nil";
|
733
745
|
} else {
|
734
|
-
output << "\"" << RSTRING_PTR(match)
|
746
|
+
output << "\"" << re2::StringPiece(RSTRING_PTR(match),
|
747
|
+
RSTRING_LEN(match)) << "\"";
|
735
748
|
}
|
736
749
|
}
|
737
750
|
|
@@ -910,9 +923,11 @@ static VALUE re2_regexp_initialize(int argc, VALUE *argv, VALUE self) {
|
|
910
923
|
RE2::Options re2_options;
|
911
924
|
parse_re2_options(&re2_options, options);
|
912
925
|
|
913
|
-
p->pattern = new(std::nothrow) RE2(
|
926
|
+
p->pattern = new(std::nothrow) RE2(
|
927
|
+
re2::StringPiece(RSTRING_PTR(pattern), RSTRING_LEN(pattern)), re2_options);
|
914
928
|
} else {
|
915
|
-
p->pattern = new(std::nothrow) RE2(
|
929
|
+
p->pattern = new(std::nothrow) RE2(
|
930
|
+
re2::StringPiece(RSTRING_PTR(pattern), RSTRING_LEN(pattern)));
|
916
931
|
}
|
917
932
|
|
918
933
|
if (p->pattern == 0) {
|
@@ -1501,11 +1516,13 @@ static VALUE re2_regexp_match(int argc, VALUE *argv, const VALUE self) {
|
|
1501
1516
|
|
1502
1517
|
if (n == 0) {
|
1503
1518
|
#ifdef HAVE_ENDPOS_ARGUMENT
|
1504
|
-
bool matched = p->pattern->Match(
|
1505
|
-
|
1519
|
+
bool matched = p->pattern->Match(
|
1520
|
+
re2::StringPiece(RSTRING_PTR(text), RSTRING_LEN(text)),
|
1521
|
+
startpos, endpos, anchor, 0, 0);
|
1506
1522
|
#else
|
1507
|
-
bool matched = p->pattern->Match(
|
1508
|
-
|
1523
|
+
bool matched = p->pattern->Match(
|
1524
|
+
re2::StringPiece(RSTRING_PTR(text), RSTRING_LEN(text)),
|
1525
|
+
startpos, anchor, 0, 0);
|
1509
1526
|
#endif
|
1510
1527
|
return BOOL2RUBY(matched);
|
1511
1528
|
} else {
|
@@ -1529,11 +1546,13 @@ static VALUE re2_regexp_match(int argc, VALUE *argv, const VALUE self) {
|
|
1529
1546
|
m->number_of_matches = n;
|
1530
1547
|
|
1531
1548
|
#ifdef HAVE_ENDPOS_ARGUMENT
|
1532
|
-
bool matched = p->pattern->Match(
|
1533
|
-
|
1549
|
+
bool matched = p->pattern->Match(
|
1550
|
+
re2::StringPiece(RSTRING_PTR(m->text), RSTRING_LEN(m->text)),
|
1551
|
+
startpos, endpos, anchor, m->matches, n);
|
1534
1552
|
#else
|
1535
|
-
bool matched = p->pattern->Match(
|
1536
|
-
|
1553
|
+
bool matched = p->pattern->Match(
|
1554
|
+
re2::StringPiece(RSTRING_PTR(m->text), RSTRING_LEN(m->text)),
|
1555
|
+
startpos, anchor, m->matches, n);
|
1537
1556
|
#endif
|
1538
1557
|
if (matched) {
|
1539
1558
|
return matchdata;
|
@@ -1559,7 +1578,8 @@ static VALUE re2_regexp_match_p(const VALUE self, VALUE text) {
|
|
1559
1578
|
|
1560
1579
|
TypedData_Get_Struct(self, re2_pattern, &re2_regexp_data_type, p);
|
1561
1580
|
|
1562
|
-
return BOOL2RUBY(RE2::PartialMatch(
|
1581
|
+
return BOOL2RUBY(RE2::PartialMatch(
|
1582
|
+
re2::StringPiece(RSTRING_PTR(text), RSTRING_LEN(text)), *p->pattern));
|
1563
1583
|
}
|
1564
1584
|
|
1565
1585
|
/*
|
@@ -1578,7 +1598,8 @@ static VALUE re2_regexp_full_match_p(const VALUE self, VALUE text) {
|
|
1578
1598
|
|
1579
1599
|
TypedData_Get_Struct(self, re2_pattern, &re2_regexp_data_type, p);
|
1580
1600
|
|
1581
|
-
return BOOL2RUBY(RE2::FullMatch(
|
1601
|
+
return BOOL2RUBY(RE2::FullMatch(
|
1602
|
+
re2::StringPiece(RSTRING_PTR(text), RSTRING_LEN(text)), *p->pattern));
|
1582
1603
|
}
|
1583
1604
|
|
1584
1605
|
/*
|
@@ -1604,7 +1625,8 @@ static VALUE re2_regexp_scan(const VALUE self, VALUE text) {
|
|
1604
1625
|
VALUE scanner = rb_class_new_instance(0, 0, re2_cScanner);
|
1605
1626
|
TypedData_Get_Struct(scanner, re2_scanner, &re2_scanner_data_type, c);
|
1606
1627
|
|
1607
|
-
c->input = new(std::nothrow) re2::StringPiece(
|
1628
|
+
c->input = new(std::nothrow) re2::StringPiece(
|
1629
|
+
RSTRING_PTR(text), RSTRING_LEN(text));
|
1608
1630
|
RB_OBJ_WRITE(scanner, &c->regexp, self);
|
1609
1631
|
RB_OBJ_WRITE(scanner, &c->text, text);
|
1610
1632
|
|
@@ -1669,12 +1691,14 @@ static VALUE re2_Replace(VALUE, VALUE str, VALUE pattern,
|
|
1669
1691
|
/* Take a copy of str so it can be modified in-place by
|
1670
1692
|
* RE2::Replace.
|
1671
1693
|
*/
|
1672
|
-
|
1694
|
+
StringValue(str);
|
1695
|
+
std::string str_as_string(RSTRING_PTR(str), RSTRING_LEN(str));
|
1673
1696
|
|
1674
1697
|
/* Do the replacement. */
|
1675
1698
|
if (rb_obj_is_kind_of(pattern, re2_cRegexp)) {
|
1676
1699
|
TypedData_Get_Struct(pattern, re2_pattern, &re2_regexp_data_type, p);
|
1677
|
-
RE2::Replace(&str_as_string, *p->pattern,
|
1700
|
+
RE2::Replace(&str_as_string, *p->pattern,
|
1701
|
+
re2::StringPiece(RSTRING_PTR(rewrite), RSTRING_LEN(rewrite)));
|
1678
1702
|
|
1679
1703
|
return encoded_str_new(str_as_string.data(), str_as_string.size(),
|
1680
1704
|
p->pattern->options().encoding());
|
@@ -1682,7 +1706,9 @@ static VALUE re2_Replace(VALUE, VALUE str, VALUE pattern,
|
|
1682
1706
|
/* Ensure pattern is a string. */
|
1683
1707
|
StringValue(pattern);
|
1684
1708
|
|
1685
|
-
RE2::Replace(&str_as_string,
|
1709
|
+
RE2::Replace(&str_as_string,
|
1710
|
+
re2::StringPiece(RSTRING_PTR(pattern), RSTRING_LEN(pattern)),
|
1711
|
+
re2::StringPiece(RSTRING_PTR(rewrite), RSTRING_LEN(rewrite)));
|
1686
1712
|
|
1687
1713
|
return encoded_str_new(str_as_string.data(), str_as_string.size(), RE2::Options::EncodingUTF8);
|
1688
1714
|
}
|
@@ -1717,12 +1743,14 @@ static VALUE re2_GlobalReplace(VALUE, VALUE str, VALUE pattern,
|
|
1717
1743
|
* RE2::GlobalReplace.
|
1718
1744
|
*/
|
1719
1745
|
re2_pattern *p;
|
1720
|
-
|
1746
|
+
StringValue(str);
|
1747
|
+
std::string str_as_string(RSTRING_PTR(str), RSTRING_LEN(str));
|
1721
1748
|
|
1722
1749
|
/* Do the replacement. */
|
1723
1750
|
if (rb_obj_is_kind_of(pattern, re2_cRegexp)) {
|
1724
1751
|
TypedData_Get_Struct(pattern, re2_pattern, &re2_regexp_data_type, p);
|
1725
|
-
RE2::GlobalReplace(&str_as_string, *p->pattern,
|
1752
|
+
RE2::GlobalReplace(&str_as_string, *p->pattern,
|
1753
|
+
re2::StringPiece(RSTRING_PTR(rewrite), RSTRING_LEN(rewrite)));
|
1726
1754
|
|
1727
1755
|
return encoded_str_new(str_as_string.data(), str_as_string.size(),
|
1728
1756
|
p->pattern->options().encoding());
|
@@ -1730,8 +1758,9 @@ static VALUE re2_GlobalReplace(VALUE, VALUE str, VALUE pattern,
|
|
1730
1758
|
/* Ensure pattern is a string. */
|
1731
1759
|
StringValue(pattern);
|
1732
1760
|
|
1733
|
-
RE2::GlobalReplace(&str_as_string,
|
1734
|
-
RSTRING_PTR(
|
1761
|
+
RE2::GlobalReplace(&str_as_string,
|
1762
|
+
re2::StringPiece(RSTRING_PTR(pattern), RSTRING_LEN(pattern)),
|
1763
|
+
re2::StringPiece(RSTRING_PTR(rewrite), RSTRING_LEN(rewrite)));
|
1735
1764
|
|
1736
1765
|
return encoded_str_new(str_as_string.data(), str_as_string.size(), RE2::Options::EncodingUTF8);
|
1737
1766
|
}
|
@@ -1753,7 +1782,8 @@ static VALUE re2_GlobalReplace(VALUE, VALUE str, VALUE pattern,
|
|
1753
1782
|
static VALUE re2_QuoteMeta(VALUE, VALUE unquoted) {
|
1754
1783
|
StringValue(unquoted);
|
1755
1784
|
|
1756
|
-
std::string quoted_string = RE2::QuoteMeta(
|
1785
|
+
std::string quoted_string = RE2::QuoteMeta(
|
1786
|
+
re2::StringPiece(RSTRING_PTR(unquoted), RSTRING_LEN(unquoted)));
|
1757
1787
|
|
1758
1788
|
return rb_str_new(quoted_string.data(), quoted_string.size());
|
1759
1789
|
}
|
@@ -1902,7 +1932,8 @@ static VALUE re2_set_add(VALUE self, VALUE pattern) {
|
|
1902
1932
|
|
1903
1933
|
{
|
1904
1934
|
std::string err;
|
1905
|
-
index = s->set->Add(
|
1935
|
+
index = s->set->Add(
|
1936
|
+
re2::StringPiece(RSTRING_PTR(pattern), RSTRING_LEN(pattern)), &err);
|
1906
1937
|
strlcpy(msg, err.c_str(), sizeof(msg));
|
1907
1938
|
}
|
1908
1939
|
|
@@ -2009,7 +2040,8 @@ static VALUE re2_set_match(int argc, VALUE *argv, const VALUE self) {
|
|
2009
2040
|
if (raise_exception) {
|
2010
2041
|
#ifdef HAVE_ERROR_INFO_ARGUMENT
|
2011
2042
|
RE2::Set::ErrorInfo e;
|
2012
|
-
bool match_failed = !s->set->Match(
|
2043
|
+
bool match_failed = !s->set->Match(
|
2044
|
+
re2::StringPiece(RSTRING_PTR(str), RSTRING_LEN(str)), &v, &e);
|
2013
2045
|
VALUE result = rb_ary_new2(v.size());
|
2014
2046
|
|
2015
2047
|
if (match_failed) {
|
@@ -2036,7 +2068,8 @@ static VALUE re2_set_match(int argc, VALUE *argv, const VALUE self) {
|
|
2036
2068
|
rb_raise(re2_eSetUnsupportedError, "current version of RE2::Set::Match() does not output error information, :exception option can only be set to false");
|
2037
2069
|
#endif
|
2038
2070
|
} else {
|
2039
|
-
bool matched = s->set->Match(
|
2071
|
+
bool matched = s->set->Match(
|
2072
|
+
re2::StringPiece(RSTRING_PTR(str), RSTRING_LEN(str)), &v);
|
2040
2073
|
VALUE result = rb_ary_new2(v.size());
|
2041
2074
|
|
2042
2075
|
if (matched) {
|
data/lib/2.6/re2.bundle
CHANGED
Binary file
|
data/lib/2.7/re2.bundle
CHANGED
Binary file
|
data/lib/3.0/re2.bundle
CHANGED
Binary file
|
data/lib/3.1/re2.bundle
CHANGED
Binary file
|
data/lib/3.2/re2.bundle
CHANGED
Binary file
|
data/lib/3.3/re2.bundle
CHANGED
Binary file
|
data/lib/re2/version.rb
CHANGED
data/spec/kernel_spec.rb
CHANGED
@@ -10,6 +10,12 @@ RSpec.describe Kernel do
|
|
10
10
|
expect(re).not_to be_case_sensitive
|
11
11
|
end
|
12
12
|
|
13
|
+
it "accepts patterns containing null bytes" do
|
14
|
+
re = RE2("a\0b")
|
15
|
+
|
16
|
+
expect(re.pattern).to eq("a\0b")
|
17
|
+
end
|
18
|
+
|
13
19
|
it "raises an error if given an inappropriate type" do
|
14
20
|
expect { RE2(nil) }.to raise_error(TypeError)
|
15
21
|
end
|
data/spec/re2/match_data_spec.rb
CHANGED
@@ -190,7 +190,7 @@ RSpec.describe RE2::MatchData do
|
|
190
190
|
describe "#inspect" do
|
191
191
|
it "returns a text representation of the object and indices" do
|
192
192
|
md = RE2::Regexp.new('(\d+) (\d+)').match("1234 56")
|
193
|
-
|
193
|
+
|
194
194
|
expect(md.inspect).to eq('#<RE2::MatchData "1234 56" 1:"1234" 2:"56">')
|
195
195
|
end
|
196
196
|
|
@@ -199,6 +199,12 @@ RSpec.describe RE2::MatchData do
|
|
199
199
|
|
200
200
|
expect(md.inspect).to eq('#<RE2::MatchData "1234 " 1:"1234" 2:nil>')
|
201
201
|
end
|
202
|
+
|
203
|
+
it "supports matches with null bytes" do
|
204
|
+
md = RE2::Regexp.new("(\\w\0\\w) (\\w\0\\w)").match("a\0b c\0d")
|
205
|
+
|
206
|
+
expect(md.inspect).to eq("#<RE2::MatchData \"a\0b c\0d\" 1:\"a\0b\" 2:\"c\0d\">")
|
207
|
+
end
|
202
208
|
end
|
203
209
|
|
204
210
|
describe "#to_s" do
|
@@ -239,6 +245,12 @@ RSpec.describe RE2::MatchData do
|
|
239
245
|
expect(md.string[md.begin(:foo)..-1]).to eq('foobar')
|
240
246
|
end
|
241
247
|
|
248
|
+
it "returns the offset of the start of a match by something that can be coerced to a String" do
|
249
|
+
md = RE2::Regexp.new('(?P<foo>fo{2})').match('a foobar')
|
250
|
+
|
251
|
+
expect(md.string[md.begin(StringLike.new("foo"))..-1]).to eq('foobar')
|
252
|
+
end
|
253
|
+
|
242
254
|
it "returns the offset despite multibyte characters" do
|
243
255
|
md = RE2::Regexp.new('(Ruby)').match('I ♥ Ruby')
|
244
256
|
|
@@ -268,6 +280,12 @@ RSpec.describe RE2::MatchData do
|
|
268
280
|
|
269
281
|
expect(md.begin(:foo)).to be_nil
|
270
282
|
end
|
283
|
+
|
284
|
+
it "raises a type error if given an invalid name or number" do
|
285
|
+
md = RE2::Regexp.new('(\d)').match('123')
|
286
|
+
|
287
|
+
expect { md.begin(nil) }.to raise_error(TypeError)
|
288
|
+
end
|
271
289
|
end
|
272
290
|
|
273
291
|
describe "#end" do
|
@@ -289,6 +307,12 @@ RSpec.describe RE2::MatchData do
|
|
289
307
|
expect(md.string[0...md.end(:foo)]).to eq('a foo')
|
290
308
|
end
|
291
309
|
|
310
|
+
it "returns the offset of a match by something that can be coerced to a String" do
|
311
|
+
md = RE2::Regexp.new('(?P<foo>fo{2})').match('a foobar')
|
312
|
+
|
313
|
+
expect(md.string[0...md.end(StringLike.new("foo"))]).to eq('a foo')
|
314
|
+
end
|
315
|
+
|
292
316
|
it "returns the offset despite multibyte characters" do
|
293
317
|
md = RE2::Regexp.new('(Ruby)').match('I ♥ Ruby')
|
294
318
|
|
@@ -318,6 +342,12 @@ RSpec.describe RE2::MatchData do
|
|
318
342
|
|
319
343
|
expect(md.end(:foo)).to be_nil
|
320
344
|
end
|
345
|
+
|
346
|
+
it "raises a type error if given an invalid name or number" do
|
347
|
+
md = RE2::Regexp.new('(\d)').match('123')
|
348
|
+
|
349
|
+
expect { md.end(nil) }.to raise_error(TypeError)
|
350
|
+
end
|
321
351
|
end
|
322
352
|
|
323
353
|
describe "#deconstruct" do
|
data/spec/re2/regexp_spec.rb
CHANGED
@@ -12,6 +12,12 @@ RSpec.describe RE2::Regexp do
|
|
12
12
|
expect(re).to be_a(RE2::Regexp)
|
13
13
|
end
|
14
14
|
|
15
|
+
it "accepts patterns containing null bytes" do
|
16
|
+
re = RE2::Regexp.new("a\0b")
|
17
|
+
|
18
|
+
expect(re.pattern).to eq("a\0b")
|
19
|
+
end
|
20
|
+
|
15
21
|
it "raises an error if given an inappropriate type" do
|
16
22
|
expect { RE2::Regexp.new(nil) }.to raise_error(TypeError)
|
17
23
|
end
|
@@ -41,6 +47,12 @@ RSpec.describe RE2::Regexp do
|
|
41
47
|
expect(re).to be_a(RE2::Regexp)
|
42
48
|
end
|
43
49
|
|
50
|
+
it "accepts patterns containing null bytes" do
|
51
|
+
re = RE2::Regexp.compile("a\0b")
|
52
|
+
|
53
|
+
expect(re.pattern).to eq("a\0b")
|
54
|
+
end
|
55
|
+
|
44
56
|
it "raises an error if given an inappropriate type" do
|
45
57
|
expect { RE2::Regexp.compile(nil) }.to raise_error(TypeError)
|
46
58
|
end
|
@@ -339,6 +351,12 @@ RSpec.describe RE2::Regexp do
|
|
339
351
|
expect(re.match("My name is Alice Bloggs")).to eq(true)
|
340
352
|
end
|
341
353
|
|
354
|
+
it "supports matching against text containing null bytes" do
|
355
|
+
re = RE2::Regexp.new("a\0b")
|
356
|
+
|
357
|
+
expect(re.match("a\0b")).to eq(true)
|
358
|
+
end
|
359
|
+
|
342
360
|
it "returns nil if the text does not match the pattern" do
|
343
361
|
re = RE2::Regexp.new('My name is (\w+) (\w+)')
|
344
362
|
|
@@ -511,6 +529,13 @@ RSpec.describe RE2::Regexp do
|
|
511
529
|
expect(md[3]).to eq("three")
|
512
530
|
end
|
513
531
|
|
532
|
+
it "supports extracting submatches containing null bytes" do
|
533
|
+
re = RE2::Regexp.new("(a\0b)")
|
534
|
+
md = re.match("a\0bc")
|
535
|
+
|
536
|
+
expect(md[1]).to eq("a\0b")
|
537
|
+
end
|
538
|
+
|
514
539
|
it "extracts a specific number of submatches", :aggregate_failures do
|
515
540
|
re = RE2::Regexp.new('(\w+) (\w+) (\w+)')
|
516
541
|
md = re.match("one two three", submatches: 2)
|
@@ -599,6 +624,13 @@ RSpec.describe RE2::Regexp do
|
|
599
624
|
expect(re.partial_match?("My age is 99")).to eq(false)
|
600
625
|
end
|
601
626
|
|
627
|
+
it "supports matching against text containing null bytes", :aggregate_failures do
|
628
|
+
re = RE2::Regexp.new("a\0b")
|
629
|
+
|
630
|
+
expect(re.partial_match?("a\0b")).to eq(true)
|
631
|
+
expect(re.partial_match?("ab")).to eq(false)
|
632
|
+
end
|
633
|
+
|
602
634
|
it "returns false if the pattern is invalid" do
|
603
635
|
re = RE2::Regexp.new('???', log_errors: false)
|
604
636
|
|
@@ -620,6 +652,13 @@ RSpec.describe RE2::Regexp do
|
|
620
652
|
expect(re =~ "My age is 99").to eq(false)
|
621
653
|
end
|
622
654
|
|
655
|
+
it "supports matching against text containing null bytes", :aggregate_failures do
|
656
|
+
re = RE2::Regexp.new("a\0b")
|
657
|
+
|
658
|
+
expect(re =~ "a\0b").to eq(true)
|
659
|
+
expect(re =~ "ab").to eq(false)
|
660
|
+
end
|
661
|
+
|
623
662
|
it "returns false if the pattern is invalid" do
|
624
663
|
re = RE2::Regexp.new('???', log_errors: false)
|
625
664
|
|
@@ -662,6 +701,13 @@ RSpec.describe RE2::Regexp do
|
|
662
701
|
expect(re.full_match?("My name is Alice Bloggs and I am 99")).to eq(false)
|
663
702
|
end
|
664
703
|
|
704
|
+
it "supports matching against text containing null bytes", :aggregate_failures do
|
705
|
+
re = RE2::Regexp.new("a\0b")
|
706
|
+
|
707
|
+
expect(re.full_match?("a\0b")).to eq(true)
|
708
|
+
expect(re.full_match?("a\0bc")).to eq(false)
|
709
|
+
end
|
710
|
+
|
665
711
|
it "returns false if the pattern is invalid" do
|
666
712
|
re = RE2::Regexp.new('???', log_errors: false)
|
667
713
|
|
@@ -742,6 +788,12 @@ RSpec.describe RE2::Regexp do
|
|
742
788
|
|
743
789
|
expect(scanner).to be_a(RE2::Scanner)
|
744
790
|
end
|
791
|
+
|
792
|
+
it "raises a type error if given invalid input" do
|
793
|
+
r = RE2::Regexp.new('(\w+)')
|
794
|
+
|
795
|
+
expect { r.scan(nil) }.to raise_error(TypeError)
|
796
|
+
end
|
745
797
|
end
|
746
798
|
|
747
799
|
describe "#partial_match" do
|
data/spec/re2/scanner_spec.rb
CHANGED
@@ -34,6 +34,16 @@ RSpec.describe RE2::Scanner do
|
|
34
34
|
expect(scanner.scan).to be_nil
|
35
35
|
end
|
36
36
|
|
37
|
+
it "supports scanning inputs with null bytes", :aggregate_failures do
|
38
|
+
r = RE2::Regexp.new("(\\w\0\\w)")
|
39
|
+
scanner = r.scan("a\0b c\0d e\0f")
|
40
|
+
|
41
|
+
expect(scanner.scan).to eq(["a\0b"])
|
42
|
+
expect(scanner.scan).to eq(["c\0d"])
|
43
|
+
expect(scanner.scan).to eq(["e\0f"])
|
44
|
+
expect(scanner.scan).to be_nil
|
45
|
+
end
|
46
|
+
|
37
47
|
it "returns UTF-8 matches if the pattern is UTF-8" do
|
38
48
|
r = RE2::Regexp.new('(\w+)')
|
39
49
|
scanner = r.scan("It")
|
@@ -190,6 +200,18 @@ RSpec.describe RE2::Scanner do
|
|
190
200
|
expect(scanner.to_enum.first).to eq(["1"])
|
191
201
|
end
|
192
202
|
|
203
|
+
it "supports inputs with null bytes", :aggregate_failures do
|
204
|
+
r = RE2::Regexp.new("(\\w\0\\w)")
|
205
|
+
scanner = r.scan("a\0b c\0d")
|
206
|
+
|
207
|
+
expect(scanner.to_enum.first).to eq(["a\0b"])
|
208
|
+
expect(scanner.to_enum.first).to eq(["c\0d"])
|
209
|
+
|
210
|
+
scanner.rewind
|
211
|
+
|
212
|
+
expect(scanner.to_enum.first).to eq(["a\0b"])
|
213
|
+
end
|
214
|
+
|
193
215
|
it "resets the eof? check", :aggregate_failures do
|
194
216
|
r = RE2::Regexp.new('(\d)')
|
195
217
|
scanner = r.scan("1")
|
data/spec/re2/set_spec.rb
CHANGED
@@ -123,6 +123,14 @@ RSpec.describe RE2::Set do
|
|
123
123
|
expect(set.match("def", exception: false)).to be_empty
|
124
124
|
end
|
125
125
|
|
126
|
+
it "supports matching null bytes", :aggregate_failures do
|
127
|
+
set = RE2::Set.new
|
128
|
+
set.add("a\0b")
|
129
|
+
set.compile
|
130
|
+
|
131
|
+
expect(set.match("a\0b", exception: false)).to eq([0])
|
132
|
+
end
|
133
|
+
|
126
134
|
it "returns an empty array if there is no match when :exception is true" do
|
127
135
|
skip "Underlying RE2::Set::Match does not output error information" unless RE2::Set.match_raises_errors?
|
128
136
|
|
data/spec/re2_spec.rb
CHANGED
@@ -4,6 +4,18 @@ RSpec.describe RE2 do
|
|
4
4
|
expect(RE2.Replace("woo", "o", "a")).to eq("wao")
|
5
5
|
end
|
6
6
|
|
7
|
+
it "supports inputs with null bytes" do
|
8
|
+
expect(RE2.Replace("w\0oo", "o", "a")).to eq("w\0ao")
|
9
|
+
end
|
10
|
+
|
11
|
+
it "supports patterns with null bytes" do
|
12
|
+
expect(RE2.Replace("w\0oo", "\0", "o")).to eq("wooo")
|
13
|
+
end
|
14
|
+
|
15
|
+
it "supports replacements with null bytes" do
|
16
|
+
expect(RE2.Replace("woo", "o", "\0")).to eq("w\0o")
|
17
|
+
end
|
18
|
+
|
7
19
|
it "performs replacement based on regular expressions" do
|
8
20
|
expect(RE2.Replace("woo", "o+", "e")).to eq("we")
|
9
21
|
end
|
@@ -82,6 +94,18 @@ RSpec.describe RE2 do
|
|
82
94
|
expect(RE2.GlobalReplace("woo", "o", "a")).to eq("waa")
|
83
95
|
end
|
84
96
|
|
97
|
+
it "supports inputs with null bytes" do
|
98
|
+
expect(RE2.GlobalReplace("w\0oo", "o", "a")).to eq("w\0aa")
|
99
|
+
end
|
100
|
+
|
101
|
+
it "supports patterns with null bytes" do
|
102
|
+
expect(RE2.GlobalReplace("w\0\0oo", "\0", "a")).to eq("waaoo")
|
103
|
+
end
|
104
|
+
|
105
|
+
it "supports replacements with null bytes" do
|
106
|
+
expect(RE2.GlobalReplace("woo", "o", "\0")).to eq("w\0\0")
|
107
|
+
end
|
108
|
+
|
85
109
|
it "performs replacement based on regular expressions" do
|
86
110
|
expect(RE2.GlobalReplace("woohoo", "o+", "e")).to eq("wehe")
|
87
111
|
end
|
@@ -167,5 +191,9 @@ RSpec.describe RE2 do
|
|
167
191
|
it "supports passing something that can be coerced to a String as input" do
|
168
192
|
expect(RE2.QuoteMeta(StringLike.new("1.5"))).to eq('1\.5')
|
169
193
|
end
|
194
|
+
|
195
|
+
it "supports strings containing null bytes" do
|
196
|
+
expect(RE2.QuoteMeta("abc\0def")).to eq('abc\x00def')
|
197
|
+
end
|
170
198
|
end
|
171
199
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: re2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.7.0
|
5
5
|
platform: x86_64-darwin
|
6
6
|
authors:
|
7
7
|
- Paul Mucur
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2024-01-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake-compiler
|