re2 1.21.0 → 1.21.2

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.
Files changed (92) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +3 -8
  3. package/binding.gyp +12 -4
  4. package/lib/accessors.cc +1 -1
  5. package/lib/addon.cc +100 -31
  6. package/lib/exec.cc +2 -4
  7. package/lib/match.cc +2 -4
  8. package/lib/replace.cc +27 -15
  9. package/lib/search.cc +1 -3
  10. package/lib/split.cc +1 -3
  11. package/lib/test.cc +2 -4
  12. package/lib/util.h +1 -4
  13. package/lib/wrapped_re2.h +42 -15
  14. package/package.json +9 -4
  15. package/re2.js +33 -32
  16. package/vendor/re2/.github/workflows/ci-bazel.yml +2 -2
  17. package/vendor/re2/.github/workflows/ci-cmake.yml +8 -14
  18. package/vendor/re2/.github/workflows/ci.yml +12 -9
  19. package/vendor/re2/.github/workflows/pages.yml +3 -3
  20. package/vendor/re2/.github/workflows/pr.yml +1 -1
  21. package/vendor/re2/.github/workflows/python.yml +7 -7
  22. package/vendor/re2/.github/workflows/release.yml +1 -1
  23. package/vendor/re2/BUILD.bazel +37 -2
  24. package/vendor/re2/CMakeLists.txt +6 -1
  25. package/vendor/re2/MODULE.bazel +3 -3
  26. package/vendor/re2/Makefile +5 -3
  27. package/vendor/re2/python/_re2.cc +9 -2
  28. package/vendor/re2/python/setup.py +1 -1
  29. package/vendor/re2/re2/bitmap256.cc +4 -4
  30. package/vendor/re2/re2/bitmap256.h +11 -9
  31. package/vendor/re2/re2/bitstate.cc +9 -6
  32. package/vendor/re2/re2/compile.cc +14 -11
  33. package/vendor/re2/re2/dfa.cc +26 -22
  34. package/vendor/re2/re2/filtered_re2.cc +8 -5
  35. package/vendor/re2/re2/fuzzing/re2_fuzzer.cc +2 -0
  36. package/vendor/re2/re2/mimics_pcre.cc +3 -3
  37. package/vendor/re2/re2/nfa.cc +21 -17
  38. package/vendor/re2/re2/onepass.cc +17 -15
  39. package/vendor/re2/re2/parse.cc +14 -13
  40. package/vendor/re2/re2/prefilter.cc +15 -13
  41. package/vendor/re2/re2/prefilter.h +3 -2
  42. package/vendor/re2/re2/prefilter_tree.cc +18 -18
  43. package/vendor/re2/re2/prefilter_tree.h +5 -4
  44. package/vendor/re2/re2/prog.cc +39 -31
  45. package/vendor/re2/re2/prog.h +42 -16
  46. package/vendor/re2/re2/re2.cc +56 -51
  47. package/vendor/re2/re2/re2.h +23 -27
  48. package/vendor/re2/re2/regexp.cc +13 -11
  49. package/vendor/re2/re2/regexp.h +40 -11
  50. package/vendor/re2/re2/set.cc +15 -10
  51. package/vendor/re2/re2/simplify.cc +13 -9
  52. package/vendor/re2/re2/sparse_array.h +9 -7
  53. package/vendor/re2/re2/sparse_set.h +9 -7
  54. package/vendor/re2/re2/testing/backtrack.cc +8 -6
  55. package/vendor/re2/re2/testing/charclass_test.cc +1 -1
  56. package/vendor/re2/re2/testing/compile_test.cc +10 -7
  57. package/vendor/re2/re2/testing/dfa_test.cc +15 -12
  58. package/vendor/re2/re2/testing/dump.cc +5 -4
  59. package/vendor/re2/re2/testing/exhaustive1_test.cc +1 -0
  60. package/vendor/re2/re2/testing/exhaustive2_test.cc +2 -2
  61. package/vendor/re2/re2/testing/exhaustive3_test.cc +3 -3
  62. package/vendor/re2/re2/testing/exhaustive_test.cc +0 -1
  63. package/vendor/re2/re2/testing/exhaustive_tester.cc +14 -5
  64. package/vendor/re2/re2/testing/exhaustive_tester.h +1 -0
  65. package/vendor/re2/re2/testing/filtered_re2_test.cc +12 -11
  66. package/vendor/re2/re2/testing/mimics_pcre_test.cc +2 -1
  67. package/vendor/re2/re2/testing/null_walker.cc +2 -3
  68. package/vendor/re2/re2/testing/parse_test.cc +4 -2
  69. package/vendor/re2/re2/testing/possible_match_test.cc +9 -6
  70. package/vendor/re2/re2/testing/random_test.cc +1 -1
  71. package/vendor/re2/re2/testing/re2_arg_test.cc +4 -5
  72. package/vendor/re2/re2/testing/re2_test.cc +13 -9
  73. package/vendor/re2/re2/testing/regexp_benchmark.cc +189 -153
  74. package/vendor/re2/re2/testing/regexp_generator.cc +11 -7
  75. package/vendor/re2/re2/testing/regexp_generator.h +1 -0
  76. package/vendor/re2/re2/testing/regexp_test.cc +3 -2
  77. package/vendor/re2/re2/testing/required_prefix_test.cc +2 -1
  78. package/vendor/re2/re2/testing/search_test.cc +6 -3
  79. package/vendor/re2/re2/testing/set_test.cc +4 -4
  80. package/vendor/re2/re2/testing/simplify_test.cc +2 -3
  81. package/vendor/re2/re2/testing/string_generator.cc +11 -8
  82. package/vendor/re2/re2/testing/string_generator.h +1 -0
  83. package/vendor/re2/re2/testing/string_generator_test.cc +6 -2
  84. package/vendor/re2/re2/testing/tester.cc +46 -40
  85. package/vendor/re2/re2/testing/tester.h +1 -1
  86. package/vendor/re2/re2/tostring.cc +5 -4
  87. package/vendor/re2/re2/walker-inl.h +4 -3
  88. package/vendor/re2/util/pcre.cc +3 -2
  89. package/vendor/re2/util/pcre.h +16 -16
  90. package/lib/str-val.cc +0 -112
  91. package/lib/str-val.h +0 -32
  92. package/vendor/re2/util/logging.h +0 -109
