diff options
-rw-r--r-- | db/jsobj.cpp | 2 | ||||
-rw-r--r-- | db/json.cpp | 32 | ||||
-rw-r--r-- | dbtests/jsobjtests.cpp | 24 |
3 files changed, 44 insertions, 14 deletions
diff --git a/db/jsobj.cpp b/db/jsobj.cpp index f9c51113338..4b0b90fba75 100644 --- a/db/jsobj.cpp +++ b/db/jsobj.cpp @@ -265,7 +265,7 @@ string BSONElement::jsonString( JsonStringFormat format, bool includeFieldNames s << "{ \"$regex\" : \""; else s << "/"; - s << regex(); + s << escape( regex() ); if ( format == Strict ) s << "\", \"$options\" : \""; else diff --git a/db/json.cpp b/db/json.cpp index f2ff482f717..e1c907ca50d 100644 --- a/db/json.cpp +++ b/db/json.cpp @@ -344,7 +344,7 @@ struct dateEnd { struct regexValue { regexValue( ObjectBuilder &_b ) : b( _b ) {} void operator() ( const char *start, const char *end ) const { - b.regex = string( start, end ); + b.regex = b.popString(); } ObjectBuilder &b; }; @@ -352,7 +352,7 @@ struct regexValue { struct regexOptions { regexOptions( ObjectBuilder &_b ) : b( _b ) {} void operator() ( const char *start, const char *end ) const { - b.regexOptions = string( start, end ); + b.regexOptions = b.popString(); } ObjectBuilder &b; }; @@ -445,21 +445,27 @@ public: dateS = ch_p( '{' ) >> "\"$date\"" >> ':' >> uint_parser< unsigned long long >()[ dateValue( self.b ) ] >> '}'; dateT = str_p( "Date" ) >> '(' >> uint_parser< unsigned long long >()[ dateValue( self.b ) ] >> ')'; - // FIXME: Not unescaping regexp fields right now, since in the JS - // and TenGen formats there are no bracketing quotes and 'str' will - // not match. - // Obviously this should fixed up soon. regex = regexS | regexT; - regexS = ch_p( '{' ) >> "\"$regex\"" >> ':' >> regexValueS >> ',' >> "\"$options\"" >> ':' >> regexOptionsS >> '}'; - regexValueS = lexeme_d[ '"' >> ( *( ~ch_p( '"' ) ) )[ regexValue( self.b ) ] >> '"' ]; - regexOptionsS = lexeme_d[ '"' >> ( *( ~ch_p( '"' ) ) )[ regexOptions( self.b ) ] >> '"' ]; - regexT = lexeme_d[ ch_p( '/' ) >> - ( *( ~ch_p( '/' ) ) )[ regexValue( self.b ) ] >> '/' >> - ( *( ~ch_p( ' ' ) ) )[ regexOptions( self.b ) ] ]; // assuming a space terminal is really gross, and tempoary. + regexS = ch_p( '{' ) >> "\"$regex\"" >> ':' >> str[ regexValue( self.b ) ] >> ',' >> "\"$options\"" >> ':' >> str[ regexOptions( self.b ) ] >> '}'; + // FIXME Obviously it would be nice to unify this with str. + regexT = lexeme_d[ ch_p( '/' )[ chClear( self.b ) ] >> + *( ( ch_p( "\\" ) >> + ( ch_p( "\"" )[ chE( self.b ) ] | + ch_p( "\\" )[ chE( self.b ) ] | + ch_p( "/" )[ chE( self.b ) ] | + ch_p( "b" )[ chE( self.b ) ] | + ch_p( "f" )[ chE( self.b ) ] | + ch_p( "n" )[ chE( self.b ) ] | + ch_p( "r" )[ chE( self.b ) ] | + ch_p( "t" )[ chE( self.b ) ] | + ( ch_p( "u" ) >> ( repeat_p( 4 )[ xdigit_p ][ chU( self.b ) ] ) ) ) ) | + ch_p( '\x7f' )[ ch( self.b ) ] | + ( ~cntrl_p & ~ch_p( '/' ) & ( ~ch_p( '\\' ) )[ ch( self.b ) ] ) ) >> str_p( "/" )[ regexValue( self.b ) ] + >> ( *( alpha_p[ ch( self.b ) ] ) )[ regexOptions( self.b ) ] ]; } rule< ScannerT > object, members, pair, array, elements, value, str, number, dbref, dbrefS, dbrefT, oid, oidS, oidT, bindata, date, dateS, dateT, - regex, regexS, regexT, quotedOid, regexValueS, regexOptionsS; + regex, regexS, regexT, quotedOid; const rule< ScannerT > &start() const { return object; } }; ObjectBuilder &b; diff --git a/dbtests/jsobjtests.cpp b/dbtests/jsobjtests.cpp index aa6681836ef..b7d48d75f8e 100644 --- a/dbtests/jsobjtests.cpp +++ b/dbtests/jsobjtests.cpp @@ -742,6 +742,28 @@ namespace FromJsonTests { } }; + class RegexEscape : public Base { + virtual BSONObj bson() const { + BSONObjBuilder b; + b.appendRegex( "a", "\t", "c" ); + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ \"a\" : { \"$regex\" : \"\\t\", \"$options\" : \"c\" } }"; + } + }; + + class RegexWithQuotes : public Base { + virtual BSONObj bson() const { + BSONObjBuilder b; + b.appendRegex( "a", "\"", "" ); + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ \"a\" : /\"/ }"; + } + }; + } // namespace FromJsonTests class All : public UnitTest::Suite { @@ -802,6 +824,8 @@ public: add< FromJsonTests::BinDataPaddedDouble >(); add< FromJsonTests::Date >(); add< FromJsonTests::Regex >(); + add< FromJsonTests::RegexEscape >(); + add< FromJsonTests::RegexWithQuotes >(); } }; |