re2 2.6.0-x86-linux → 2.8.0-x86-linux

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c8d221dce2a4803ccffbede68f63fa66d6d58d9619f0ea164c06a86af7db1e4b
4
- data.tar.gz: bc960e9de6bcf5ef7659dfd961082bbf7a54fb227929b4e3e861804f2a657dee
3
+ metadata.gz: 6fa923a6d48f4ca3fee107a8da82b3a6aaaa5f186d63d5910e4b6d4651b12626
4
+ data.tar.gz: 86cfc0a4227e499a0cd65b81136463971c320906b044d1dd41d14a19ea81ca0f
5
5
  SHA512:
6
- metadata.gz: 6e64b999321f4b2593abbefe190de85c799cb321cf65605b61b1171ad1d4577d4311ad61699d1828824be0f7cd1f64a9cb2a88012836d8a325dd34b15bad80ff
7
- data.tar.gz: 53814c52baf7a6e28ed94551352b16e894518a518dce72a918fba3543e3df81d182f6a16740ac43380d312213af22ad14e8e3baa40f6e79c1a50ae44d9a90e3a
6
+ metadata.gz: 2694d2d18548470808458d823d6c3b4b4c546643084b542f8c6415325cbfae7cfad774868d0c59840db2078c649c96d60ee1ecc14bd26fa9ab6b27091bf860c5
7
+ data.tar.gz: a3b51d050c13d275a7de0cf027a1201291899195f7a029620cc4b5d13821624d2c08f0c60d10e332cb8ebfdb9b6ad5c934da2f0d50f2a2b5da282d54a334c0bf
data/.rspec CHANGED
@@ -1,2 +1,3 @@
1
1
  --color
2
2
  --require spec_helper
3
+ --format documentation
data/README.md CHANGED
@@ -6,8 +6,8 @@ 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.6.0
10
- **Bundled RE2 version:** libre2.11 (2023-11-01)
9
+ **Current version:** 2.8.0
10
+ **Bundled RE2 version:** libre2.11 (2024-02-01)
11
11
 
