| 63 | { |
| 64 | public: |
| 65 | SimilarToCompiler(MemoryPool& pool, AutoPtr<RE2>& regexp, unsigned aFlags, |
| 66 | const char* aPatternStr, unsigned aPatternLen, |
| 67 | const char* escapeStr, unsigned escapeLen) |
| 68 | : re2PatternStr(pool), |
| 69 | patternStr(aPatternStr), |
| 70 | patternPos(0), |
| 71 | patternLen(aPatternLen), |
| 72 | flags(aFlags), |
| 73 | useEscape(escapeStr != nullptr) |
| 74 | { |
| 75 | if (!(flags & COMP_FLAG_LATIN) && !(flags & COMP_FLAG_WELLFORMED)) |
| 76 | { |
| 77 | if (!Jrd::UnicodeUtil::utf8WellFormed(patternLen, reinterpret_cast<const UCHAR*>(patternStr), nullptr)) |
| 78 | status_exception::raise(Arg::Gds(isc_malformed_string)); |
| 79 | } |
| 80 | |
| 81 | if (escapeStr) |
| 82 | { |
| 83 | if (!(flags & COMP_FLAG_LATIN) && !(flags & COMP_FLAG_WELLFORMED)) |
| 84 | { |
| 85 | if (!Jrd::UnicodeUtil::utf8WellFormed(escapeLen, reinterpret_cast<const UCHAR*>(escapeStr), nullptr)) |
| 86 | status_exception::raise(Arg::Gds(isc_malformed_string)); |
| 87 | } |
| 88 | |
| 89 | unsigned escapePos = 0; |
| 90 | escapeChar = getChar(flags & COMP_FLAG_LATIN, escapeStr, escapeLen, escapePos); |
| 91 | |
| 92 | if (escapePos != escapeLen) |
| 93 | status_exception::raise(Arg::Gds(isc_escape_invalid)); |
| 94 | } |
| 95 | |
| 96 | if (flags & COMP_FLAG_GROUP_CAPTURE) |
| 97 | re2PatternStr.append("("); |
| 98 | |
| 99 | int parseFlags; |
| 100 | parseExpr(&parseFlags); |
| 101 | |
| 102 | if (flags & COMP_FLAG_GROUP_CAPTURE) |
| 103 | re2PatternStr.append(")"); |
| 104 | |
| 105 | // Check for proper termination. |
| 106 | if (patternPos < patternLen) |
| 107 | status_exception::raise(Arg::Gds(isc_invalid_similar_pattern)); |
| 108 | |
| 109 | RE2::Options options; |
| 110 | options.set_log_errors(false); |
| 111 | options.set_dot_nl(true); |
| 112 | options.set_case_sensitive(!(flags & COMP_FLAG_CASE_INSENSITIVE)); |
| 113 | options.set_encoding(flags & COMP_FLAG_LATIN ? RE2::Options::EncodingLatin1 : RE2::Options::EncodingUTF8); |
| 114 | |
| 115 | re2::StringPiece sp((const char*) re2PatternStr.c_str(), re2PatternStr.length()); |
| 116 | regexp = FB_NEW_POOL(pool) RE2(sp, options); |
| 117 | |
| 118 | if (!regexp->ok()) |
| 119 | status_exception::raise(Arg::Gds(isc_invalid_similar_pattern)); |
| 120 | } |
| 121 | |
| 122 | bool hasPatternChar() |
nothing calls this directly
no test coverage detected