@@ -636,14 +636,14 @@ fn parse_primary_node(pair: Pair<Rule>) -> Result<ExpressionNode, RevsetParseErr
636636 assert_eq ! ( lhs. as_rule( ) , Rule :: strict_identifier) ;
637637 assert_eq ! ( op. as_rule( ) , Rule :: pattern_kind_op) ;
638638 let kind = lhs. as_str ( ) ;
639- let value = parse_as_string_literal ( rhs) ;
639+ let value = parse_as_string_literal ( rhs) ? ;
640640 ExpressionKind :: StringPattern { kind, value }
641641 }
642642 // Identifier without "@" may be substituted by aliases. Primary expression including "@"
643643 // is considered an indecomposable unit, and no alias substitution would be made.
644644 Rule :: identifier if pairs. peek ( ) . is_none ( ) => ExpressionKind :: Identifier ( first. as_str ( ) ) ,
645645 Rule :: identifier | Rule :: string_literal | Rule :: raw_string_literal => {
646- let name = parse_as_string_literal ( first) ;
646+ let name = parse_as_string_literal ( first) ? ;
647647 match pairs. next ( ) {
648648 None => ExpressionKind :: String ( name) ,
649649 Some ( op) => {
@@ -654,7 +654,7 @@ fn parse_primary_node(pair: Pair<Rule>) -> Result<ExpressionNode, RevsetParseErr
654654 // infix "<name>@<remote>"
655655 Some ( second) => {
656656 let name: RefNameBuf = name. into ( ) ;
657- let remote: RemoteNameBuf = parse_as_string_literal ( second) . into ( ) ;
657+ let remote: RemoteNameBuf = parse_as_string_literal ( second) ? . into ( ) ;
658658 ExpressionKind :: RemoteSymbol ( RemoteRefSymbolBuf { name, remote } )
659659 }
660660 }
@@ -669,14 +669,17 @@ fn parse_primary_node(pair: Pair<Rule>) -> Result<ExpressionNode, RevsetParseErr
669669}
670670
671671/// Parses part of compound symbol to string.
672- fn parse_as_string_literal ( pair : Pair < Rule > ) -> String {
672+ fn parse_as_string_literal ( pair : Pair < Rule > ) -> Result < String , RevsetParseError > {
673+ let span = pair. as_span ( ) ;
673674 match pair. as_rule ( ) {
674- Rule :: identifier => pair. as_str ( ) . to_owned ( ) ,
675- Rule :: string_literal => STRING_LITERAL_PARSER . parse ( pair. into_inner ( ) ) ,
675+ Rule :: identifier => Ok ( pair. as_str ( ) . to_owned ( ) ) ,
676+ Rule :: string_literal => STRING_LITERAL_PARSER
677+ . parse ( pair. into_inner ( ) )
678+ . map_err ( |err| RevsetParseError :: expression ( err. to_string ( ) , span) ) ,
676679 Rule :: raw_string_literal => {
677680 let [ content] = pair. into_inner ( ) . collect_array ( ) . unwrap ( ) ;
678681 assert_eq ! ( content. as_rule( ) , Rule :: raw_string_content) ;
679- content. as_str ( ) . to_owned ( )
682+ Ok ( content. as_str ( ) . to_owned ( ) )
680683 }
681684 _ => {
682685 panic ! ( "unexpected string literal rule: {:?}" , pair. as_str( ) ) ;
@@ -697,7 +700,7 @@ pub fn parse_symbol(text: &str) -> Result<String, RevsetParseError> {
697700 let mut pairs = RevsetParser :: parse ( Rule :: symbol_name, text) ?;
698701 let first = pairs. next ( ) . unwrap ( ) ;
699702 let span = first. as_span ( ) ;
700- let name = parse_as_string_literal ( first) ;
703+ let name = parse_as_string_literal ( first) ? ;
701704 if name. is_empty ( ) {
702705 Err ( RevsetParseError :: expression (
703706 "Expected non-empty string" ,
@@ -1284,9 +1287,15 @@ mod tests {
12841287 Ok ( ExpressionKind :: String ( "aeiou" . to_owned( ) ) )
12851288 ) ;
12861289 assert_eq ! (
1287- parse_into_kind( r#""\xe0\xe8\xec\xf0\xf9 ""# ) ,
1290+ parse_into_kind( r#""\xc3\xa0\xc3\xa8\xc3\xac\xc3\xb0\xc3\xb9 ""# ) ,
12881291 Ok ( ExpressionKind :: String ( "àèìðù" . to_owned( ) ) )
12891292 ) ;
1293+ assert_eq ! (
1294+ parse_into_kind( r#""\xc3""# ) ,
1295+ Err ( RevsetParseErrorKind :: Expression (
1296+ "Invalid UTF-8 sequence" . to_owned( )
1297+ ) )
1298+ ) ;
12901299 assert_eq ! (
12911300 parse_into_kind( r#""\x""# ) ,
12921301 Err ( RevsetParseErrorKind :: SyntaxError )
0 commit comments