package/LICENSE CHANGED
@@ -7,7 +7,7 @@ The text of the BSD license is reproduced below.
7
7
  The "New" BSD License:
8
8
  **********************
9
9
 
10
- Copyright (c) 2005-2020, Eugene Lazutkin
10
+ Copyright (c) 2005-2024, Eugene Lazutkin
11
11
  All rights reserved.
12
12
 
13
13
  Redistribution and use in source and binary forms, with or without
package/README.md CHANGED
@@ -353,6 +353,8 @@ console.log('re2_res : ' + re2_res); // prints: re2_res : abc,a,b,c
353
353
 
354
354
  ## Release history
355
355
 
356
+ - 1.21.2 *Fixed another memory regression reported by [matthewvalentine](https://github.com/matthewvalentine), thx! Updated deps. Added more tests and benchmarks.*
357
+ - 1.21.1 *Fixed a memory regression reported by [matthewvalentine](https://github.com/matthewvalentine), thx! Updated deps.*
356
358
  - 1.21.0 *Fixed the performance problem reported by [matthewvalentine](https://github.com/matthewvalentine) (thx!). The change improves performance for multiple use cases.*
357
359
  - 1.20.12 *Updated deps. Maintenance chores. Fixes for buffer-related bugs: `exec()` index (reported by [matthewvalentine](https://github.com/matthewvalentine), thx) and `match()` index.*
358
360
  - 1.20.11 *Updated deps. Added support for Node 22 (thx, [Elton Leong](https://github.com/eltonkl)).*
@@ -367,16 +369,9 @@ console.log('re2_res : ' + re2_res); // prints: re2_res : abc,a,b,c
367
369
  - 1.20.2 *Fix: added a missing C++ file, which caused a bug on Alpine Linux. Thx, [rbitanga-manticore](https://github.com/rbitanga-manticore).*
368
370
  - 1.20.1 *Fix: files included in the npm package to build the C++ code.*
369
371
  - 1.20.0 *Updated RE2. New version uses `abseil-cpp` and required the adaptation work. Thx, [Stefano Rivera](https://github.com/stefanor).*
370
- - 1.19.2 *Bugfix: infinite loop in matchAll() with empty matches. Thx, [ziyunfei](https://github.com/ziyunfei).*
371
- - 1.19.1 *Bugfix: indices for the `d` flag when `lastIndex` is non zero. Bugfix: the match result. Thx, [teebu](https://github.com/teebu).*
372
- - 1.19.0 *Added `hasIndices` AKA the `d` flag. Thx, [teebu](https://github.com/teebu).*
373
- - 1.18.3 *Fixed bug with non-matched groups. Thx, [Dan Setterquist](https://github.com/dset).*
374
- - 1.18.2 *Reference to the binary module by its full name.*
375
- - 1.18.1 *Support for Node 16, 18, 20 + Darwin arm64 precompiled binaries.*
376
- - 1.18.0 *Modified TS bindings, added a type test (thx, [Kenichi Kamiya](https://github.com/kachick) and [Jamie Magee](https://github.com/JamieMagee)).*
377
372
 
378
373
  The rest can be consulted in the project's wiki [Release history](https://github.com/uhop/node-re2/wiki/Release-history).
379
374
 
380
375
  ## License
381
376
 
382
- BSD
377
+ BSD-3-Clause
package/binding.gyp CHANGED
@@ -3,8 +3,9 @@
3
3
  {
4
4
  "target_name": "re2",
5
5
  "sources": [
6
- "lib/str-val.cc",
7
6
  "lib/addon.cc",
7
+ "lib/accessors.cc",
8
+ "lib/util.cc",
8
9
  "lib/new.cc",
9
10
  "lib/exec.cc",
10
11
  "lib/test.cc",
@@ -13,9 +14,6 @@
13
14
  "lib/search.cc",
14
15
  "lib/split.cc",
15
16
  "lib/to_string.cc",
16
- "lib/accessors.cc",
17
- "lib/util.cc",
18
- "lib/str-val.cc",
19
17
  "vendor/re2/re2/bitmap256.cc",
20
18
  "vendor/re2/re2/bitstate.cc",
21
19
  "vendor/re2/re2/compile.cc",
@@ -44,6 +42,7 @@
44
42
  "vendor/abseil-cpp/absl/base/internal/raw_logging.cc",
45
43
  "vendor/abseil-cpp/absl/base/internal/spinlock.cc",
46
44
  "vendor/abseil-cpp/absl/base/internal/spinlock_wait.cc",
45
+ "vendor/abseil-cpp/absl/base/internal/strerror.cc",
47
46
  "vendor/abseil-cpp/absl/base/internal/sysinfo.cc",
48
47
  "vendor/abseil-cpp/absl/base/internal/thread_identity.cc",
49
48
  "vendor/abseil-cpp/absl/base/internal/throw_delegate.cc",
@@ -52,6 +51,7 @@
52
51
  "vendor/abseil-cpp/absl/container/internal/raw_hash_set.cc",
53
52
  "vendor/abseil-cpp/absl/debugging/internal/address_is_readable.cc",
54
53
  "vendor/abseil-cpp/absl/debugging/internal/elf_mem_image.cc",
54
+ "vendor/abseil-cpp/absl/debugging/internal/examine_stack.cc",
55
55
  "vendor/abseil-cpp/absl/debugging/internal/vdso_support.cc",
56
56
  "vendor/abseil-cpp/absl/debugging/stacktrace.cc",
57
57
  "vendor/abseil-cpp/absl/debugging/symbolize.cc",
@@ -66,6 +66,14 @@
66
66
  "vendor/abseil-cpp/absl/hash/internal/city.cc",
67
67
  "vendor/abseil-cpp/absl/hash/internal/hash.cc",
68
68
  "vendor/abseil-cpp/absl/hash/internal/low_level_hash.cc",
69
+ "vendor/abseil-cpp/absl/log/internal/globals.cc",
70
+ "vendor/abseil-cpp/absl/log/internal/log_format.cc",
71
+ "vendor/abseil-cpp/absl/log/internal/log_message.cc",
72
+ "vendor/abseil-cpp/absl/log/internal/log_sink_set.cc",
73
+ "vendor/abseil-cpp/absl/log/internal/nullguard.cc",
74
+ "vendor/abseil-cpp/absl/log/internal/proto.cc",
75
+ "vendor/abseil-cpp/absl/log/globals.cc",
76
+ "vendor/abseil-cpp/absl/log/log_sink.cc",
69
77
  "vendor/abseil-cpp/absl/numeric/int128.cc",
70
78
  "vendor/abseil-cpp/absl/strings/ascii.cc",
71
79
  "vendor/abseil-cpp/absl/strings/charconv.cc",
package/lib/accessors.cc CHANGED
@@ -41,7 +41,7 @@ NAN_GETTER(WrappedRE2::GetFlags)
41
41
  std::string flags;
42
42
  if (re2->hasIndices)
43
43
  {
44
- flags = "d";
44
+ flags += "d";
45
45
  }
46
46
  if (re2->global)
47
47
  {
package/lib/addon.cc CHANGED
@@ -1,7 +1,5 @@
1
1
  #include "./wrapped_re2.h"
2
2
 
3
- #include "./str-val.h"
4
-
5
3
  static NAN_METHOD(GetUtf8Length)
6
4
  {
7
5
  auto t = info[0]->ToString(Nan::GetCurrentContext());
@@ -92,55 +90,126 @@ NODE_MODULE_INIT()
92
90
  Nan::Set(module->ToObject(context).ToLocalChecked(), Nan::New("exports").ToLocalChecked(), WrappedRE2::Init());
93
91
  }
94
92
 
93
+ WrappedRE2::~WrappedRE2()
94
+ {
95
+ dropCache();
96
+ }
97
+
95
98
  // private methods
96
99
 
97
- void WrappedRE2::dropLastString()
100
+ void WrappedRE2::dropCache()
98
101
  {
99
- lastString.Reset();
100
- if (lastStringValue)
102
+ if (!lastString.IsEmpty())
101
103
  {
102
- delete lastStringValue;
103
- lastStringValue = nullptr;
104
+ // lastString.ClearWeak();
105
+ lastString.Reset();
104
106
  }
105
- }
106
-
107
- inline size_t countBytes(const char *data, size_t from, size_t n)
108
- {
109
- for (; n > 0; --n)
107
+ if (!lastCache.IsEmpty())
110
108
  {
111
- size_t s = getUtf8CharSize(data[from]);
112
- from += s;
113
- if (s == 4 && n >= 2)
114
- --n; // this utf8 character will take two utf16 characters
115
- // the decrement above is protected to avoid an overflow of an unsigned integer
109
+ // lastCache.ClearWeak();
110
+ lastCache.Reset();
116
111
  }
117
- return from;
112
+ lastStringValue.clear();
118
113
  }
119
114
 
120
- void WrappedRE2::prepareLastString(const v8::Local<v8::Value> &arg, bool ignoreLastIndex)
115
+ const StrVal& WrappedRE2::prepareArgument(const v8::Local<v8::Value> &arg, bool ignoreLastIndex)
121
116
  {
122
117
  size_t startFrom = ignoreLastIndex ? 0 : lastIndex;
123
118
 
119
+ if (lastString == arg && !node::Buffer::HasInstance(arg) && !lastCache.IsEmpty())
120
+ {
121
+ // we have a properly cached string
122
+ lastStringValue.setIndex(startFrom);
123
+ return lastStringValue;
124
+ }
125
+
126
+ dropCache();
127
+
124
128
  if (node::Buffer::HasInstance(arg))
125
129
  {
126
- dropLastString();
127
- lastStringValue = new StrValBuffer(arg, startFrom);
130
+ // no need to cache buffers
131
+
132
+ lastString.Reset(arg);
133
+ static_cast<v8::PersistentBase<v8::Value> &>(lastString).SetWeak();
134
+
135
+ auto argSize = node::Buffer::Length(arg);
136
+ lastStringValue.reset(arg, argSize, argSize, startFrom, true);
137
+
138
+ return lastStringValue;
139
+ }
140
+
141
+ // caching the string
142
+
143
+ auto t = arg->ToString(Nan::GetCurrentContext());
144
+ if (t.IsEmpty())
145
+ {
146
+ // do not process bad strings
147
+ lastStringValue.isBad = true;
148
+ return lastStringValue;
149
+ }
150
+
151
+ lastString.Reset(arg);
152
+ static_cast<v8::PersistentBase<v8::Value> &>(lastString).SetWeak();
153
+
154
+ auto s = t.ToLocalChecked();
155
+ auto argLength = Nan::DecodeBytes(s);
156
+
157
+ auto buffer = node::Buffer::New(v8::Isolate::GetCurrent(), s).ToLocalChecked();
158
+ lastCache.Reset(buffer);
159
+ static_cast<v8::PersistentBase<v8::Object> &>(lastCache).SetWeak();
160
+
161
+ auto argSize = node::Buffer::Length(buffer);
162
+ lastStringValue.reset(buffer, argSize, argLength, startFrom);
163
+
164
+ return lastStringValue;
165
+ };
166
+
167
+ // StrVal
168
+
169
+ void StrVal::setIndex(size_t newIndex)
170
+ {
171
+ isValidIndex = newIndex <= length;
172
+ if (!isValidIndex)
173
+ {
174
+ index = newIndex;
175
+ byteIndex = 0;
176
+ return;
177
+ }
178
+
179
+ if (newIndex == index)
180
+ return;
181
+
182
+ if (isBuffer)
183
+ {
184
+ byteIndex = index = newIndex;
128
185
  return;
129
186
  }
130
187
 
131
188
  // String
132
189
 
133
- // check if the same string is already in the cache
134
- if (lastString == arg && lastStringValue)
190
+ if (!newIndex)
135
191
  {
136
- if (!global && !sticky)
137
- return; // we are good
138
- lastStringValue->setIndex(startFrom);
192
+ byteIndex = index = 0;
139
193
  return;
140
194
  }
141
195
 
142
- dropLastString();
143
- lastString.Reset(arg);
144
- static_cast<v8::PersistentBase<v8::Value>&>(lastString).SetWeak();
145
- lastStringValue = new StrValString(arg, startFrom);
146
- };
196
+ if (newIndex == length)
197
+ {
198
+ byteIndex = size;
199
+ index = length;
200
+ return;
201
+ }
202
+
203
+ byteIndex = index < newIndex ? getUtf16PositionByCounter(data, byteIndex, newIndex - index) : getUtf16PositionByCounter(data, 0, newIndex);
204
+ index = newIndex;
205
+ }
206
+
207
+ void StrVal::reset(const v8::Local<v8::Value> &arg, size_t argSize, size_t argLength, size_t newIndex, bool buffer)
208
+ {
209
+ clear();
210
+ isBuffer = buffer;
211
+ size = argSize;
212
+ length = argLength;
213
+ data = node::Buffer::Data(arg);
214
+ setIndex(newIndex);
215
+ }
package/lib/exec.cc CHANGED
@@ -1,5 +1,4 @@
1
1
  #include "./wrapped_re2.h"
2
- #include "./str-val.h"
3
2
 
4
3
  #include <vector>
5
4
 
@@ -15,13 +14,12 @@ NAN_METHOD(WrappedRE2::Exec)
15
14
  return;
16
15
  }
17
16
 
18
- re2->prepareLastString(info[0]);
19
- StrValBase &str = *re2->lastStringValue;
17
+ auto str = re2->prepareArgument(info[0]);
20
18
  if (str.isBad) return; // throws an exception
21
19
 
22
20
  if (re2->global || re2->sticky)
23
21
  {
24
- if (!str.isIndexValid)
22
+ if (!str.isValidIndex)
25
23
  {
26
24
  re2->lastIndex = 0;
27
25
  info.GetReturnValue().SetNull();
package/lib/match.cc CHANGED
@@ -1,5 +1,4 @@
1
1
  #include "./wrapped_re2.h"
2
- #include "./str-val.h"
3
2
 
4
3
  #include <vector>
5
4
 
@@ -15,11 +14,10 @@ NAN_METHOD(WrappedRE2::Match)
15
14
  return;
16
15
  }
17
16
 
18
- re2->prepareLastString(info[0], re2->global);
19
- StrValBase &str = *re2->lastStringValue;
17
+ auto str = re2->prepareArgument(info[0], re2->global);
20
18
  if (str.isBad) return; // throws an exception
21
19
 
22
- if (!str.isIndexValid)
20
+ if (!str.isValidIndex)
23
21
  {
24
22
  re2->lastIndex = 0;
25
23
  info.GetReturnValue().SetNull();
package/lib/replace.cc CHANGED
@@ -1,5 +1,4 @@
1
1
  #include "./wrapped_re2.h"
2
- #include "./str-val.h"
3
2
 
4
3
  #include <algorithm>
5
4
  #include <memory>
@@ -213,7 +212,7 @@ inline std::string replace(
213
212
 
214
213
  static Nan::Maybe<std::string> replace(
215
214
  WrappedRE2 *re2,
216
- const StrValBase &replacee,
215
+ const StrVal &replacee,
217
216
  const char *replacer,
218
217
  size_t replacer_size)
219
218
  {
@@ -370,13 +369,19 @@ inline Nan::Maybe<std::string> replace(
370
369
  return Nan::Just(std::string(node::Buffer::Data(result), node::Buffer::Length(result)));
371
370
  }
372
371
 
373
- StrValString val(result);
374
- return Nan::Just(std::string(val.data, val.size));
372
+ auto t = result->ToString(Nan::GetCurrentContext());
373
+ if (t.IsEmpty())
374
+ {
375
+ return Nan::Nothing<std::string>();
376
+ }
377
+
378
+ v8::String::Utf8Value s(v8::Isolate::GetCurrent(), t.ToLocalChecked());
379
+ return Nan::Just(std::string(*s));
375
380
  }
376
381
 
377
382
  static Nan::Maybe<std::string> replace(
378
383
  WrappedRE2 *re2,
379
- const StrValBase &replacee,
384
+ const StrVal &replacee,
380
385
  const Nan::Callback *replacer,
381
386
  const v8::Local<v8::Value> &input,
382
387
  bool useBuffers)
@@ -492,11 +497,10 @@ NAN_METHOD(WrappedRE2::Replace)
492
497
  return;
493
498
  }
494
499
 
495
- re2->prepareLastString(info[0]);
496
- StrValBase &replacee = *re2->lastStringValue;
500
+ auto replacee = re2->prepareArgument(info[0]);
497
501
  if (replacee.isBad) return; // throws an exception
498
502
 
499
- if (!replacee.isIndexValid)
503
+ if (!replacee.isValidIndex)
500
504
  {
501
505
  info.GetReturnValue().Set(info[0]);
502
506
  return;
@@ -518,15 +522,23 @@ NAN_METHOD(WrappedRE2::Replace)
518
522
  }
519
523
  else
520
524
  {
521
- StrValBase *replacer = StrValBase::New(info[1]);
522
- if (replacer->isBad) return; // throws an exception
523
-
524
- if (!replacer->data)
525
+ v8::Local<v8::Object> replacer;
526
+ if (node::Buffer::HasInstance(info[1]))
525
527
  {
526
- info.GetReturnValue().Set(info[0]);
527
- return;
528
+ replacer = info[1].As<v8::Object>();
529
+ }
530
+ else
531
+ {
532
+ auto t = info[1]->ToString(Nan::GetCurrentContext());
533
+ if (t.IsEmpty())
534
+ return; // throws an exception
535
+ replacer = node::Buffer::New(v8::Isolate::GetCurrent(), t.ToLocalChecked()).ToLocalChecked();
528
536
  }
529
- const auto replaced = replace(re2, replacee, replacer->data, replacer->size);
537
+
538
+ auto data = node::Buffer::Data(replacer);
539
+ auto size = node::Buffer::Length(replacer);
540
+
541
+ const auto replaced = replace(re2, replacee, data, size);
530
542
  if (replaced.IsNothing())
531
543
  {
532
544
  info.GetReturnValue().Set(info[0]);
package/lib/search.cc CHANGED
@@ -1,5 +1,4 @@
1
1
  #include "./wrapped_re2.h"
2
- #include "./str-val.h"
3
2
 
4
3
  NAN_METHOD(WrappedRE2::Search)
5
4
  {
@@ -13,8 +12,7 @@ NAN_METHOD(WrappedRE2::Search)
13
12
  return;
14
13
  }
15
14
 
16
- re2->prepareLastString(info[0], true);
17
- StrValBase &str = *re2->lastStringValue;
15
+ auto str = re2->prepareArgument(info[0], true);
18
16
  if (str.isBad) return; // throws an exception
19
17
 
20
18
  if (!str.data)
package/lib/split.cc CHANGED
@@ -1,5 +1,4 @@
1
1
  #include "./wrapped_re2.h"
2
- #include "./str-val.h"
3
2
 
4
3
  #include <algorithm>
5
4
  #include <limits>
@@ -20,8 +19,7 @@ NAN_METHOD(WrappedRE2::Split)
20
19
  return;
21
20
  }
22
21
 
23
- re2->prepareLastString(info[0], true);
24
- StrValBase &str = *re2->lastStringValue;
22
+ auto str = re2->prepareArgument(info[0], true);
25
23
  if (str.isBad) return; // throws an exception
26
24
 
27
25
  size_t limit = std::numeric_limits<size_t>::max();
package/lib/test.cc CHANGED
@@ -1,5 +1,4 @@
1
1
  #include "./wrapped_re2.h"
2
- #include "./str-val.h"
3
2
 
4
3
  #include <vector>
5
4
 
@@ -15,8 +14,7 @@ NAN_METHOD(WrappedRE2::Test)
15
14
  return;
16
15
  }
17
16
 
18
- re2->prepareLastString(info[0]);
19
- StrValBase &str = *re2->lastStringValue;
17
+ auto str = re2->prepareArgument(info[0]);
20
18
  if (str.isBad) return; // throws an exception
21
19
 
22
20
  if (!re2->global && !re2->sticky)
@@ -25,7 +23,7 @@ NAN_METHOD(WrappedRE2::Test)
25
23
  return;
26
24
  }
27
25
 
28
- if (!str.isIndexValid)
26
+ if (!str.isValidIndex)
29
27
  {
30
28
  re2->lastIndex = 0;
31
29
  info.GetReturnValue().SetNull();
package/lib/util.h CHANGED
@@ -1,5 +1,4 @@
1
- #ifndef UTIL_H_
2
- #define UTIL_H_
1
+ #pragma once
3
2
 
4
3
  #include "./wrapped_re2.h"
5
4
 
@@ -13,5 +12,3 @@ void consoleCall(const v8::Local<v8::String> &methodName, v8::Local<v8::Value> t
13
12
  void printDeprecationWarning(const char *warning);
14
13
 
15
14
  v8::Local<v8::String> callToString(const v8::Local<v8::Object> &object);
16
-
17
- #endif
package/lib/wrapped_re2.h CHANGED
@@ -1,13 +1,30 @@
1
- #ifndef WRAPPED_RE2_H_
2
- #define WRAPPED_RE2_H_
1
+ #pragma once
3
2
 
3
+ #include <string>
4
4
  #include <nan.h>
5
-
6
5
  #include <re2/re2.h>
7
6
 
8
- #include <string>
7
+ struct StrVal
8
+ {
9
+ char *data;
10
+ size_t size, length;
11
+ size_t index, byteIndex;
12
+ bool isBuffer, isValidIndex, isBad;
13
+
14
+ StrVal() : data(NULL), size(0), length(0), index(0), byteIndex(0), isBuffer(false), isValidIndex(false), isBad(false) {}
9
15
 
10
- struct StrValBase;
16
+ operator re2::StringPiece() const { return re2::StringPiece(data, size); }
17
+
18
+ void setIndex(size_t newIndex = 0);
19
+ void reset(const v8::Local<v8::Value> &arg, size_t size, size_t length, size_t newIndex = 0, bool buffer = false);
20
+
21
+ void clear()
22
+ {
23
+ isBad = isBuffer = isValidIndex = false;
24
+ size = length = index = byteIndex = 0;
25
+ data = nullptr;
26
+ }
27
+ };
11
28
 
12
29
  class WrappedRE2 : public Nan::ObjectWrap
13
30
  {
@@ -29,8 +46,7 @@ private:
29
46
  dotAll(s),
30
47
  sticky(y),
31
48
  hasIndices(d),
32
- lastIndex(0),
33
- lastStringValue(nullptr) {}
49
+ lastIndex(0) {}
34
50
 
35
51
  static NAN_METHOD(New);
36
52
  static NAN_METHOD(ToString);
@@ -63,10 +79,7 @@ private:
63
79
  static NAN_SETTER(SetUnicodeWarningLevel);
64
80
 
65
81
  public:
66
- ~WrappedRE2()
67
- {
68
- dropLastString();
69
- }
82
+ ~WrappedRE2();
70
83
 
71
84
  static v8::Local<v8::Function> Init();
72
85
 
@@ -97,12 +110,15 @@ public:
97
110
  bool hasIndices;
98
111
  size_t lastIndex;
99
112
 
113
+ friend struct PrepareLastString;
114
+
100
115
  private:
101
116
  Nan::Persistent<v8::Value> lastString; // weak pointer
102
- StrValBase *lastStringValue;
117
+ Nan::Persistent<v8::Object> lastCache; // weak pointer
118
+ StrVal lastStringValue;
103
119
 
104
- void dropLastString();
105
- void prepareLastString(const v8::Local<v8::Value> &arg, bool ignoreLastIndex = false);
120
+ void dropCache();
121
+ const StrVal &prepareArgument(const v8::Local<v8::Value> &arg, bool ignoreLastIndex = false);
106
122
  };
107
123
 
108
124
  // utilities
@@ -183,4 +199,15 @@ inline size_t getUtf8CharSize(char ch)
183
199
  return ((0xE5000000 >> ((ch >> 3) & 0x1E)) & 3) + 1;
184
200
  }
185
201
 
186
- #endif
202
+ inline size_t getUtf16PositionByCounter(const char *data, size_t from, size_t n)
203
+ {
204
+ for (; n > 0; --n)
205
+ {
206
+ size_t s = getUtf8CharSize(data[from]);
207
+ from += s;
208
+ if (s == 4 && n >= 2)
209
+ --n; // this utf8 character will take two utf16 characters
210
+ // the decrement above is protected to avoid an overflow of an unsigned integer
211
+ }
212
+ return from;
213
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "re2",
3
- "version": "1.21.0",
3
+ "version": "1.21.2",
4
4
  "description": "Bindings for RE2: fast, safe alternative to backtracking regular expression engines.",
5
5
  "homepage": "https://github.com/uhop/node-re2",
6
6
  "bugs": "https://github.com/uhop/node-re2/issues",
@@ -20,7 +20,7 @@
20
20
  "node-gyp": "^10.1.0"
21
21
  },
22
22
  "devDependencies": {
23
- "@types/node": "^20.12.12",
23
+ "@types/node": "^20.14.2",
24
24
  "heya-unit": "^0.3.0",
25
25
  "typescript": "^5.4.5"
26
26
  },
@@ -28,9 +28,14 @@
28
28
  "test": "node tests/tests.js",
29
29
  "ts-test": "tsc",
30
30
  "save-to-github": "save-to-github-cache --artifact build/Release/re2.node",
31
- "install": "install-from-cache --artifact build/Release/re2.node --host-var RE2_DOWNLOAD_MIRROR --skip-path-var RE2_DOWNLOAD_SKIP_PATH --skip-ver-var RE2_DOWNLOAD_SKIP_VER || node-gyp rebuild",
31
+ "install": "install-from-cache --artifact build/Release/re2.node --host-var RE2_DOWNLOAD_MIRROR --skip-path-var RE2_DOWNLOAD_SKIP_PATH --skip-ver-var RE2_DOWNLOAD_SKIP_VER || node-gyp -j max rebuild",
32
32
  "verify-build": "node scripts/verify-build.js",
33
- "rebuild": "node-gyp rebuild"
33
+ "build:dev": "node-gyp -j max build --debug",
34
+ "build": "node-gyp -j max build",
35
+ "rebuild:dev": "node-gyp -j max rebuild --debug",
36
+ "rebuild": "node-gyp -j max rebuild",
37
+ "clean": "node-gyp clean",
38
+ "reconfigure": "node-gyp configure"
34
39
  },
35
40
  "github": "https://github.com/uhop/node-re2",
36
41
  "repository": {
package/re2.js CHANGED
@@ -1,38 +1,39 @@
1
1
  'use strict';
2
2
 
3
3
  const RE2 = require('./build/Release/re2.node');
4
+ // const RE2 = require('./build/Debug/re2.node');
4
5
 
5
- if (typeof Symbol != 'undefined') {
6
- Symbol.match &&
7
- (RE2.prototype[Symbol.match] = function (str) {
8
- return this.match(str);
9
- });
10
- Symbol.search &&
11
- (RE2.prototype[Symbol.search] = function (str) {
12
- return this.search(str);
13
- });
14
- Symbol.replace &&
15
- (RE2.prototype[Symbol.replace] = function (str, repl) {
16
- return this.replace(str, repl);
17
- });
18
- Symbol.split &&
19
- (RE2.prototype[Symbol.split] = function (str, limit) {
20
- return this.split(str, limit);
21
- });
22
- Symbol.matchAll &&
23
- (RE2.prototype[Symbol.matchAll] = function* (str) {
24
- if (!this.global) {
25
- throw TypeError('String.prototype.matchAll called with a non-global RE2 argument');
26
- }
27
- const re = new RE2(this);
28
- re.lastIndex = this.lastIndex;
29
- for (;;) {
30
- const result = re.exec(str);
31
- if (!result) break;
32
- if (result[0] === '') ++re.lastIndex;
33
- yield result;
34
- }
35
- });
36
- }
6
+ const setAliases = (object, dict) => {
7
+ for (let [name, alias] of Object.entries(dict)) {
8
+ Object.defineProperty(
9
+ object,
10
+ alias,
11
+ Object.getOwnPropertyDescriptor(object, name)
12
+ );
13
+ }
14
+ };
15
+
16
+ setAliases(RE2.prototype, {
17
+ match: Symbol.match,
18
+ search: Symbol.search,
19
+ replace: Symbol.replace,
20
+ split: Symbol.split
21
+ });
22
+
23
+ RE2.prototype[Symbol.matchAll] = function* (str) {
24
+ if (!this.global)
25
+ throw TypeError(
26
+ 'String.prototype.matchAll() is called with a non-global RE2 argument'
27
+ );
28
+
29
+ const re = new RE2(this);
30
+ re.lastIndex = this.lastIndex;
31
+ for (;;) {
32
+ const result = re.exec(str);
33
+ if (!result) break;
34
+ if (result[0] === '') ++re.lastIndex;
35
+ yield result;
36
+ }
37
+ };
37
38
 
38
39
  module.exports = RE2;
@@ -14,8 +14,8 @@ jobs:
14
14
  env:
15
15
  BAZELISK_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
16
16
  steps:
17
- - uses: actions/checkout@v4.1.4
18
- - uses: bazel-contrib/setup-bazel@0.8.2
17
+ - uses: actions/checkout@v4.1.6
18
+ - uses: bazel-contrib/setup-bazel@0.8.4
19
19
  with:
20
20
  bazelisk-version: '1.x'
21
21
  - run: .github/bazel.sh