@@ -2628,32 +2628,35 @@ internal bool FuzzParseCommandBuffer(ReadOnlySpan<byte> buffer, out RespCommand
26282628 [ MethodImpl( MethodImplOptions. AggressiveInlining) ]
26292629 private RespCommand ParseCommand( bool writeErrorOnFailure, out bool commandReceived)
26302630 {
2631- var cmd = RespCommand . INVALID ;
2631+ RespCommand cmd;
26322632
26332633 // Initialize count as -1 (i.e., read head has not been advanced)
26342634 var count = - 1 ;
26352635 commandReceived = true;
26362636 endReadHead = readHead;
26372637
2638- var remainingBytes = bytesRead - readHead ;
26392638 var ptr = recvBufferPtr + readHead ;
2640- var end = ptr + remainingBytes ;
2639+ var end = recvBufferPtr + bytesRead ;
2640+ var remainingBytes = bytesRead - readHead ;
26412641
26422642 // Attempt parsing using fast parse pass for most common operations
26432643 cmd = FastParseCommand( out count, ptr , remainingBytes ) ;
26442644
2645- // See if input command is all upper-case. If not, convert and try fast parse pass again.
2646- if ( ( cmd == RespCommand . NONE ) && MakeUpperCase( ptr, remainingBytes ) )
2645+ if ( cmd == RespCommand . NONE )
26472646 {
2648- cmd = FastParseCommand( out count, ptr , remainingBytes ) ;
2649- }
2647+ // See if input command is all upper-case. If not, convert and try fast parse pass again.
2648+ if ( MakeUpperCase( ptr, remainingBytes ) )
2649+ {
2650+ cmd = FastParseCommand( out count, ptr , remainingBytes ) ;
2651+ }
26502652
2651- // If we have not found a command, continue parsing on slow path.
2652- // But first ensure we are attempting to read a RESP array header.
2653- if ( ( cmd == RespCommand . NONE ) && ( * ptr == '* ') )
2654- {
2655- cmd = ArrayParseCommand( writeErrorOnFailure , ptr , end , out count , out commandReceived ) ;
2656- if ( ! commandReceived ) return cmd;
2653+ // If we have not found a command, continue parsing on slow path.
2654+ // But first ensure we are attempting to read a RESP array header.
2655+ if ( ( cmd == RespCommand . NONE ) && ( * ptr == '* ') )
2656+ {
2657+ cmd = ArrayParseCommand( writeErrorOnFailure , ptr , end , out count , out commandReceived ) ;
2658+ if ( ! commandReceived ) return cmd;
2659+ }
26572660 }
26582661
26592662 if ( cmd != RespCommand. NONE)
@@ -2674,42 +2677,11 @@ private RespCommand ParseCommand(bool writeErrorOnFailure, out bool commandRecei
26742677
26752678 readHead = ( int ) ( ptr - recvBufferPtr ) ;
26762679 }
2677- else if ( CanRunInlineCommands( ) )
2680+ else if ( CanRunInlineCommands( ) && ( * ptr != ' * ' ) )
26782681 {
2679- // This may be an inline command string. We'll parse it and convert a part to a RESP command string,
2680- // which is then parsed to get the command.
2681- SpanByteAndMemory spam = new ( null ) ;
2682- if ( ! ParseInlineCommandline( ref spam, writeErrorOnFailure , ref ptr , out commandReceived , out var nbytes, out var result) )
2683- {
2684- if ( commandReceived)
2685- endReadHead = readHead;
2682+ cmd = TryParseInlineCommandline( writeErrorOnFailure, ref ptr , out commandReceived , ref count ) ;
2683+ if ( ! commandReceived )
26862684 return RespCommand. INVALID;
2687- }
2688-
2689- // If we're here, commandReceived is true, and we've reached end-of-line.
2690- endReadHead = readHead;
2691-
2692- fixed ( byte * nptr = spam. Memory. Memory. Span)
2693- {
2694- var nend = nptr + nbytes;
2695-
2696- cmd = FastParseCommand( out count, nptr , nbytes ) ;
2697-
2698- // Since we're operating on a temporary buffer and not the actual receive buffer,
2699- // we don't care for its commandReceived, and we reset readHead afterwards.
2700- if ( cmd == RespCommand . NONE )
2701- {
2702- cmd = ArrayParseCommand( writeErrorOnFailure, nptr , nend , out count , out _ ,
2703- result [ 0 ] . ReadOnlySpan , result . Length > 1 ? result [ 1 ] : default ) ;
2704- }
2705- readHead = endReadHead ;
2706-
2707- if ( cmd == RespCommand . INVALID )
2708- logger? . LogWarning ( "Received malformed input message. Line is skipped." ) ;
2709- }
2710-
2711- // Note that arguments are initialized from the actual command string, and not our made-up RESP string.
2712- parseState . InitializeWithArguments ( result [ ( result . Length - count ) ..] ) ;
27132685 }
27142686 else
27152687 {
@@ -2725,6 +2697,47 @@ private RespCommand ParseCommand(bool writeErrorOnFailure, out bool commandRecei
27252697 return cmd;
27262698 }
27272699
2700+ private RespCommand TryParseInlineCommandline( bool writeErrorOnFailure, ref byte * ptr ,
2701+ out bool commandReceived, ref int count )
2702+ {
2703+ // This may be an inline command string. We'll parse it and convert a part to a RESP command string,
2704+ // which is then parsed to get the command.
2705+ SpanByteAndMemory spam = new ( null ) ;
2706+ if ( ! ParseInlineCommandline( ref spam, writeErrorOnFailure , ref ptr , out commandReceived , out var nbytes, out var result) )
2707+ {
2708+ if ( commandReceived)
2709+ endReadHead = readHead;
2710+ return RespCommand. INVALID;
2711+ }
2712+
2713+ // If we're here, commandReceived is true, and we've reached end-of-line.
2714+ endReadHead = readHead;
2715+
2716+ fixed ( byte * nptr = spam. Memory. Memory. Span)
2717+ {
2718+ var nend = nptr + nbytes;
2719+
2720+ var cmd = FastParseCommand( out count, nptr , nbytes ) ;
2721+
2722+ // Since we're operating on a temporary buffer and not the actual receive buffer,
2723+ // we don't care for its commandReceived, and we reset readHead afterwards.
2724+ if ( cmd == RespCommand . NONE )
2725+ {
2726+ cmd = ArrayParseCommand( writeErrorOnFailure, nptr , nend , out count , out _ ,
2727+ result [ 0 ] . ReadOnlySpan , result . Length > 1 ? result [ 1 ] : default ) ;
2728+ }
2729+ readHead = endReadHead ;
2730+
2731+ if ( cmd == RespCommand . INVALID )
2732+ logger? . LogWarning ( "Received malformed input message. Line is skipped." ) ;
2733+ else
2734+ // Note that arguments are initialized from the actual command string, and not our made-up RESP string.
2735+ parseState. InitializeWithArguments ( result [ ( result . Length - count ) ..] ) ;
2736+
2737+ return cmd;
2738+ }
2739+ }
2740+
27282741 private bool ParseInlineCommandline( ref SpanByteAndMemory spam ,
27292742 bool writeErrorOnFailure , ref byte * ptr , out bool commandReceived ,
27302743 out int nbytes , out ArgSlice [ ] result )
0 commit comments