re2 2.6.0.rc1-arm64-darwin → 2.8.0-arm64-darwin

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aeea11fe983c4a111eca8d593e830e47fbc88b7f8b6f2d1d1a58c0a45c72b363
4
- data.tar.gz: a4e3841f0d06601371e045814e8c3f4381a70dc3a74e6431eb5d308678866f1f
3
+ metadata.gz: bf27f182a6bf770a1241b9e89e6d68d3468b61ce8f436acb79a8620ff1bee463
4
+ data.tar.gz: 138fbd5dc29e3065885c0e549ab02b6a0baf4ce87f7ba36ec3974d21cdbadeaf
5
5
  SHA512:
6
- metadata.gz: 91b75520402ee70ef82cba9ccf654e356526588a476a4a2d527b8e71c61e160abc63f4a9840f11a61fc14b9f50d8387948fe46cd2831c41dc7f3fe3c2db44b98
7
- data.tar.gz: b962af565015eabf353839cc9f7ced89f33fd9bb7abf1a61aebc1f3752c0b484f7f2e8d932773786c80b0bf473ca2dd13757e9f101b71dbc38a081109e15c4dd
6
+ metadata.gz: 6e7d1c10a36dafdb2b26d14deaae4bf1324d14ef1912d69399f8962341db4a11c65a430fa0b164e5f8c0c790645e6f127ac81f8adfa80624584398859bb299df
7
+ data.tar.gz: 024e409d79d5c434750f91f376f50610874f2738d8b965d987ca6fc49cdb59ffc12ae2c40e2ca6ef1ff2a96f8cf0d110a5ba0fffb6f771fcc6e1bad7a6d3c9f2
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.5.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
@@ -30,6 +30,7 @@ RE2('(\w+):(\d+)').full_match("ruby:1234")
30
30
  * [Encoding](#encoding)
31
31
  * [Requirements](#requirements)
32
32
  * [Native gems](#native-gems)
33
+ * [Verifying the gems](#verifying-the-gems)
33
34
  * [Installing the `ruby` platform gem](#installing-the-ruby-platform-gem)
34
35
  * [Using system libraries](#using-system-libraries)
35
36
  * [Thanks](#thanks)
@@ -260,17 +261,46 @@ This gem requires the following to run:
260
261
 
261
262
  It supports the following RE2 ABI versions:
262
263
 
263
- * 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)
264
265
 
265
266
  ### Native gems
266
267
 
267
268
  Where possible, a pre-compiled native gem will be provided for the following platforms:
268
269
 
269
- * Linux `aarch64-linux` and `arm-linux` (requires [glibc](https://www.gnu.org/software/libc/) 2.29+)
270
- * Linux `x86-linux` and `x86_64-linux` (requires [glibc](https://www.gnu.org/software/libc/) 2.17+) including [musl](https://musl.libc.org/)-based systems such as [Alpine](https://alpinelinux.org)
270
+ * Linux
271
+ * `aarch64-linux` and `arm-linux` (requires [glibc](https://www.gnu.org/software/libc/) 2.29+)
272
+ * `x86-linux` and `x86_64-linux` (requires [glibc](https://www.gnu.org/software/libc/) 2.17+)
273
+ * [musl](https://musl.libc.org/)-based systems such as [Alpine](https://alpinelinux.org) are supported as long as a [glibc-compatible library is installed](https://wiki.alpinelinux.org/wiki/Running_glibc_programs)
271
274
  * macOS `x86_64-darwin` and `arm64-darwin`
272
275
  * Windows `x64-mingw32` and `x64-mingw-ucrt`
273
276
 
277
+ ### Verifying the gems
278
+
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
+
281
+ ```console
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
+ ```
288
+
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
+
291
+ ```console
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
+ gpg: using RSA key 702609D9C790F45B577D7BEC39AC3530070E0F75
295
+ gpg: Good signature from "Paul Mucur <mudge@mudge.name>" [unknown]
296
+ gpg: aka "Paul Mucur <paul@ghostcassette.com>" [unknown]
297
+ gpg: WARNING: This key is not certified with a trusted signature!
298
+ gpg: There is no indication that the signature belongs to the owner.
299
+ Primary key fingerprint: 7026 09D9 C790 F45B 577D 7BEC 39AC 3530 070E 0F75
300
+ ```
301
+
302
+ The fingerprint should be as shown above or you can independently verify it with the ones shown in the footer of https://mudge.name.
303
+
274
304
  ### Installing the `ruby` platform gem
275
305
 
276
306
  > [!WARNING]
@@ -343,6 +373,8 @@ Alternatively, you can set the `RE2_USE_SYSTEM_LIBRARIES` environment variable i
343
373
  * Thanks to [Jean Boussier](https://github.com/byroot) for contributing the
344
374
  switch to Ruby's `TypedData` API and the resulting garbage collection
345
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.
346
378
 
347
379
  ## Contact
348
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.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
@@ -10,5 +10,5 @@
10
10
 
11
11
 
12
12
  module RE2
13
- VERSION = "2.6.0.rc1"
13
+ VERSION = "2.8.0"
14
14
  end
data/re2.gemspec CHANGED
@@ -39,7 +39,7 @@ Gem::Specification.new do |s|
39
39
  "spec/re2/scanner_spec.rb"
40
40
  ]
41
41
  s.add_development_dependency("rake-compiler", "~> 1.2.5")
42
- s.add_development_dependency("rake-compiler-dock", "~> 1.4.0.rc2")
42
+ s.add_development_dependency("rake-compiler-dock", "~> 1.4.0")
43
43
  s.add_development_dependency("rspec", "~> 3.2")
44
44
  s.add_runtime_dependency("mini_portile2", "~> 2.8.5") # keep version in sync with extconf.rb
45
45
  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.rc1
4
+ version: 2.8.0
5
5
  platform: arm64-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: 2023-12-13 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
@@ -31,14 +31,14 @@ dependencies:
31
31
  requirements:
32
32
  - - "~>"
33
33
  - !ruby/object:Gem::Version
34
- version: 1.4.0.rc2
34
+ version: 1.4.0
35
35
  type: :development
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - "~>"
40
40
  - !ruby/object:Gem::Version
41
- version: 1.4.0.rc2
41
+ version: 1.4.0
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: rspec
44
44
  requirement: !ruby/object:Gem::Requirement
@@ -108,9 +108,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
108
108
  version: 3.4.dev
109
109
  required_rubygems_version: !ruby/object:Gem::Requirement
110
110
  requirements:
111
- - - ">"
111
+ - - ">="
112
112
  - !ruby/object:Gem::Version
113
- version: 1.3.1
113
+ version: '0'
114
114
  requirements: []
115
115
  rubygems_version: 3.3.26
116
116
  signing_key: