ICU-4521 Fix dangling pointer if a UnicodeString passed to RegexPattern::compile

doesn't persist for the life of the RegexPattern; ensure RegexPattern == still works.

X-SVN-Rev: 27541
This commit is contained in:
Peter Edberg 2010-02-11 06:57:20 +00:00
parent 1457da183c
commit a6c3b1905e
3 changed files with 43 additions and 18 deletions

View file

@ -103,8 +103,9 @@ void RegexCompile::compile(
UParseError &pp, // Error position info
UErrorCode &e) // Error Code
{
fRXPat->fPatternString = new UnicodeString(pat);
UText patternText = UTEXT_INITIALIZER;
utext_openConstUnicodeString(&patternText, &pat, &e);
utext_openConstUnicodeString(&patternText, fRXPat->fPatternString, &e);
if (U_SUCCESS(e)) {
compile(&patternText, pp, e);

View file

@ -68,7 +68,18 @@ RegexPattern &RegexPattern::operator = (const RegexPattern &other) {
init();
// Copy simple fields
fPattern = utext_clone(fPattern, other.fPattern, FALSE, TRUE, &fDeferredStatus);
if ( other.fPatternString == NULL ) {
fPatternString = NULL;
fPattern = utext_clone(fPattern, other.fPattern, FALSE, TRUE, &fDeferredStatus);
} else {
fPatternString = new UnicodeString(*(other.fPatternString));
UErrorCode status = U_ZERO_ERROR;
fPattern = utext_openConstUnicodeString(NULL, fPatternString, &status);
if (U_FAILURE(status)) {
fDeferredStatus = U_MEMORY_ALLOCATION_ERROR;
return *this;
}
}
fFlags = other.fFlags;
fLiteralText = other.fLiteralText;
fDeferredStatus = other.fDeferredStatus;
@ -149,6 +160,7 @@ void RegexPattern::init() {
fNeedsAltInput = FALSE;
fPattern = NULL; // will be set later
fPatternString = NULL; // may be set later
fCompiledPat = new UVector32(fDeferredStatus);
fGroupMap = new UVector32(fDeferredStatus);
fSets = new UVector(fDeferredStatus);
@ -196,6 +208,11 @@ void RegexPattern::zap() {
fInitialChars8 = NULL;
if (fPattern != NULL) {
utext_close(fPattern);
fPattern = NULL;
}
if (fPatternString != NULL) {
delete fPatternString;
fPatternString = NULL;
}
}
@ -230,22 +247,20 @@ RegexPattern *RegexPattern::clone() const {
//
//--------------------------------------------------------------------------
UBool RegexPattern::operator ==(const RegexPattern &other) const {
if (this->fPattern == NULL) {
if (other.fPattern == NULL) {
return this->fFlags == other.fFlags && this->fDeferredStatus == other.fDeferredStatus;
} else {
return FALSE;
}
} else {
if (other.fPattern == NULL) {
return FALSE;
} else {
if (this->fFlags == other.fFlags && this->fDeferredStatus == other.fDeferredStatus) {
if (this->fPatternString != NULL && other.fPatternString != NULL) {
return *(this->fPatternString) == *(other.fPatternString);
} else if (this->fPattern == NULL) {
if (other.fPattern == NULL) {
return TRUE;
}
} else if (other.fPattern != NULL) {
UTEXT_SETNATIVEINDEX(this->fPattern, 0);
UTEXT_SETNATIVEINDEX(other.fPattern, 0);
return this->fFlags == other.fFlags && this->fDeferredStatus == other.fDeferredStatus &&
utext_equals(this->fPattern, other.fPattern);
return utext_equals(this->fPattern, other.fPattern);
}
}
return FALSE;
}
//---------------------------------------------------------------------
@ -538,7 +553,9 @@ UBool U_EXPORT2 RegexPattern::matches(UText *regex,
//
//---------------------------------------------------------------------
UnicodeString RegexPattern::pattern() const {
if (fPattern == NULL) {
if (fPatternString != NULL) {
return *fPatternString;
} else if (fPattern == NULL) {
return UnicodeString();
} else {
UErrorCode status = U_ZERO_ERROR;

View file

@ -205,7 +205,9 @@ public:
* from a pattern string rather than separately compiling the pattern and
* then creating a RegexMatcher object from the pattern.</p>
*
* @param regex The regular expression to be compiled.
* @param regex The regular expression to be compiled. Note, the text referred
* to by this UText must not be deleted during the lifetime of the
* RegexPattern object or any RegexMatcher object created from it.
* @param pe Receives the position (line and column nubers) of any error
* within the regular expression.)
* @param status A reference to a UErrorCode to receive any errors.
@ -262,7 +264,9 @@ public:
* from a pattern string instead of than separately compiling the pattern and
* then creating a RegexMatcher object from the pattern.</p>
*
* @param regex The regular expression to be compiled.
* @param regex The regular expression to be compiled. Note, the text referred
* to by this UText must not be deleted during the lifetime of the
* RegexPattern object or any RegexMatcher object created from it.
* @param flags The match mode flags to be used.
* @param pe Receives the position (line and column numbers) of any error
* within the regular expression.)
@ -319,7 +323,9 @@ public:
* from a pattern string instead of than separately compiling the pattern and
* then creating a RegexMatcher object from the pattern.</p>
*
* @param regex The regular expression to be compiled.
* @param regex The regular expression to be compiled. Note, the text referred
* to by this UText must not be deleted during the lifetime of the
* RegexPattern object or any RegexMatcher object created from it.
* @param flags The match mode flags to be used.
* @param status A reference to a UErrorCode to receive any errors.
* @return A regexPattern object for the compiled pattern.
@ -566,6 +572,7 @@ private:
// Implementation Data
//
UText *fPattern; // The original pattern string.
UnicodeString *fPatternString; // The original pattern UncodeString if relevant
uint32_t fFlags; // The flags used when compiling the pattern.
//
UVector32 *fCompiledPat; // The compiled pattern p-code.