Skip to content
This repository has been archived by the owner on Dec 15, 2022. It is now read-only.

Commit

Permalink
Merge pull request #88 from alexandrudima/no-cache-for-G
Browse files Browse the repository at this point in the history
Fixes #87: Do not cache search results if regular expression contains \G
  • Loading branch information
Max Brunsfeld authored Sep 19, 2018
2 parents ca78059 + ac865da commit bfb1753
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 0 deletions.
13 changes: 13 additions & 0 deletions spec/onig-scanner-spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict'

const OnigScanner = require('..').OnigScanner
const OnigString = require('..').OnigString;

describe('OnigScanner', () => {
describe('::findNextMatchSync', () => {
Expand Down Expand Up @@ -113,6 +114,18 @@ describe('OnigScanner', () => {
})
)

describe('when a regular expression contains \\G', () =>
it('it does not get cached', () => {
let str = new OnigString('first-and-second');
let scanner = new OnigScanner(['\\G-and'])
let match = scanner.findNextMatchSync(str, 0)
expect(match).toEqual(null)

match = scanner.findNextMatchSync(str, 5)
expect(match.captureIndices).toEqual([{index: 0, start: 5, end: 9, length: 4}])
})
)

describe('::findNextMatch', () => {
let matchCallback

Expand Down
17 changes: 17 additions & 0 deletions src/onig-reg-exp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@ OnigRegExp::OnigRegExp(const string& source)
lastSearchPosition = -1;
lastSearchResult = NULL;

hasGAnchor = false;
for (size_t pos = 0, len = source.size(); pos < len; pos++) {
if (source[pos] == '\\' && pos + 1 < len) {
if (source[pos + 1] == 'G') {
hasGAnchor = true;
break;
}
pos++;
}
}

OnigErrorInfo error;
const UChar* sourceData = (const UChar*)source.data();
int status = onig_new(&regex_, sourceData, sourceData + source.length(),
Expand All @@ -28,6 +39,12 @@ OnigRegExp::~OnigRegExp() {
}

shared_ptr<OnigResult> OnigRegExp::Search(OnigString* str, int position) {
if (hasGAnchor) {
// Should not use caching, because the regular expression
// targets the current search position (\G)
return Search(str->utf8_value(), position, str->utf8_length());
}

if (lastSearchStrUniqueId == str->uniqueId() && lastSearchPosition <= position) {
if (lastSearchResult == NULL || lastSearchResult->LocationAt(0) >= position) {
return lastSearchResult;
Expand Down
1 change: 1 addition & 0 deletions src/onig-reg-exp.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class OnigRegExp {
string source_;
regex_t* regex_;

bool hasGAnchor;
int lastSearchStrUniqueId;
int lastSearchPosition;
shared_ptr<OnigResult> lastSearchResult;
Expand Down

0 comments on commit bfb1753

Please sign in to comment.