ICU-3337 better detect incorrect usage of Regex APIs.

X-SVN-Rev: 16595
This commit is contained in:
Andy Heninger 2004-10-22 16:32:12 +00:00
parent 65f51b930c
commit 9f286086d1
4 changed files with 85 additions and 5 deletions

View File

@ -721,6 +721,11 @@ RegexMatcher &RegexMatcher::reset(const UnicodeString &input) {
return *this;
}
RegexMatcher &RegexMatcher::reset(const UChar *) {
fDeferredStatus = U_INTERNAL_PROGRAM_ERROR;
return *this;
}
RegexMatcher &RegexMatcher::reset(int32_t position, UErrorCode &status) {
if (U_FAILURE(status)) {

View File

@ -324,6 +324,15 @@ RegexMatcher *RegexPattern::matcher(const UnicodeString &input,
return retMatcher;
};
RegexMatcher *RegexPattern::matcher(const UChar *input,
UErrorCode &status) const
{
RegexMatcher *retMatcher = NULL;
if (U_SUCCESS(status)) {
status = U_UNSUPPORTED_ERROR;
}
return retMatcher;
}
//---------------------------------------------------------------------

View File

@ -247,6 +247,22 @@ public:
virtual RegexMatcher *matcher(const UnicodeString &input,
UErrorCode &status) const;
private:
/**
* Cause a compilation error if an application accidently attempts to
* create a matcher with a (UChar *) string as input rather than
* a UnicodeString. Avoids a dangling reference to a temporary string.
* <p>
* To efficiently work with UChar *strings, wrap the data in a UnicodeString
* using one of the aliasing constructors, such as
* <code>UnicodeString(UBool isTerminated, const UChar *text, int32_t textLength);</code>
*
* @internal
*/
virtual RegexMatcher *matcher(const UChar *input,
UErrorCode &status) const;
public:
/**
* Creates a RegexMatcher that will match against this pattern. The
@ -446,6 +462,22 @@ public:
RegexMatcher(const UnicodeString &regexp, const UnicodeString &input,
uint32_t flags, UErrorCode &status);
private:
/**
* Cause a compilation error if an application accidently attempts to
* create a matcher with a (UChar *) string as input rather than
* a UnicodeString. Avoids a dangling reference to a temporary string.
* <p>
* To efficiently work with UChar *strings, wrap the data in a UnicodeString
* using one of the aliasing constructors, such as
* <code>UnicodeString(UBool isTerminated, const UChar *text, int32_t textLength);</code>
*
* @internal
*/
RegexMatcher(const UnicodeString &regexp, const UChar *input,
uint32_t flags, UErrorCode &status);
public:
/**
* Destructor.
@ -654,6 +686,20 @@ public:
*/
virtual RegexMatcher &reset(const UnicodeString &input);
private:
/**
* Cause a compilation error if an application accidently attempts to
* reset a matcher with a (UChar *) string as input rather than
* a UnicodeString. Avoids a dangling reference to a temporary string.
* <p>
* To efficiently work with UChar *strings, wrap the data in a UnicodeString
* using one of the aliasing constructors, such as
* <code>UnicodeString(UBool isTerminated, const UChar *text, int32_t textLength);</code>
*
* @internal
*/
virtual RegexMatcher &reset(const UChar *input);
public:
/**
* Returns the input string being matched. The returned string is not a copy,
@ -821,7 +867,6 @@ private:
friend class RegexPattern;
friend class RegexCImpl;
//
// MatchAt This is the internal interface to the match engine itself.
// Match status comes back in matcher member variables.

View File

@ -940,6 +940,26 @@ void RegexTest::API_Match() {
delete p;
}
//
// Compilation error on reset with UChar *
// These were a hazard that people were stumbling over with runtime errors.
// Changed them to compiler errors by adding private methods that more closely
// matched the incorrect use of the functions.
//
#if 0
{
UErrorCode status = U_ZERO_ERROR;
UChar ucharString[20];
RegexMatcher m(".", 0, status);
m.reset(ucharString); // should not compile.
RegexPattern *p = RegexPattern::compile(".", 0, status);
RegexMatcher *m2 = p->matcher(ucharString, status); // should not compile.
RegexMatcher m3(".", ucharString, 0, status); // Should not compile
}
#endif
}
@ -1362,7 +1382,8 @@ void RegexTest::API_Pattern() {
REGEX_CHECK_STATUS;
REGEX_ASSERT(pat1->getDynamicClassID() == RegexPattern::getStaticClassID());
REGEX_ASSERT(pat1->getDynamicClassID() != NULL);
RegexMatcher *m = pat1->matcher("Hello, World", status);
UnicodeString Hello("Hello, world.");
RegexMatcher *m = pat1->matcher(Hello, status);
REGEX_ASSERT(pat1->getDynamicClassID() != m->getDynamicClassID());
REGEX_ASSERT(m->getDynamicClassID() == RegexMatcher::getStaticClassID());
REGEX_ASSERT(m->getDynamicClassID() != NULL);
@ -1766,7 +1787,7 @@ void RegexTest::PerlTests() {
// Coming out, capture group 2 is the pattern, capture group 3 is the flags.
//
RegexPattern *flagPat = RegexPattern::compile("('?)(.*)\\1(.*)", 0, pe, status);
RegexMatcher* flagMat = flagPat->matcher("", status);
RegexMatcher* flagMat = flagPat->matcher(status);
//
// The Perl tests reference several perl-isms, which are evaluated/substituted
@ -1783,11 +1804,11 @@ void RegexTest::PerlTests() {
// regexp for $-[0], $+[2], etc.
RegexPattern *groupsPat = RegexPattern::compile("\\$([+\\-])\\[(\\d+)\\]", 0, pe, status);
RegexMatcher *groupsMat = groupsPat->matcher("", status);
RegexMatcher *groupsMat = groupsPat->matcher(status);
// regexp for $0, $1, $2, etc.
RegexPattern *cgPat = RegexPattern::compile("\\$(\\d+)", 0, pe, status);
RegexMatcher *cgMat = cgPat->matcher("", status);
RegexMatcher *cgMat = cgPat->matcher(status);
//