@@ -1396,7 +1396,20 @@ impl<'i> Parser<'i> {
13961396 let invocation = self . read_invocation ( ) ?;
13971397 Ok ( Expression :: Application ( invocation) )
13981398 } else if is_function ( content) {
1399- let target = self . read_identifier ( ) ?;
1399+ // Extract the entire text before the opening parenthesis
1400+ self . trim_whitespace ( ) ;
1401+ let content = self . source ;
1402+ let paren = content
1403+ . find ( '(' )
1404+ . unwrap ( ) ; // is_function() already checked
1405+ let text = & content[ 0 ..paren] ;
1406+
1407+ // Validate that the entire text is a valid identifier
1408+ let target = validate_identifier ( text) . ok_or (
1409+ ParsingError :: InvalidFunction ( self . offset , text. len ( ) ) ,
1410+ ) ?;
1411+
1412+ self . advance ( text. len ( ) ) ;
14001413 let parameters = self . read_parameters ( ) ?;
14011414
14021415 let function = Function { target, parameters } ;
@@ -1892,12 +1905,17 @@ impl<'i> Parser<'i> {
18921905
18931906 /// Parse a target like <procedure_name> or <https://example.com/proc>
18941907 fn read_target ( & mut self ) -> Result < Target < ' i > , ParsingError > {
1908+ let start_offset = self . offset ;
18951909 self . take_block_chars ( "an invocation" , '<' , '>' , true , |inner| {
1896- let content = inner. source ;
1910+ let content = inner
1911+ . source
1912+ . trim ( ) ;
18971913 if content. starts_with ( "https://" ) {
18981914 Ok ( Target :: Remote ( External ( content) ) )
18991915 } else {
1900- let identifier = inner. read_identifier ( ) ?;
1916+ let identifier = validate_identifier ( content) . ok_or_else ( || {
1917+ ParsingError :: InvalidInvocation ( start_offset + 1 , content. len ( ) )
1918+ } ) ?;
19011919 Ok ( Target :: Local ( identifier) )
19021920 }
19031921 } )
0 commit comments