re2 1.17.2 → 1.17.6

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 (41) hide show
  1. package/.github/actions/{linux-alpine-node-17 → linux-alpine-node-18}/Dockerfile +1 -1
  2. package/.github/actions/linux-alpine-node-18/action.yml +7 -0
  3. package/.github/actions/{linux-alpine-node-17 → linux-alpine-node-18}/entrypoint.sh +0 -0
  4. package/.github/actions/linux-node-12/action.yml +2 -2
  5. package/.github/actions/linux-node-12/entrypoint.sh +1 -1
  6. package/.github/actions/linux-node-18/Dockerfile +6 -0
  7. package/.github/actions/linux-node-18/action.yml +12 -0
  8. package/.github/actions/{linux-alpine-node-12 → linux-node-18}/entrypoint.sh +1 -0
  9. package/.github/workflows/build.yml +29 -26
  10. package/.github/workflows/tests.yml +8 -5
  11. package/.prettierrc +1 -1
  12. package/README.md +9 -0
  13. package/lib/accessors.cc +16 -0
  14. package/lib/addon.cc +1 -0
  15. package/lib/new.cc +9 -2
  16. package/lib/replace.cc +44 -41
  17. package/lib/to_string.cc +4 -0
  18. package/lib/wrapped_re2.h +5 -3
  19. package/package.json +3 -3
  20. package/re2.js +13 -0
  21. package/tests/test_exec.js +238 -223
  22. package/tests/test_general.js +14 -0
  23. package/tests/test_matchAll.js +81 -0
  24. package/tests/test_prototype.js +1 -0
  25. package/tests/test_replace.js +278 -227
  26. package/tests/test_toString.js +1 -0
  27. package/tests/tests.js +1 -0
  28. package/vendor/re2/fuzzing/compiler-rt/include/fuzzer/FuzzedDataProvider.h +328 -236
  29. package/vendor/re2/make_unicode_casefold.py +1 -1
  30. package/vendor/re2/make_unicode_groups.py +1 -1
  31. package/vendor/re2/prefilter_tree.cc +67 -82
  32. package/vendor/re2/prefilter_tree.h +3 -2
  33. package/vendor/re2/prog.cc +5 -2
  34. package/vendor/re2/prog.h +0 -1
  35. package/vendor/re2/re2.h +1 -1
  36. package/vendor/re2/regexp.cc +1 -2
  37. package/vendor/re2/stringpiece.h +10 -7
  38. package/vendor/util/mutex.h +4 -4
  39. package/.github/actions/linux-alpine-node-12/Dockerfile +0 -6
  40. package/.github/actions/linux-alpine-node-12/action.yml +0 -7
  41. package/.github/actions/linux-alpine-node-17/action.yml +0 -7
@@ -1,4 +1,4 @@
1
- FROM node:17-alpine
1
+ FROM node:18-alpine
2
2
 
3
3
  RUN apk add --no-cache python3 make gcc g++
4
4
 
@@ -0,0 +1,7 @@
1
+ name: 'Create a binary artifact for Node 18 on Alpine Linux'
2
+ description: 'Create a binary artifact for Node 18 on Alpine Linux using musl'
3
+ runs:
4
+ using: 'docker'
5
+ image: 'Dockerfile'
6
+ args:
7
+ - ${{inputs.node-version}}
@@ -1,5 +1,5 @@
1
- name: 'Create a binary artifact for Node >10 on Linux'
2
- description: 'Create a binary artifact for Node >10 on Linux using CentOS6 and glibc 2.17'
1
+ name: 'Create a binary artifact for Node > 10 on Linux'
2
+ description: 'Create a binary artifact for Node > 10 on Linux using CentOS7 and glibc 2.17'
3
3
  inputs:
4
4
  node-version:
5
5
  description: 'Node.js version'
@@ -2,7 +2,7 @@
2
2
 
3
3
  NVM_DIR=$HOME/.nvm