12
12
  ```ruby
13
13
  RE2('h.*o').full_match?("hello") #=> true
@@ -261,7 +261,7 @@ This gem requires the following to run:
261
261
 
262
262
  It supports the following RE2 ABI versions:
263
263
 
264
- * libre2.0 (prior to release 2020-03-02) to libre2.11 (2023-07-01 to 2023-11-01)
264
+ * libre2.0 (prior to release 2020-03-02) to libre2.11 (2023-07-01 to 2024-02-01)
265
265
 
266
266
  ### Native gems
267
267
 
@@ -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.5.0
283
- Fetching re2-2.5.0-arm64-darwin.gem
284
- Downloaded re2-2.5.0-arm64-darwin
285
- $ sha256sum re2-2.5.0-arm64-darwin.gem
286
- 4b20c4539a12787102b22012e678968af23f87e35f88843744835bd13ac9f6bc re2-2.5.0-arm64-darwin.gem
282
+ $ gem fetch re2 -v 2.7.0
283
+ Fetching re2-2.7.0-arm64-darwin.gem
284
+ Downloaded re2-2.7.0-arm64-darwin
285
+ $ sha256sum re2-2.7.0-arm64-darwin.gem
286
+ 7d993f27a1afac4001c539a829e2af211ced62604930c90df32a307cf74cb4a4 re2-2.7.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.5.0-arm64-darwin.gem.sig re2-2.5.0-arm64-darwin.gem
293
- gpg: Signature made Fri 15 Dec 2023 12:58:58 GMT
292
+ $ gpg --verify re2-2.7.0-arm64-darwin.gem.sig re2-2.7.0-arm64-darwin.gem
293
+ gpg: Signature made Sat 20 Jan 15:01:45 2024 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/dependencies.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  libre2:
3
- version: '2023-11-01'
4
- sha256: 4e6593ac3c71de1c0f322735bc8b0492a72f66ffccfad76e259fa21c41d27d8a
3
+ version: '2024-02-01'
4
+ sha256: cd191a311b84fcf37310e5cd876845b4bf5aee76fdd755008eef3b6478ce07bb
5
5
  abseil:
6
- version: '20230802.1'
7
- sha256: 987ce98f02eefbaf930d6e38ab16aa05737234d7afbab2d5c4ea7adbe50c28ed
6
+ version: '20240116.0'
7
+ sha256: 338420448b140f0dfd1a1ea3c3ce71b3bc172071f24f4d9a57d59b45037da440
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(RSTRING_PTR(c->text));
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
- const char *name = SYMBOL_P(idx) ? rb_id2name(SYM2ID(idx)) : StringValuePtr(idx);
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(name);
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 char* name, const VALUE self) {
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(RSTRING_PTR(idx), self);
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,9 @@ 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 << "\"";
747
+ output.write(RSTRING_PTR(match), RSTRING_LEN(match));
748
+ output << "\"";
735
749
  }
736
750
  }
737
751
 
@@ -910,9 +924,11 @@ static VALUE re2_regexp_initialize(int argc, VALUE *argv, VALUE self) {
910
924
  RE2::Options re2_options;
911
925
  parse_re2_options(&re2_options, options);
912
926
 
913
- p->pattern = new(std::nothrow) RE2(RSTRING_PTR(pattern), re2_options);
927
+ p->pattern = new(std::nothrow) RE2(
928
+ re2::StringPiece(RSTRING_PTR(pattern), RSTRING_LEN(pattern)), re2_options);
914
929
  } else {
915
- p->pattern = new(std::nothrow) RE2(RSTRING_PTR(pattern));
930
+ p->pattern = new(std::nothrow) RE2(
931
+ re2::StringPiece(RSTRING_PTR(pattern), RSTRING_LEN(pattern)));
916
932
  }
917
933
 
918
934
  if (p->pattern == 0) {
@@ -1501,11 +1517,13 @@ static VALUE re2_regexp_match(int argc, VALUE *argv, const VALUE self) {
1501
1517
 
1502
1518
  if (n == 0) {
1503
1519
  #ifdef HAVE_ENDPOS_ARGUMENT
1504
- bool matched = p->pattern->Match(RSTRING_PTR(text), startpos,
1505
- endpos, anchor, 0, 0);
1520
+ bool matched = p->pattern->Match(
1521
+ re2::StringPiece(RSTRING_PTR(text), RSTRING_LEN(text)),
1522
+ startpos, endpos, anchor, 0, 0);
1506
1523
  #else
1507
- bool matched = p->pattern->Match(RSTRING_PTR(text), startpos, anchor,
1508
- 0, 0);
1524
+ bool matched = p->pattern->Match(
1525
+ re2::StringPiece(RSTRING_PTR(text), RSTRING_LEN(text)),
1526
+ startpos, anchor, 0, 0);
1509
1527
  #endif
1510
1528
  return BOOL2RUBY(matched);
1511
1529
  } else {
@@ -1529,11 +1547,13 @@ static VALUE re2_regexp_match(int argc, VALUE *argv, const VALUE self) {
1529
1547
  m->number_of_matches = n;
1530
1548
 
1531
1549
  #ifdef HAVE_ENDPOS_ARGUMENT
1532
- bool matched = p->pattern->Match(RSTRING_PTR(m->text), startpos,
1533
- endpos, anchor, m->matches, n);
1550
+ bool matched = p->pattern->Match(
1551
+ re2::StringPiece(RSTRING_PTR(m->text), RSTRING_LEN(m->text)),
1552
+ startpos, endpos, anchor, m->matches, n);
1534
1553
  #else
1535
- bool matched = p->pattern->Match(RSTRING_PTR(m->text), startpos,
1536
- anchor, m->matches, n);
1554
+ bool matched = p->pattern->Match(
1555
+ re2::StringPiece(RSTRING_PTR(m->text), RSTRING_LEN(m->text)),
1556
+ startpos, anchor, m->matches, n);
1537
1557
  #endif
1538
1558
  if (matched) {
1539
1559
  return matchdata;
@@ -1559,7 +1579,8 @@ static VALUE re2_regexp_match_p(const VALUE self, VALUE text) {
1559
1579
 
1560
1580
  TypedData_Get_Struct(self, re2_pattern, &re2_regexp_data_type, p);
1561
1581
 
1562
- return BOOL2RUBY(RE2::PartialMatch(RSTRING_PTR(text), *p->pattern));
1582
+ return BOOL2RUBY(RE2::PartialMatch(
1583
+ re2::StringPiece(RSTRING_PTR(text), RSTRING_LEN(text)), *p->pattern));
1563
1584
  }
1564
1585
 
1565
1586
  /*
@@ -1578,7 +1599,8 @@ static VALUE re2_regexp_full_match_p(const VALUE self, VALUE text) {
1578
1599
 
1579
1600
  TypedData_Get_Struct(self, re2_pattern, &re2_regexp_data_type, p);
1580
1601
 
1581
- return BOOL2RUBY(RE2::FullMatch(RSTRING_PTR(text), *p->pattern));
1602
+ return BOOL2RUBY(RE2::FullMatch(
1603
+ re2::StringPiece(RSTRING_PTR(text), RSTRING_LEN(text)), *p->pattern));
1582
1604
  }
1583
1605
 
1584
1606
  /*
@@ -1604,7 +1626,8 @@ static VALUE re2_regexp_scan(const VALUE self, VALUE text) {
1604
1626
  VALUE scanner = rb_class_new_instance(0, 0, re2_cScanner);
1605
1627
  TypedData_Get_Struct(scanner, re2_scanner, &re2_scanner_data_type, c);
1606
1628
 
1607
- c->input = new(std::nothrow) re2::StringPiece(RSTRING_PTR(text));
1629
+ c->input = new(std::nothrow) re2::StringPiece(
1630
+ RSTRING_PTR(text), RSTRING_LEN(text));
1608
1631
  RB_OBJ_WRITE(scanner, &c->regexp, self);
1609
1632
  RB_OBJ_WRITE(scanner, &c->text, text);
1610
1633
 
@@ -1669,12 +1692,14 @@ static VALUE re2_Replace(VALUE, VALUE str, VALUE pattern,
1669
1692
  /* Take a copy of str so it can be modified in-place by
1670
1693
  * RE2::Replace.
1671
1694
  */
1672
- std::string str_as_string(StringValuePtr(str));
1695
+ StringValue(str);
1696
+ std::string str_as_string(RSTRING_PTR(str), RSTRING_LEN(str));
1673
1697
 
1674
1698
  /* Do the replacement. */
1675
1699
  if (rb_obj_is_kind_of(pattern, re2_cRegexp)) {
1676
1700
  TypedData_Get_Struct(pattern, re2_pattern, &re2_regexp_data_type, p);
1677
- RE2::Replace(&str_as_string, *p->pattern, RSTRING_PTR(rewrite));
1701
+ RE2::Replace(&str_as_string, *p->pattern,
1702
+ re2::StringPiece(RSTRING_PTR(rewrite), RSTRING_LEN(rewrite)));
1678
1703
 
1679
1704
  return encoded_str_new(str_as_string.data(), str_as_string.size(),
1680
1705
  p->pattern->options().encoding());
@@ -1682,7 +1707,9 @@ static VALUE re2_Replace(VALUE, VALUE str, VALUE pattern,
1682
1707
  /* Ensure pattern is a string. */
1683
1708
  StringValue(pattern);
1684
1709
 
1685
- RE2::Replace(&str_as_string, RSTRING_PTR(pattern), RSTRING_PTR(rewrite));
1710
+ RE2::Replace(&str_as_string,
1711
+ re2::StringPiece(RSTRING_PTR(pattern), RSTRING_LEN(pattern)),
1712
+ re2::StringPiece(RSTRING_PTR(rewrite), RSTRING_LEN(rewrite)));
1686
1713
 
1687
1714
  return encoded_str_new(str_as_string.data(), str_as_string.size(), RE2::Options::EncodingUTF8);
1688
1715
  }
@@ -1717,12 +1744,14 @@ static VALUE re2_GlobalReplace(VALUE, VALUE str, VALUE pattern,
1717
1744
  * RE2::GlobalReplace.
1718
1745
  */
1719
1746
  re2_pattern *p;
1720
- std::string str_as_string(StringValuePtr(str));
1747
+ StringValue(str);
1748
+ std::string str_as_string(RSTRING_PTR(str), RSTRING_LEN(str));
1721
1749
 
1722
1750
  /* Do the replacement. */
1723
1751
  if (rb_obj_is_kind_of(pattern, re2_cRegexp)) {
1724
1752
  TypedData_Get_Struct(pattern, re2_pattern, &re2_regexp_data_type, p);
1725
- RE2::GlobalReplace(&str_as_string, *p->pattern, RSTRING_PTR(rewrite));
1753
+ RE2::GlobalReplace(&str_as_string, *p->pattern,
1754
+ re2::StringPiece(RSTRING_PTR(rewrite), RSTRING_LEN(rewrite)));
1726
1755
 
1727
1756
  return encoded_str_new(str_as_string.data(), str_as_string.size(),
1728
1757
  p->pattern->options().encoding());
@@ -1730,8 +1759,9 @@ static VALUE re2_GlobalReplace(VALUE, VALUE str, VALUE pattern,
1730
1759
  /* Ensure pattern is a string. */
1731
1760
  StringValue(pattern);
1732
1761
 
1733
- RE2::GlobalReplace(&str_as_string, RSTRING_PTR(pattern),
1734
- RSTRING_PTR(rewrite));
1762
+ RE2::GlobalReplace(&str_as_string,
1763
+ re2::StringPiece(RSTRING_PTR(pattern), RSTRING_LEN(pattern)),
1764
+ re2::StringPiece(RSTRING_PTR(rewrite), RSTRING_LEN(rewrite)));
1735
1765
 
1736
1766
  return encoded_str_new(str_as_string.data(), str_as_string.size(), RE2::Options::EncodingUTF8);
1737
1767
  }
@@ -1753,7 +1783,8 @@ static VALUE re2_GlobalReplace(VALUE, VALUE str, VALUE pattern,
1753
1783
  static VALUE re2_QuoteMeta(VALUE, VALUE unquoted) {
1754
1784
  StringValue(unquoted);
1755
1785
 
1756
- std::string quoted_string = RE2::QuoteMeta(RSTRING_PTR(unquoted));
1786
+ std::string quoted_string = RE2::QuoteMeta(
1787
+ re2::StringPiece(RSTRING_PTR(unquoted), RSTRING_LEN(unquoted)));
1757
1788
 
1758
1789
  return rb_str_new(quoted_string.data(), quoted_string.size());
1759
1790
  }
@@ -1902,7 +1933,8 @@ static VALUE re2_set_add(VALUE self, VALUE pattern) {
1902
1933
 
1903
1934
  {
1904
1935
  std::string err;
1905
- index = s->set->Add(RSTRING_PTR(pattern), &err);
1936
+ index = s->set->Add(
1937
+ re2::StringPiece(RSTRING_PTR(pattern), RSTRING_LEN(pattern)), &err);
1906
1938
  strlcpy(msg, err.c_str(), sizeof(msg));
1907
1939
  }
1908
1940
 
@@ -2009,7 +2041,8 @@ static VALUE re2_set_match(int argc, VALUE *argv, const VALUE self) {
2009
2041
  if (raise_exception) {
2010
2042
  #ifdef HAVE_ERROR_INFO_ARGUMENT
2011
2043
  RE2::Set::ErrorInfo e;
2012
- bool match_failed = !s->set->Match(RSTRING_PTR(str), &v, &e);
2044
+ bool match_failed = !s->set->Match(
2045
+ re2::StringPiece(RSTRING_PTR(str), RSTRING_LEN(str)), &v, &e);
2013
2046
  VALUE result = rb_ary_new2(v.size());
2014
2047
 
2015
2048
  if (match_failed) {
@@ -2036,7 +2069,8 @@ static VALUE re2_set_match(int argc, VALUE *argv, const VALUE self) {
2036
2069
  rb_raise(re2_eSetUnsupportedError, "current version of RE2::Set::Match() does not output error information, :exception option can only be set to false");
2037
2070
  #endif
2038
2071
  } else {
2039
- bool matched = s->set->Match(RSTRING_PTR(str), &v);
2072
+ bool matched = s->set->Match(
2073
+ re2::StringPiece(RSTRING_PTR(str), RSTRING_LEN(str)), &v);
2040
2074
  VALUE result = rb_ary_new2(v.size());
2041
2075
 
2042
2076
  if (matched) {
data/lib/2.6/re2.so CHANGED
Binary file
data/lib/2.7/re2.so CHANGED
Binary file
data/lib/3.0/re2.so CHANGED
Binary file
data/lib/3.1/re2.so CHANGED
Binary file
data/lib/3.2/re2.so CHANGED
Binary file
data/lib/3.3/re2.so CHANGED
Binary file
data/lib/re2/version.rb CHANGED
@@ -10,5 +10,5 @@
10
10
 
11
11
 
12
12
  module RE2
13
- VERSION = "2.6.0"
13
+ VERSION = "2.8.0"
14
14
  end
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
@@ -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
@@ -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
@@ -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.6.0
4
+ version: 2.8.0
5
5
  platform: x86-linux
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: 2023-12-27 00:00:00.000000000 Z
12
+ date: 2024-01-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake-compiler