Fix CompileRegex not actually setting a valid error code. (#775)
Fix CompileRegex not actually setting a valid error code.
This commit is contained in:
parent
e2767a3c80
commit
d430bd2f5c
@ -38,6 +38,7 @@
|
||||
RegEx::RegEx()
|
||||
{
|
||||
mErrorOffset = 0;
|
||||
mErrorCode = 0;
|
||||
mError = NULL;
|
||||
re = NULL;
|
||||
mFree = true;
|
||||
@ -48,6 +49,7 @@ RegEx::RegEx()
|
||||
void RegEx::Clear ()
|
||||
{
|
||||
mErrorOffset = 0;
|
||||
mErrorCode = 0;
|
||||
mError = NULL;
|
||||
if (re)
|
||||
pcre_free(re);
|
||||
@ -80,7 +82,7 @@ int RegEx::Compile(const char *pattern, int iFlags)
|
||||
if (!mFree)
|
||||
Clear();
|
||||
|
||||
re = pcre_compile(pattern, iFlags, &mError, &mErrorOffset, NULL);
|
||||
re = pcre_compile2(pattern, iFlags, &mErrorCode, &mError, &mErrorOffset, NULL);
|
||||
|
||||
if (re == NULL)
|
||||
{
|
||||
@ -115,7 +117,7 @@ int RegEx::Match(const char *str, unsigned int offset)
|
||||
{
|
||||
return 0;
|
||||
} else {
|
||||
mErrorOffset = rc;
|
||||
mErrorCode = rc;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -158,7 +160,7 @@ int RegEx::MatchAll(const char *str)
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
mErrorOffset = rc;
|
||||
mErrorCode = rc;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -172,6 +174,7 @@ void RegEx::ClearMatch()
|
||||
{
|
||||
// Clears match results
|
||||
mErrorOffset = 0;
|
||||
mErrorCode = 0;
|
||||
mError = NULL;
|
||||
if (subject)
|
||||
delete [] subject;
|
||||
|
@ -57,6 +57,7 @@ public:
|
||||
bool GetSubstring(int s, char buffer[], int max, int match);
|
||||
public:
|
||||
int mErrorOffset;
|
||||
int mErrorCode;
|
||||
const char *mError;
|
||||
int mMatchCount;
|
||||
RegexMatch mMatches[MAX_MATCHES];
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "extension.h"
|
||||
#include <sh_string.h>
|
||||
#include "pcre.h"
|
||||
#include "posix_map.h"
|
||||
#include "CRegEx.h"
|
||||
using namespace SourceHook;
|
||||
|
||||
@ -82,10 +83,11 @@ static cell_t CompileRegex(IPluginContext *pCtx, const cell_t *params)
|
||||
|
||||
if (x->Compile(regex, params[2]) == 0)
|
||||
{
|
||||
cell_t *eOff;
|
||||
pCtx->LocalToPhysAddr(params[5], &eOff);
|
||||
cell_t *eError;
|
||||
pCtx->LocalToPhysAddr(params[5], &eError);
|
||||
const char *err = x->mError;
|
||||
*eOff = x->mErrorOffset;
|
||||
// Convert error code to posix error code but use pcre's error string since it is more detailed.
|
||||
*eError = pcre_posix_compile_error_map[x->mErrorCode];
|
||||
pCtx->StringToLocal(params[3], params[4], err ? err:"unknown");
|
||||
delete x;
|
||||
return 0;
|
||||
@ -146,7 +148,7 @@ static cell_t MatchRegex(IPluginContext *pCtx, const cell_t *params)
|
||||
/* there was a match error. move on. */
|
||||
cell_t *res;
|
||||
pCtx->LocalToPhysAddr(params[3], &res);
|
||||
*res = x->mErrorOffset;
|
||||
*res = x->mErrorCode;
|
||||
/* only clear the match results, since the regex object
|
||||
may still be referenced later */
|
||||
x->ClearMatch();
|
||||
@ -199,7 +201,7 @@ static cell_t MatchRegexAll(IPluginContext *pCtx, const cell_t *params)
|
||||
/* there was a match error. move on. */
|
||||
cell_t *res;
|
||||
pCtx->LocalToPhysAddr(params[3], &res);
|
||||
*res = x->mErrorOffset;
|
||||
*res = x->mErrorCode;
|
||||
/* only clear the match results, since the regex object
|
||||
may still be referenced later */
|
||||
x->ClearMatch();
|
||||
|
136
extensions/regex/posix_map.h
Normal file
136
extensions/regex/posix_map.h
Normal file
@ -0,0 +1,136 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
Maps pcre_compile2 error codes to posix error codes.
|
||||
From pcreposix.c and pcreposix.h
|
||||
*/
|
||||
|
||||
// posix error codes
|
||||
enum {
|
||||
REG_ASSERT = 1, /* internal error ? */
|
||||
REG_BADBR, /* invalid repeat counts in {} */
|
||||
REG_BADPAT, /* pattern error */
|
||||
REG_BADRPT, /* ? * + invalid */
|
||||
REG_EBRACE, /* unbalanced {} */
|
||||
REG_EBRACK, /* unbalanced [] */
|
||||
REG_ECOLLATE, /* collation error - not relevant */
|
||||
REG_ECTYPE, /* bad class */
|
||||
REG_EESCAPE, /* bad escape sequence */
|
||||
REG_EMPTY, /* empty expression */
|
||||
REG_EPAREN, /* unbalanced () */
|
||||
REG_ERANGE, /* bad range inside [] */
|
||||
REG_ESIZE, /* expression too big */
|
||||
REG_ESPACE, /* failed to get memory */
|
||||
REG_ESUBREG, /* bad back reference */
|
||||
REG_INVARG, /* bad argument */
|
||||
|
||||
// This isnt used below since it is not a compile error. So we remove it as to not conflict.
|
||||
//REG_NOMATCH /* match failed */
|
||||
};
|
||||
|
||||
// pcre compile error -> posix compile error
|
||||
const int pcre_posix_compile_error_map[] = {
|
||||
0, /* no error */
|
||||
REG_EESCAPE, /* \ at end of pattern */
|
||||
REG_EESCAPE, /* \c at end of pattern */
|
||||
REG_EESCAPE, /* unrecognized character follows \ */
|
||||
REG_BADBR, /* numbers out of order in {} quantifier */
|
||||
/* 5 */
|
||||
REG_BADBR, /* number too big in {} quantifier */
|
||||
REG_EBRACK, /* missing terminating ] for character class */
|
||||
REG_ECTYPE, /* invalid escape sequence in character class */
|
||||
REG_ERANGE, /* range out of order in character class */
|
||||
REG_BADRPT, /* nothing to repeat */
|
||||
/* 10 */
|
||||
REG_BADRPT, /* operand of unlimited repeat could match the empty string */
|
||||
REG_ASSERT, /* internal error: unexpected repeat */
|
||||
REG_BADPAT, /* unrecognized character after (? */
|
||||
REG_BADPAT, /* POSIX named classes are supported only within a class */
|
||||
REG_EPAREN, /* missing ) */
|
||||
/* 15 */
|
||||
REG_ESUBREG, /* reference to non-existent subpattern */
|
||||
REG_INVARG, /* erroffset passed as NULL */
|
||||
REG_INVARG, /* unknown option bit(s) set */
|
||||
REG_EPAREN, /* missing ) after comment */
|
||||
REG_ESIZE, /* parentheses nested too deeply */
|
||||
/* 20 */
|
||||
REG_ESIZE, /* regular expression too large */
|
||||
REG_ESPACE, /* failed to get memory */
|
||||
REG_EPAREN, /* unmatched parentheses */
|
||||
REG_ASSERT, /* internal error: code overflow */
|
||||
REG_BADPAT, /* unrecognized character after (?< */
|
||||
/* 25 */
|
||||
REG_BADPAT, /* lookbehind assertion is not fixed length */
|
||||
REG_BADPAT, /* malformed number or name after (?( */
|
||||
REG_BADPAT, /* conditional group contains more than two branches */
|
||||
REG_BADPAT, /* assertion expected after (?( */
|
||||
REG_BADPAT, /* (?R or (?[+-]digits must be followed by ) */
|
||||
/* 30 */
|
||||
REG_ECTYPE, /* unknown POSIX class name */
|
||||
REG_BADPAT, /* POSIX collating elements are not supported */
|
||||
REG_INVARG, /* this version of PCRE is not compiled with PCRE_UTF8 support */
|
||||
REG_BADPAT, /* spare error */
|
||||
REG_BADPAT, /* character value in \x{} or \o{} is too large */
|
||||
/* 35 */
|
||||
REG_BADPAT, /* invalid condition (?(0) */
|
||||
REG_BADPAT, /* \C not allowed in lookbehind assertion */
|
||||
REG_EESCAPE, /* PCRE does not support \L, \l, \N, \U, or \u */
|
||||
REG_BADPAT, /* number after (?C is > 255 */
|
||||
REG_BADPAT, /* closing ) for (?C expected */
|
||||
/* 40 */
|
||||
REG_BADPAT, /* recursive call could loop indefinitely */
|
||||
REG_BADPAT, /* unrecognized character after (?P */
|
||||
REG_BADPAT, /* syntax error in subpattern name (missing terminator) */
|
||||
REG_BADPAT, /* two named subpatterns have the same name */
|
||||
REG_BADPAT, /* invalid UTF-8 string */
|
||||
/* 45 */
|
||||
REG_BADPAT, /* support for \P, \p, and \X has not been compiled */
|
||||
REG_BADPAT, /* malformed \P or \p sequence */
|
||||
REG_BADPAT, /* unknown property name after \P or \p */
|
||||
REG_BADPAT, /* subpattern name is too long (maximum 32 characters) */
|
||||
REG_BADPAT, /* too many named subpatterns (maximum 10,000) */
|
||||
/* 50 */
|
||||
REG_BADPAT, /* repeated subpattern is too long */
|
||||
REG_BADPAT, /* octal value is greater than \377 (not in UTF-8 mode) */
|
||||
REG_BADPAT, /* internal error: overran compiling workspace */
|
||||
REG_BADPAT, /* internal error: previously-checked referenced subpattern not found */
|
||||
REG_BADPAT, /* DEFINE group contains more than one branch */
|
||||
/* 55 */
|
||||
REG_BADPAT, /* repeating a DEFINE group is not allowed */
|
||||
REG_INVARG, /* inconsistent NEWLINE options */
|
||||
REG_BADPAT, /* \g is not followed followed by an (optionally braced) non-zero number */
|
||||
REG_BADPAT, /* a numbered reference must not be zero */
|
||||
REG_BADPAT, /* an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT) */
|
||||
/* 60 */
|
||||
REG_BADPAT, /* (*VERB) not recognized */
|
||||
REG_BADPAT, /* number is too big */
|
||||
REG_BADPAT, /* subpattern name expected */
|
||||
REG_BADPAT, /* digit expected after (?+ */
|
||||
REG_BADPAT, /* ] is an invalid data character in JavaScript compatibility mode */
|
||||
/* 65 */
|
||||
REG_BADPAT, /* different names for subpatterns of the same number are not allowed */
|
||||
REG_BADPAT, /* (*MARK) must have an argument */
|
||||
REG_INVARG, /* this version of PCRE is not compiled with PCRE_UCP support */
|
||||
REG_BADPAT, /* \c must be followed by an ASCII character */
|
||||
REG_BADPAT, /* \k is not followed by a braced, angle-bracketed, or quoted name */
|
||||
/* 70 */
|
||||
REG_BADPAT, /* internal error: unknown opcode in find_fixedlength() */
|
||||
REG_BADPAT, /* \N is not supported in a class */
|
||||
REG_BADPAT, /* too many forward references */
|
||||
REG_BADPAT, /* disallowed UTF-8/16/32 code point (>= 0xd800 && <= 0xdfff) */
|
||||
REG_BADPAT, /* invalid UTF-16 string (should not occur) */
|
||||
/* 75 */
|
||||
REG_BADPAT, /* overlong MARK name */
|
||||
REG_BADPAT, /* character value in \u.... sequence is too large */
|
||||
REG_BADPAT, /* invalid UTF-32 string (should not occur) */
|
||||
REG_BADPAT, /* setting UTF is disabled by the application */
|
||||
REG_BADPAT, /* non-hex character in \\x{} (closing brace missing?) */
|
||||
/* 80 */
|
||||
REG_BADPAT, /* non-octal character in \o{} (closing brace missing?) */
|
||||
REG_BADPAT, /* missing opening brace after \o */
|
||||
REG_BADPAT, /* parentheses too deeply nested */
|
||||
REG_BADPAT, /* invalid range in character class */
|
||||
REG_BADPAT, /* group name must start with a non-digit */
|
||||
/* 85 */
|
||||
REG_BADPAT /* parentheses too deeply nested (stack check) */
|
||||
};
|
@ -58,6 +58,24 @@
|
||||
enum RegexError
|
||||
{
|
||||
REGEX_ERROR_NONE = 0, /* No error */
|
||||
|
||||
REGEX_ERROR_ASSERT = 1, /* internal error ? */
|
||||
REGEX_ERROR_BADBR, /* invalid repeat counts in {} */
|
||||
REGEX_ERROR_BADPAT, /* pattern error */
|
||||
REGEX_ERROR_BADRPT, /* ? * + invalid */
|
||||
REGEX_ERROR_EBRACE, /* unbalanced {} */
|
||||
REGEX_ERROR_EBRACK, /* unbalanced [] */
|
||||
REGEX_ERROR_ECOLLATE, /* collation error - not relevant */
|
||||
REGEX_ERROR_ECTYPE, /* bad class */
|
||||
REGEX_ERROR_EESCAPE, /* bad escape sequence */
|
||||
REGEX_ERROR_EMPTY, /* empty expression */
|
||||
REGEX_ERROR_EPAREN, /* unbalanced () */
|
||||
REGEX_ERROR_ERANGE, /* bad range inside [] */
|
||||
REGEX_ERROR_ESIZE, /* expression too big */
|
||||
REGEX_ERROR_ESPACE, /* failed to get memory */
|
||||
REGEX_ERROR_ESUBREG, /* bad back reference */
|
||||
REGEX_ERROR_INVARG, /* bad argument */
|
||||
|
||||
REGEX_ERROR_NOMATCH = -1, /* No match was found */
|
||||
REGEX_ERROR_NULL = -2,
|
||||
REGEX_ERROR_BADOPTION = -3,
|
||||
@ -124,7 +142,7 @@ methodmap Regex < Handle
|
||||
// @param ret Error code, if applicable.
|
||||
// @return Number of matches found or -1 on failure.
|
||||
//
|
||||
// @note Use GetSubString() and loop from 1 -> totalmatches.
|
||||
// @note Use GetSubString() and loop from 0 -> totalmatches - 1.
|
||||
public native int MatchAll(const char[] str, RegexError &ret = REGEX_ERROR_NONE);
|
||||
|
||||
// Returns a matched substring from a regex handle.
|
||||
|
Loading…
Reference in New Issue
Block a user