4
4
 
5
- curl -sS -o- https://raw.githubusercontent.com/creationix/nvm/v0.35.3/install.sh | bash
5
+ curl -sS -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
6
6
  [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
7
7
 
8
8
  nvm install --no-progress $1
@@ -0,0 +1,6 @@
1
+ FROM node:18-buster
2
+
3
+ RUN apt install python3 make gcc g++
4
+
5
+ COPY entrypoint.sh /entrypoint.sh
6
+ ENTRYPOINT ["/entrypoint.sh"]
@@ -0,0 +1,12 @@
1
+ name: 'Create a binary artifact for Node == 18 on Linux'
2
+ description: 'Create a binary artifact for Node == 18 on Linux using node:18-buster'
3
+ inputs:
4
+ node-version:
5
+ description: 'Node.js version'
6
+ required: false
7
+ default: '18'
8
+ runs:
9
+ using: 'docker'
10
+ image: 'Dockerfile'
11
+ args:
12
+ - ${{inputs.node-version}}
@@ -1,6 +1,7 @@
1
1
  #!/bin/sh
2
2
 
3
3
  npm config set unsafe-perm true
4
+ export USERNAME=`whoami`
4
5
  export DEVELOPMENT_SKIP_GETTING_ASSET=true
5
6
  npm i
6
7
  npm run build --if-present
@@ -30,15 +30,18 @@ jobs:
30
30
 
31
31
  strategy:
32
32
  matrix:
33
- os: [windows-latest, macOS-latest]
34
- node-version: [12, 14, 16, 17]
33
+ os: [macOS-latest, windows-latest]
34
+ node-version: [14, 16, 18]
35
+ exclude:
36
+ - os: windows-latest
37
+ node-version: 14
35
38
 
36
39
  steps:
37
- - uses: actions/checkout@v2
40
+ - uses: actions/checkout@v3
38
41
  with:
39
42
  submodules: true
40
43
  - name: Setup Node.js ${{matrix.node-version}}
41
- uses: actions/setup-node@v1
44
+ uses: actions/setup-node@v3
42
45
  with:
43
46
  node-version: ${{matrix.node-version}}
44
47
  - name: Get NPM cache directory
@@ -46,7 +49,7 @@ jobs:
46
49
  run: |
47
50
  echo "::set-output name=dir::$(npm config get cache)"
48
51
  - name: Cache node modules
49
- uses: actions/cache@v2
52
+ uses: actions/cache@v3
50
53
  with:
51
54
  path: ${{steps.npm-cache.outputs.dir}}
52
55
  key: ${{runner.os}}-node-${{hashFiles('**/package-lock.json')}}
@@ -65,7 +68,7 @@ jobs:
65
68
  GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
66
69
  run: npm run save-to-github
67
70
 
68
- build-linux-node:
71
+ build-linux-centos7-node:
69
72
  name: Node.js ${{matrix.node-version}} on CentOS 7
70
73
  needs: create-release
71
74
  runs-on: ubuntu-latest
@@ -73,10 +76,10 @@ jobs:
73
76
 
74
77
  strategy:
75
78
  matrix:
76
- node-version: [12, 14, 16, 17]
79
+ node-version: [14, 16]
77
80
 
78
81
  steps:
79
- - uses: actions/checkout@v2
82
+ - uses: actions/checkout@v3
80
83
  with:
81
84
  submodules: true
82
85
  - name: Get NPM cache directory
@@ -84,7 +87,7 @@ jobs:
84
87
  run: |
85
88
  echo "::set-output name=dir::$(npm config get cache)"
86
89
  - name: Cache node modules
87
- uses: actions/cache@v2
90
+ uses: actions/cache@v3
88
91
  with:
89
92
  path: ${{steps.npm-cache.outputs.dir}}
90
93
  key: Linux-node-${{hashFiles('**/package-lock.json')}}
@@ -98,14 +101,14 @@ jobs:
98
101
  with:
99
102
  node-version: ${{matrix.node-version}}
100
103
 
101
- build-linux-alpine-node-12:
102
- name: Node.js 12 on Alpine Linux
104
+ build-linux-node-18:
105
+ name: Node.js 18 on Debian Buster
103
106
  needs: create-release
104
107
  runs-on: ubuntu-latest
105
108
  continue-on-error: true
106
109
 
107
110
  steps:
108
- - uses: actions/checkout@v2
111
+ - uses: actions/checkout@v3
109
112
  with:
110
113
  submodules: true
111
114
  - name: Get NPM cache directory
@@ -113,15 +116,15 @@ jobs:
113
116
  run: |
114
117
  echo "::set-output name=dir::$(npm config get cache)"
115
118
  - name: Cache node modules
116
- uses: actions/cache@v2
119
+ uses: actions/cache@v3
117
120
  with:
118
121
  path: ${{steps.npm-cache.outputs.dir}}
119
- key: Linux-Alpine-node-${{hashFiles('**/package-lock.json')}}
122
+ key: Linux-node-${{hashFiles('**/package-lock.json')}}
120
123
  restore-keys: |
121
- Linux-Alpine-node-
122
- Linux-Alpine-
124
+ Linux-node-
125
+ Linux-
123
126
  - name: Install, test, and create artifact
124
- uses: ./.github/actions/linux-alpine-node-12/
127
+ uses: ./.github/actions/linux-node-18/
125
128
  env:
126
129
  GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
127
130
 
@@ -132,7 +135,7 @@ jobs:
132
135
  continue-on-error: true
133
136
 
134
137
  steps:
135
- - uses: actions/checkout@v2
138
+ - uses: actions/checkout@v3
136
139
  with:
137
140
  submodules: true
138
141
  - name: Get NPM cache directory
@@ -140,7 +143,7 @@ jobs:
140
143
  run: |
141
144
  echo "::set-output name=dir::$(npm config get cache)"
142
145
  - name: Cache node modules
143
- uses: actions/cache@v2
146
+ uses: actions/cache@v3
144
147
  with:
145
148
  path: ${{steps.npm-cache.outputs.dir}}
146
149
  key: Linux-Alpine-node-${{hashFiles('**/package-lock.json')}}
@@ -159,7 +162,7 @@ jobs:
159
162
  continue-on-error: true
160
163
 
161
164
  steps:
162
- - uses: actions/checkout@v2
165
+ - uses: actions/checkout@v3
163
166
  with:
164
167
  submodules: true
165
168
  - name: Get NPM cache directory
@@ -167,7 +170,7 @@ jobs:
167
170
  run: |
168
171
  echo "::set-output name=dir::$(npm config get cache)"
169
172
  - name: Cache node modules
170
- uses: actions/cache@v2
173
+ uses: actions/cache@v3
171
174
  with:
172
175
  path: ${{steps.npm-cache.outputs.dir}}
173
176
  key: Linux-Alpine-node-${{hashFiles('**/package-lock.json')}}
@@ -179,14 +182,14 @@ jobs:
179
182
  env:
180
183
  GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
181
184
 
182
- build-linux-alpine-node-17:
183
- name: Node.js 17 on Alpine Linux
185
+ build-linux-alpine-node-18:
186
+ name: Node.js 18 on Alpine Linux
184
187
  needs: create-release
185
188
  runs-on: ubuntu-latest
186
189
  continue-on-error: true
187
190
 
188
191
  steps:
189
- - uses: actions/checkout@v2
192
+ - uses: actions/checkout@v3
190
193
  with:
191
194
  submodules: true
192
195
  - name: Get NPM cache directory
@@ -194,7 +197,7 @@ jobs:
194
197
  run: |
195
198
  echo "::set-output name=dir::$(npm config get cache)"
196
199
  - name: Cache node modules
197
- uses: actions/cache@v2
200
+ uses: actions/cache@v3
198
201
  with:
199
202
  path: ${{steps.npm-cache.outputs.dir}}
200
203
  key: Linux-Alpine-node-${{hashFiles('**/package-lock.json')}}
@@ -202,6 +205,6 @@ jobs:
202
205
  Linux-Alpine-node-
203
206
  Linux-Alpine-
204
207
  - name: Install, test, and create artifact
205
- uses: ./.github/actions/linux-alpine-node-17/
208
+ uses: ./.github/actions/linux-alpine-node-18/
206
209
  env:
207
210
  GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
@@ -13,22 +13,25 @@ jobs:
13
13
 
14
14
  strategy:
15
15
  matrix:
16
- os: [ubuntu-latest, windows-latest, macOS-latest]
17
- node-version: [12, 14, 16, 17]
16
+ os: [ubuntu-latest, macOS-latest, windows-latest]
17
+ node-version: [14, 16, 18]
18
+ exclude:
19
+ - os: windows-latest
20
+ node-version: 14
18
21
 
19
22
  steps:
20
- - uses: actions/checkout@v2
23
+ - uses: actions/checkout@v3
21
24
  with:
22
25
  submodules: true
23
26
  - name: Setup Node.js ${{matrix.node-version}}
24
- uses: actions/setup-node@v1
27
+ uses: actions/setup-node@v3
25
28
  with:
26
29
  node-version: ${{matrix.node-version}}
27
30
  - name: Get NPM cache directory
28
31
  id: npm-cache
29
32
  run: echo "::set-output name=dir::$(npm config get cache)"
30
33
  - name: Cache node modules
31
- uses: actions/cache@v2
34
+ uses: actions/cache@v3
32
35
  with:
33
36
  path: ${{steps.npm-cache.outputs.dir}}
34
37
  key: ${{runner.os}}-node-${{hashFiles('**/package-lock.json')}}
package/.prettierrc CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "printWidth": 160,
2
+ "printWidth": 120,
3
3
  "singleQuote": true,
4
4
  "bracketSpacing": false,
5
5
  "arrowParens": "avoid",
package/README.md CHANGED
@@ -54,6 +54,7 @@ Supported properties:
54
54
  * [`re2.global`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/global)
55
55
  * [`re2.ignoreCase`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/ignoreCase)
56
56
  * [`re2.multiline`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/multiline)
57
+ * *Since 1.17.6*: [`re2.dotAll`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/dotAll)
57
58
  * [`re2.unicode`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/unicode)
58
59
  * `RE2` engine always works in the Unicode mode. See details below.
59
60
  * [`re2.sticky`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/sticky)
@@ -69,6 +70,7 @@ Supported methods:
69
70
  Starting with 1.6.0 following well-known symbol-based methods are supported (see [Symbols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol)):
70
71
 
71
72
  * [`re2[Symbol.match](str)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/match)
73
+ * *Since 1.17.5*: [`re2[Symbol.matchAll](str)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/matchAll)
72
74
  * [`re2[Symbol.search](str)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/search)
73
75
  * [`re2[Symbol.replace](str, newSubStr|function)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/replace)
74
76
  * [`re2[Symbol.split](str[, limit])`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/split)
@@ -81,6 +83,9 @@ var re = new RE2("1");
81
83
  "213".search(re); // 1
82
84
  "213".replace(re, "+"); // 2+3
83
85
  "213".split(re); // [ '2', '3' ]
86
+
87
+ Array.from("2131".matchAll(re)); // returns a generator!
88
+ // [['1', index: 1, input: '2131'], ['1', index: 3, input: '2131']]
84
89
  ```
85
90
 
86
91
  Starting with 1.8.0 [named groups](https://tc39.github.io/proposal-regexp-named-groups/) are supported.
@@ -347,6 +352,10 @@ console.log('re2_res : ' + re2_res); // prints: re2_res : abc,a,b,c
347
352
 
348
353
  ## Release history
349
354
 
355
+ - 1.17.6 *Implemented `dotAll`. Thx [Michael Kriese](https://github.com/viceice).*
356
+ - 1.17.5 *Updated deps, updated test/build targets, implemented `matchAll()` (thx, [ThePendulum](https://github.com/ThePendulum) and [David Sichau](https://github.com/DavidSichau)).*
357
+ - 1.17.4 *Updated deps.*
358
+ - 1.17.3 *Fixed bug with zero-length replacements.*
350
359
  - 1.17.2 *Added support for the enhanced local mirroring by updating [install-artifact-from-github](https://github.com/uhop/install-artifact-from-github).*
351
360
  - 1.17.1 *Fix for `lastIndex` for U+10000 - U+10FFFF UTF characters. Thx, [omg](https://github.com/omg).*
352
361
  - 1.17.0 *Updated GYP, added support for Node 17, updated deps.*
package/lib/accessors.cc CHANGED
@@ -51,6 +51,10 @@ NAN_GETTER(WrappedRE2::GetFlags)
51
51
  {
52
52
  flags += "m";
53
53
  }
54
+ if (re2->dotAll)
55
+ {
56
+ flags += "s";
57
+ }
54
58
  flags += "u";
55
59
  if (re2->sticky)
56
60
  {
@@ -96,6 +100,18 @@ NAN_GETTER(WrappedRE2::GetMultiline)
96
100
  info.GetReturnValue().Set(re2->multiline);
97
101
  }
98
102
 
103
+ NAN_GETTER(WrappedRE2::GetDotAll)
104
+ {
105
+ if (!WrappedRE2::HasInstance(info.This()))
106
+ {
107
+ info.GetReturnValue().SetUndefined();
108
+ return;
109
+ }
110
+
111
+ auto re2 = Nan::ObjectWrap::Unwrap<WrappedRE2>(info.This());
112
+ info.GetReturnValue().Set(re2->dotAll);
113
+ }
114
+
99
115
  NAN_GETTER(WrappedRE2::GetUnicode)
100
116
  {
101
117
  if (!WrappedRE2::HasInstance(info.This()))
package/lib/addon.cc CHANGED
@@ -68,6 +68,7 @@ v8::Local<v8::Function> WrappedRE2::Init()
68
68
  Nan::SetAccessor(instanceTemplate, Nan::New("global").ToLocalChecked(), GetGlobal);
69
69
  Nan::SetAccessor(instanceTemplate, Nan::New("ignoreCase").ToLocalChecked(), GetIgnoreCase);
70
70
  Nan::SetAccessor(instanceTemplate, Nan::New("multiline").ToLocalChecked(), GetMultiline);
71
+ Nan::SetAccessor(instanceTemplate, Nan::New("dotAll").ToLocalChecked(), GetDotAll);
71
72
  Nan::SetAccessor(instanceTemplate, Nan::New("unicode").ToLocalChecked(), GetUnicode);
72
73
  Nan::SetAccessor(instanceTemplate, Nan::New("sticky").ToLocalChecked(), GetSticky);
73
74
  Nan::SetAccessor(instanceTemplate, Nan::New("lastIndex").ToLocalChecked(), GetLastIndex, SetLastIndex);
package/lib/new.cc CHANGED
@@ -229,6 +229,7 @@ NAN_METHOD(WrappedRE2::New)
229
229
  bool global = false;
230
230
  bool ignoreCase = false;
231
231
  bool multiline = false;
232
+ bool dotAll = false;
232
233
  bool unicode = false;
233
234
  bool sticky = false;
234
235
 
@@ -262,6 +263,9 @@ NAN_METHOD(WrappedRE2::New)
262
263
  case 'm':
263
264
  multiline = true;
264
265
  break;
266
+ case 's':
267
+ dotAll = true;
268
+ break;
265
269
  case 'u':
266
270
  unicode = true;
267
271
  break;
@@ -299,6 +303,7 @@ NAN_METHOD(WrappedRE2::New)
299
303
  global = bool(flags & v8::RegExp::kGlobal);
300
304
  ignoreCase = bool(flags & v8::RegExp::kIgnoreCase);
301
305
  multiline = bool(flags & v8::RegExp::kMultiline);
306
+ dotAll = bool(flags & v8::RegExp::kDotAll);
302
307
  unicode = bool(flags & v8::RegExp::kUnicode);
303
308
  sticky = bool(flags & v8::RegExp::kSticky);
304
309
  }
@@ -324,6 +329,7 @@ NAN_METHOD(WrappedRE2::New)
324
329
  global = re2->global;
325
330
  ignoreCase = re2->ignoreCase;
326
331
  multiline = re2->multiline;
332
+ dotAll = re2->dotAll;
327
333
  unicode = true;
328
334
  sticky = re2->sticky;
329
335
  }
@@ -376,9 +382,10 @@ NAN_METHOD(WrappedRE2::New)
376
382
  re2::RE2::Options options;
377
383
  options.set_case_sensitive(!ignoreCase);
378
384
  options.set_one_line(!multiline); // to track this state, otherwise it is ignored
379
- options.set_log_errors(false); // inappropriate when embedding
385
+ options.set_dot_nl(dotAll);
386
+ options.set_log_errors(false); // inappropriate when embedding
380
387
 
381
- std::unique_ptr<WrappedRE2> re2(new WrappedRE2(re2::StringPiece(data, size), options, source, global, ignoreCase, multiline, sticky));
388
+ std::unique_ptr<WrappedRE2> re2(new WrappedRE2(re2::StringPiece(data, size), options, source, global, ignoreCase, multiline, dotAll, sticky));
382
389
  if (!re2->regexp.ok())
383
390
  {
384
391
  return Nan::ThrowSyntaxError(re2->regexp.error().c_str());
package/lib/replace.cc CHANGED
@@ -228,7 +228,9 @@ static Nan::Maybe<std::string> replace(WrappedRE2 *re2, const StrVal &replacee,
228
228
  {
229
229
  size_t s = getUtf8CharSize(data[lastIndex]);
230
230
  lastIndex += s;
231
- if (s == 4 && n >= 2) --n; // this utf8 character will take two utf16 characters
231
+ if (s == 4 && n >= 2) {
232
+ --n; // this utf8 character will take two utf16 characters
233
+ }
232
234
  // the decrement above is protected to avoid an overflow of an unsigned integer
233
235
  }
234
236
  }
@@ -245,28 +247,30 @@ static Nan::Maybe<std::string> replace(WrappedRE2 *re2, const StrVal &replacee,
245
247
  while (lastIndex <= size && re2->regexp.Match(str, lastIndex, size, anchor, &groups[0], groups.size()))
246
248
  {
247
249
  noMatch = false;
250
+ auto offset = match.data() - data;
248
251
  if (!re2->global && re2->sticky)
249
252
  {
250
- re2->lastIndex += replacee.isBuffer ? match.data() - data + match.size() - lastIndex : getUtf16Length(data + lastIndex, match.data() + match.size());
253
+ re2->lastIndex += replacee.isBuffer ? offset + match.size() - lastIndex : getUtf16Length(data + lastIndex, match.data() + match.size());
254
+ }
255
+ if (match.data() == data || offset > static_cast<long>(lastIndex))
256
+ {
257
+ result += std::string(data + lastIndex, offset - lastIndex);
251
258
  }
259
+ result += replace(replacer, replacer_size, groups, str, namedGroups);
252
260
  if (match.size())
253
261
  {
254
- if (match.data() == data || match.data() - data > static_cast<long>(lastIndex))
255
- {
256
- result += std::string(data + lastIndex, match.data() - data - lastIndex);
257
- }
258
- result += replace(replacer, replacer_size, groups, str, namedGroups);
259
- lastIndex = match.data() - data + match.size();
262
+ lastIndex = offset + match.size();
263
+ }
264
+ else if (offset < size)
265
+ {
266
+ auto sym_size = getUtf8CharSize(data[offset]);
267
+ result.append(data + offset, sym_size);
268
+ lastIndex = offset + sym_size;
260
269
  }
261
270
  else
262
271
  {
263
- result += replace(replacer, replacer_size, groups, str, namedGroups);
264
- size_t sym_size = getUtf8CharSize(data[lastIndex]);
265
- if (lastIndex < size)
266
- {
267
- result.append(data + lastIndex, sym_size);
268
- }
269
- lastIndex += sym_size;
272
+ lastIndex = size;
273
+ break;
270
274
  }
271
275
  if (!re2->global)
272
276
  {
@@ -295,7 +299,7 @@ static Nan::Maybe<std::string> replace(WrappedRE2 *re2, const StrVal &replacee,
295
299
 
296
300
  inline Nan::Maybe<std::string> replace(const Nan::Callback *replacer, const std::vector<re2::StringPiece> &groups, const re2::StringPiece &str, const v8::Local<v8::Value> &input, bool useBuffers, const std::map<std::string, int> &namedGroups)
297
301
  {
298
- std::vector<v8::Local<v8::Value>> argv;
302
+ std::vector<v8::Local<v8::Value> > argv;
299
303
 
300
304
  auto context = Nan::GetCurrentContext();
301
305
 
@@ -377,7 +381,9 @@ static Nan::Maybe<std::string> replace(WrappedRE2 *re2, const StrVal &replacee,
377
381
  {
378
382
  size_t s = getUtf8CharSize(data[lastIndex]);
379
383
  lastIndex += s;
380
- if (s == 4 && n >= 2) --n; // this utf8 character will take two utf16 characters
384
+ if (s == 4 && n >= 2) {
385
+ --n; // this utf8 character will take two utf16 characters
386
+ }
381
387
  // the decrement above is protected to avoid an overflow of an unsigned integer
382
388
  }
383
389
  }
@@ -396,38 +402,35 @@ static Nan::Maybe<std::string> replace(WrappedRE2 *re2, const StrVal &replacee,
396
402
  while (lastIndex <= size && re2->regexp.Match(str, lastIndex, size, anchor, &groups[0], groups.size()))
397
403
  {
398
404
  noMatch = false;
405
+ auto offset = match.data() - data;
399
406
  if (!re2->global && re2->sticky)
400
407
  {
401
- re2->lastIndex += replacee.isBuffer ? match.data() - data + match.size() - lastIndex : getUtf16Length(data + lastIndex, match.data() + match.size());
408
+ re2->lastIndex += replacee.isBuffer ? offset + match.size() - lastIndex : getUtf16Length(data + lastIndex, match.data() + match.size());
409
+ }
410
+ if (match.data() == data || offset > static_cast<long>(lastIndex))
411
+ {
412
+ result += std::string(data + lastIndex, offset - lastIndex);
402
413
  }
414
+ const auto part = replace(replacer, groups, str, input, useBuffers, namedGroups);
415
+ if (part.IsNothing())
416
+ {
417
+ return part;
418
+ }
419
+ result += part.FromJust();
403
420
  if (match.size())
404
421
  {
405
- if (match.data() == data || match.data() - data > static_cast<long>(lastIndex))
406
- {
407
- result += std::string(data + lastIndex, match.data() - data - lastIndex);
408
- }
409
- const auto part = replace(replacer, groups, str, input, useBuffers, namedGroups);
410
- if (part.IsNothing())
411
- {
412
- return part;
413
- }
414
- result += part.FromJust();
415
- lastIndex = match.data() - data + match.size();
422
+ lastIndex = offset + match.size();
423
+ }
424
+ else if (offset < size)
425
+ {
426
+ auto sym_size = getUtf8CharSize(data[offset]);
427
+ result.append(data + offset, sym_size);
428
+ lastIndex = offset + sym_size;
416
429
  }
417
430
  else
418
431
  {
419
- const auto part = replace(replacer, groups, str, input, useBuffers, namedGroups);
420
- if (part.IsNothing())
421
- {
422
- return part;
423
- }
424
- result += part.FromJust();
425
- size_t sym_size = getUtf8CharSize(data[lastIndex]);
426
- if (lastIndex < size)
427
- {
428
- result.append(data + lastIndex, sym_size);
429
- }
430
- lastIndex += sym_size;
432
+ lastIndex = size;
433
+ break;
431
434
  }
432
435
  if (!re2->global)
433
436
  {
package/lib/to_string.cc CHANGED
@@ -32,6 +32,10 @@ NAN_METHOD(WrappedRE2::ToString)
32
32
  {
33
33
  buffer += "m";
34
34
  }
35
+ if (re2->dotAll)
36
+ {
37
+ buffer += "s";
38
+ }
35
39
  buffer += "u";
36
40
  if (re2->sticky)
37
41
  {
package/lib/wrapped_re2.h CHANGED
@@ -10,9 +10,9 @@
10
10
  class WrappedRE2 : public Nan::ObjectWrap
11
11
  {
12
12
  private:
13
- WrappedRE2(const re2::StringPiece &pattern, const re2::RE2::Options &options, const std::string &s,
14
- const bool &g, const bool &i, const bool &m, const bool &y) : regexp(pattern, options),
15
- source(s), global(g), ignoreCase(i), multiline(m), sticky(y), lastIndex(0) {}
13
+ WrappedRE2(const re2::StringPiece &pattern, const re2::RE2::Options &options, const std::string &src,
14
+ const bool &g, const bool &i, const bool &m, const bool &s, const bool &y) : regexp(pattern, options),
15
+ source(src), global(g), ignoreCase(i), multiline(m), dotAll(s), sticky(y), lastIndex(0) {}
16
16
 
17
17
  static NAN_METHOD(New);
18
18
  static NAN_METHOD(ToString);
@@ -22,6 +22,7 @@ private:
22
22
  static NAN_GETTER(GetGlobal);
23
23
  static NAN_GETTER(GetIgnoreCase);
24
24
  static NAN_GETTER(GetMultiline);
25
+ static NAN_GETTER(GetDotAll);
25
26
  static NAN_GETTER(GetUnicode);
26
27
  static NAN_GETTER(GetSticky);
27
28
  static NAN_GETTER(GetLastIndex);
@@ -67,6 +68,7 @@ public:
67
68
  bool global;
68
69
  bool ignoreCase;
69
70
  bool multiline;
71
+ bool dotAll;
70
72
  bool sticky;
71
73
  size_t lastIndex;
72
74
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "re2",
3
- "version": "1.17.2",
3
+ "version": "1.17.6",
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",
@@ -11,8 +11,8 @@
11
11
  },
12
12
  "dependencies": {
13
13
  "install-artifact-from-github": "^1.3.0",
14
- "nan": "^2.15.0",
15
- "node-gyp": "^8.4.1"
14
+ "nan": "^2.16.0",
15
+ "node-gyp": "^9.0.0"
16
16
  },
17
17
  "devDependencies": {
18
18
  "heya-unit": "^0.3.0"
package/re2.js CHANGED
@@ -19,6 +19,19 @@ if (typeof Symbol != 'undefined') {
19
19
  (RE2.prototype[Symbol.split] = function (str, limit) {
20
20
  return this.split(str, limit);
21
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
+ yield result;
33
+ }
34
+ });
22
35
  }
23
36
 
24
37
  module.exports = RE2;