diff --git a/ShellPkg/Application/Shell/Shell.c b/ShellPkg/Application/Shell/Shell.c index 3080a1644f..0b6362e926 100644 --- a/ShellPkg/Application/Shell/Shell.c +++ b/ShellPkg/Application/Shell/Shell.c @@ -213,7 +213,7 @@ ContainsSplit( FirstQuote = FindNextInstance (CmdLine, L"\"", TRUE); SecondQuote = NULL; - TempSpot = ShellFindFirstCharacter(CmdLine, L"|", TRUE); + TempSpot = FindFirstCharacter(CmdLine, L"|", L'^'); if (FirstQuote == NULL || TempSpot == NULL || @@ -236,7 +236,7 @@ ContainsSplit( continue; } else { FirstQuote = FindNextInstance (SecondQuote + 1, L"\"", TRUE); - TempSpot = ShellFindFirstCharacter(TempSpot + 1, L"|", TRUE); + TempSpot = FindFirstCharacter(TempSpot + 1, L"|", L'^'); continue; } } @@ -716,7 +716,6 @@ FreeResources: } ShellFreeEnvVarList (); - ShellSetRawCmdLine (NULL); if (ShellCommandGetExit()) { return ((EFI_STATUS)ShellCommandGetExitCode()); @@ -1993,7 +1992,7 @@ IsValidSplit( return (EFI_OUT_OF_RESOURCES); } TempWalker = (CHAR16*)Temp; - if (!EFI_ERROR (ShellGetNextParameter (&TempWalker, FirstParameter, StrSize(CmdLine), TRUE))) { + if (!EFI_ERROR(GetNextParameter(&TempWalker, &FirstParameter, StrSize(CmdLine), TRUE))) { if (GetOperationType(FirstParameter) == Unknown_Invalid) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter); SetLastError(SHELL_NOT_FOUND); @@ -2042,7 +2041,7 @@ VerifySplit( // // recurse to verify the next item // - TempSpot = ShellFindFirstCharacter(CmdLine, L"|", TRUE) + 1; + TempSpot = FindFirstCharacter(CmdLine, L"|", L'^') + 1; if (*TempSpot == L'a' && (*(TempSpot + 1) == L' ' || *(TempSpot + 1) == CHAR_NULL) ) { @@ -2159,7 +2158,7 @@ DoHelpUpdate( Walker = *CmdLine; while(Walker != NULL && *Walker != CHAR_NULL) { - if (!EFI_ERROR (ShellGetNextParameter (&Walker, CurrentParameter, StrSize(*CmdLine), TRUE))) { + if (!EFI_ERROR(GetNextParameter(&Walker, &CurrentParameter, StrSize(*CmdLine), TRUE))) { if (StrStr(CurrentParameter, L"-?") == CurrentParameter) { CurrentParameter[0] = L' '; CurrentParameter[1] = L' '; @@ -2590,7 +2589,6 @@ RunShellCommand( CHAR16 *FirstParameter; CHAR16 *TempWalker; SHELL_OPERATION_TYPES Type; - CHAR16 *OldCmdLine; ASSERT(CmdLine != NULL); if (StrLen(CmdLine) == 0) { @@ -2598,14 +2596,11 @@ RunShellCommand( } Status = EFI_SUCCESS; - FirstParameter = NULL; CleanOriginal = NULL; - OldCmdLine = NULL; CleanOriginal = StrnCatGrow(&CleanOriginal, NULL, CmdLine, 0); if (CleanOriginal == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Done; + return (EFI_OUT_OF_RESOURCES); } TrimSpaces(&CleanOriginal); @@ -2632,36 +2627,35 @@ RunShellCommand( // Handle case that passed in command line is just 1 or more " " characters. // if (StrLen (CleanOriginal) == 0) { - Status = EFI_SUCCESS; - goto Done; + SHELL_FREE_NON_NULL(CleanOriginal); + return (EFI_SUCCESS); } Status = ProcessCommandLineToFinal(&CleanOriginal); if (EFI_ERROR(Status)) { - goto Done; + SHELL_FREE_NON_NULL(CleanOriginal); + return (Status); } - OldCmdLine = ShellGetRawCmdLine (); - ShellSetRawCmdLine (CleanOriginal); - // // We don't do normal processing with a split command line (output from one command input to another) // if (ContainsSplit(CleanOriginal)) { Status = ProcessNewSplitCommandLine(CleanOriginal); - goto Done; - } + SHELL_FREE_NON_NULL(CleanOriginal); + return (Status); + } // // We need the first parameter information so we can determine the operation type // FirstParameter = AllocateZeroPool(StrSize(CleanOriginal)); if (FirstParameter == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Done; + SHELL_FREE_NON_NULL(CleanOriginal); + return (EFI_OUT_OF_RESOURCES); } TempWalker = CleanOriginal; - if (!EFI_ERROR (ShellGetNextParameter (&TempWalker, FirstParameter, StrSize(CleanOriginal), TRUE))) { + if (!EFI_ERROR(GetNextParameter(&TempWalker, &FirstParameter, StrSize(CleanOriginal), TRUE))) { // // Depending on the first parameter we change the behavior // @@ -2686,12 +2680,9 @@ RunShellCommand( ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter); SetLastError(SHELL_NOT_FOUND); } - -Done: - ShellSetRawCmdLine (OldCmdLine); - SHELL_FREE_NON_NULL (OldCmdLine); - SHELL_FREE_NON_NULL (CleanOriginal); - SHELL_FREE_NON_NULL (FirstParameter); + + SHELL_FREE_NON_NULL(CleanOriginal); + SHELL_FREE_NON_NULL(FirstParameter); return (Status); } @@ -3129,3 +3120,37 @@ RunScriptFile ( return (Status); } +/** + Return the pointer to the first occurrence of any character from a list of characters. + + @param[in] String the string to parse + @param[in] CharacterList the list of character to look for + @param[in] EscapeCharacter An escape character to skip + + @return the location of the first character in the string + @retval CHAR_NULL no instance of any character in CharacterList was found in String +**/ +CONST CHAR16* +EFIAPI +FindFirstCharacter( + IN CONST CHAR16 *String, + IN CONST CHAR16 *CharacterList, + IN CONST CHAR16 EscapeCharacter + ) +{ + UINT32 WalkChar; + UINT32 WalkStr; + + for (WalkStr = 0; WalkStr < StrLen(String); WalkStr++) { + if (String[WalkStr] == EscapeCharacter) { + WalkStr++; + continue; + } + for (WalkChar = 0; WalkChar < StrLen(CharacterList); WalkChar++) { + if (String[WalkStr] == CharacterList[WalkChar]) { + return (&String[WalkStr]); + } + } + } + return (String + StrLen(String)); +} diff --git a/ShellPkg/Application/Shell/Shell.h b/ShellPkg/Application/Shell/Shell.h index a34c91ad1e..29b36b003a 100644 --- a/ShellPkg/Application/Shell/Shell.h +++ b/ShellPkg/Application/Shell/Shell.h @@ -370,6 +370,24 @@ RunScriptFile ( IN EFI_SHELL_PARAMETERS_PROTOCOL *ParamProtocol ); +/** + Return the pointer to the first occurrence of any character from a list of characters. + + @param[in] String the string to parse + @param[in] CharacterList the list of character to look for + @param[in] EscapeCharacter An escape character to skip + + @return the location of the first character in the string + @retval CHAR_NULL no instance of any character in CharacterList was found in String +**/ +CONST CHAR16* +EFIAPI +FindFirstCharacter( + IN CONST CHAR16 *String, + IN CONST CHAR16 *CharacterList, + IN CONST CHAR16 EscapeCharacter + ); + /** Cleans off leading and trailing spaces and tabs. diff --git a/ShellPkg/Application/Shell/ShellParametersProtocol.c b/ShellPkg/Application/Shell/ShellParametersProtocol.c index 0785902b16..3684f9cd82 100644 --- a/ShellPkg/Application/Shell/ShellParametersProtocol.c +++ b/ShellPkg/Application/Shell/ShellParametersProtocol.c @@ -19,6 +19,162 @@ BOOLEAN AsciiRedirection = FALSE; +/** + Return the next parameter's end from a command line string. + + @param[in] String the string to parse +**/ +CONST CHAR16* +EFIAPI +FindEndOfParameter( + IN CONST CHAR16 *String + ) +{ + CONST CHAR16 *First; + CONST CHAR16 *CloseQuote; + + First = FindFirstCharacter(String, L" \"", L'^'); + + // + // nothing, all one parameter remaining + // + if (*First == CHAR_NULL) { + return (First); + } + + // + // If space before a quote (or neither found, i.e. both CHAR_NULL), + // then that's the end. + // + if (*First == L' ') { + return (First); + } + + CloseQuote = FindFirstCharacter (First+1, L"\"", L'^'); + + // + // We did not find a terminator... + // + if (*CloseQuote == CHAR_NULL) { + return (NULL); + } + + return (FindEndOfParameter (CloseQuote+1)); +} + +/** + Return the next parameter from a command line string. + + This function moves the next parameter from Walker into TempParameter and moves + Walker up past that parameter for recursive calling. When the final parameter + is moved *Walker will be set to NULL; + + Temp Parameter must be large enough to hold the parameter before calling this + function. + + This will also remove all remaining ^ characters after processing. + + @param[in, out] Walker pointer to string of command line. Adjusted to + reminaing command line on return + @param[in, out] TempParameter pointer to string of command line item extracted. + @param[in] Length buffer size of TempParameter. + @param[in] StripQuotation if TRUE then strip the quotation marks surrounding + the parameters. + + @return EFI_INALID_PARAMETER A required parameter was NULL or pointed to a NULL or empty string. + @return EFI_NOT_FOUND A closing " could not be found on the specified string +**/ +EFI_STATUS +EFIAPI +GetNextParameter( + IN OUT CHAR16 **Walker, + IN OUT CHAR16 **TempParameter, + IN CONST UINTN Length, + IN BOOLEAN StripQuotation + ) +{ + CONST CHAR16 *NextDelim; + + if (Walker == NULL + ||*Walker == NULL + ||TempParameter == NULL + ||*TempParameter == NULL + ){ + return (EFI_INVALID_PARAMETER); + } + + + // + // make sure we dont have any leading spaces + // + while ((*Walker)[0] == L' ') { + (*Walker)++; + } + + // + // make sure we still have some params now... + // + if (StrLen(*Walker) == 0) { +DEBUG_CODE_BEGIN(); + *Walker = NULL; +DEBUG_CODE_END(); + return (EFI_INVALID_PARAMETER); + } + + NextDelim = FindEndOfParameter(*Walker); + + if (NextDelim == NULL){ +DEBUG_CODE_BEGIN(); + *Walker = NULL; +DEBUG_CODE_END(); + return (EFI_NOT_FOUND); + } + + StrnCpyS(*TempParameter, Length / sizeof(CHAR16), (*Walker), NextDelim - *Walker); + + // + // Add a CHAR_NULL if we didnt get one via the copy + // + if (*NextDelim != CHAR_NULL) { + (*TempParameter)[NextDelim - *Walker] = CHAR_NULL; + } + + // + // Update Walker for the next iteration through the function + // + *Walker = (CHAR16*)NextDelim; + + // + // Remove any non-escaped quotes in the string + // Remove any remaining escape characters in the string + // + for (NextDelim = FindFirstCharacter(*TempParameter, L"\"^", CHAR_NULL) + ; *NextDelim != CHAR_NULL + ; NextDelim = FindFirstCharacter(NextDelim, L"\"^", CHAR_NULL) + ) { + if (*NextDelim == L'^') { + + // + // eliminate the escape ^ + // + CopyMem ((CHAR16*)NextDelim, NextDelim + 1, StrSize (NextDelim + 1)); + NextDelim++; + } else if (*NextDelim == L'\"') { + + // + // eliminate the unescaped quote + // + if (StripQuotation) { + CopyMem ((CHAR16*)NextDelim, NextDelim + 1, StrSize (NextDelim + 1)); + } else{ + NextDelim++; + } + } + } + + return EFI_SUCCESS; +} + /** Function to populate Argc and Argv. @@ -82,7 +238,7 @@ ParseCommandLineToArgs( ; Walker != NULL && *Walker != CHAR_NULL ; Count++ ) { - if (EFI_ERROR (ShellGetNextParameter (&Walker, TempParameter, Size, TRUE))) { + if (EFI_ERROR(GetNextParameter(&Walker, &TempParameter, Size, TRUE))) { break; } } @@ -100,7 +256,7 @@ ParseCommandLineToArgs( Walker = (CHAR16*)NewCommandLine; while(Walker != NULL && *Walker != CHAR_NULL) { SetMem16(TempParameter, Size, CHAR_NULL); - if (EFI_ERROR (ShellGetNextParameter (&Walker, TempParameter, Size, StripQuotation))) { + if (EFI_ERROR(GetNextParameter(&Walker, &TempParameter, Size, StripQuotation))) { Status = EFI_INVALID_PARAMETER; goto Done; } diff --git a/ShellPkg/Application/Shell/ShellParametersProtocol.h b/ShellPkg/Application/Shell/ShellParametersProtocol.h index 1205d92c19..926f36242c 100644 --- a/ShellPkg/Application/Shell/ShellParametersProtocol.h +++ b/ShellPkg/Application/Shell/ShellParametersProtocol.h @@ -190,5 +190,34 @@ ParseCommandLineToArgs( IN OUT UINTN *Argc ); +/** + return the next parameter from a command line string; + + This function moves the next parameter from Walker into TempParameter and moves + Walker up past that parameter for recursive calling. When the final parameter + is moved *Walker will be set to NULL; + + Temp Parameter must be large enough to hold the parameter before calling this + function. + + @param[in, out] Walker pointer to string of command line. Adjusted to + reminaing command line on return + @param[in, out] TempParameter pointer to string of command line item extracted. + @param[in] Length Length of (*TempParameter) in bytes + @param[in] StripQuotation if TRUE then strip the quotation marks surrounding + the parameters. + + @return EFI_INALID_PARAMETER A required parameter was NULL or pointed to a NULL or empty string. + @return EFI_NOT_FOUND A closing " could not be found on the specified string +**/ +EFI_STATUS +EFIAPI +GetNextParameter( + IN OUT CHAR16 **Walker, + IN OUT CHAR16 **TempParameter, + IN CONST UINTN Length, + IN BOOLEAN StripQuotation + ); + #endif //_SHELL_PARAMETERS_PROTOCOL_PROVIDER_HEADER_ diff --git a/ShellPkg/Include/Library/ShellCommandLib.h b/ShellPkg/Include/Library/ShellCommandLib.h index 5c5e241f15..3ee820001e 100644 --- a/ShellPkg/Include/Library/ShellCommandLib.h +++ b/ShellPkg/Include/Library/ShellCommandLib.h @@ -719,49 +719,4 @@ CatSDumpHex ( IN UINTN DataSize, IN VOID *UserData ); - -/** - Return the pointer to the first occurrence of any character from a list of characters. - - @param[in] String The string to parse - @param[in] CharacterList The list of character to look for - @param[in] IgnoreEscapedCharacter TRUE to ignore escaped characters - - @return The location of the first character in the String. - @return Pointer to the ending NULL character of the String. -**/ -CONST CHAR16* -EFIAPI -ShellFindFirstCharacter ( - IN CONST CHAR16 *String, - IN CONST CHAR16 *CharacterList, - IN CONST BOOLEAN IgnoreEscapedCharacter - ); - -/** - return the next parameter from a command line string; - - This function moves the next parameter from Walker into NextParameter and moves - Walker up past that parameter for recursive calling. When the final parameter - is moved *Walker will be set to NULL; - - @param[in, out] Walker pointer to string of command line. Adjusted to - reminaing command line on return - @param[in, out] NextParameter string of command line item extracted. - @param[in] Length Length of TempParameter in bytes - @param[in] StripQuotation if TRUE then strip the quotation marks surrounding - the parameters. - - @return EFI_INALID_PARAMETER A required parameter was NULL or pointed to a NULL or empty string. - @return EFI_NOT_FOUND A closing " could not be found on the specified string -**/ -EFI_STATUS -EFIAPI -ShellGetNextParameter( - IN OUT CHAR16 **Walker, - IN OUT CHAR16 *NextParameter, - IN CONST UINTN Length, - IN BOOLEAN StripQuotation - ); - #endif //_SHELL_COMMAND_LIB_ diff --git a/ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.c b/ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.c index ac77111ef9..a97361c407 100644 --- a/ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.c +++ b/ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.c @@ -82,191 +82,6 @@ CommandInit( return (EFI_SUCCESS); } -/** - Return the pointer to the first occurrence of any character from a list of characters. - - @param[in] String The string to parse - @param[in] CharacterList The list of character to look for - @param[in] IgnoreEscapedCharacter TRUE to ignore escaped characters - - @return The location of the first character in the String. - @return Pointer to the ending NULL character of the String. -**/ -CONST CHAR16* -EFIAPI -ShellFindFirstCharacter ( - IN CONST CHAR16 *String, - IN CONST CHAR16 *CharacterList, - IN CONST BOOLEAN IgnoreEscapedCharacter - ) -{ - UINTN WalkChar; - UINTN WalkStr; - - for (WalkStr = 0; WalkStr < StrLen (String); WalkStr++) { - if (IgnoreEscapedCharacter && (String[WalkStr] == L'^')) { - WalkStr++; - continue; - } - for (WalkChar = 0; WalkChar < StrLen (CharacterList); WalkChar++) { - if (String[WalkStr] == CharacterList[WalkChar]) { - return &String[WalkStr]; - } - } - } - return &String[WalkStr]; -} - -/** - Return the next parameter's end from a command line string. - - @param[in] String the string to parse -**/ -CONST CHAR16* -FindEndOfParameter( - IN CONST CHAR16 *String - ) -{ - CONST CHAR16 *First; - CONST CHAR16 *CloseQuote; - - First = ShellFindFirstCharacter (String, L" \"", TRUE); - - // - // nothing, all one parameter remaining - // - if (*First == CHAR_NULL) { - return (First); - } - - // - // If space before a quote (or neither found, i.e. both CHAR_NULL), - // then that's the end. - // - if (*First == L' ') { - return (First); - } - - CloseQuote = ShellFindFirstCharacter (First+1, L"\"", TRUE); - - // - // We did not find a terminator... - // - if (*CloseQuote == CHAR_NULL) { - return (NULL); - } - - return (FindEndOfParameter (CloseQuote+1)); -} - -/** - Return the next parameter from a command line string. - - This function moves the next parameter from Walker into NextParameter and moves - Walker up past that parameter for recursive calling. When the final parameter - is moved *Walker will be set to NULL; - - This will also remove all remaining ^ characters after processing. - - @param[in, out] Walker pointer to string of command line. Adjusted to - reminaing command line on return - @param[in, out] NextParameter pointer to string of command line item extracted. - @param[in] Length buffer size of TempParameter. - @param[in] StripQuotation if TRUE then strip the quotation marks surrounding - the parameters. - - @return EFI_INALID_PARAMETER A required parameter was NULL or pointed to a NULL or empty string. - @return EFI_NOT_FOUND A closing " could not be found on the specified string -**/ -EFI_STATUS -EFIAPI -ShellGetNextParameter ( - IN OUT CHAR16 **Walker, - IN OUT CHAR16 *NextParameter, - IN CONST UINTN Length, - IN BOOLEAN StripQuotation - ) -{ - CONST CHAR16 *NextDelim; - - if (Walker == NULL - ||*Walker == NULL - ||NextParameter == NULL - ){ - return EFI_INVALID_PARAMETER; - } - - // - // make sure we dont have any leading spaces - // - while ((*Walker)[0] == L' ') { - (*Walker)++; - } - - // - // make sure we still have some params now... - // - if (StrLen(*Walker) == 0) { - DEBUG_CODE ( - *Walker = NULL; - ); - return (EFI_INVALID_PARAMETER); - } - - NextDelim = FindEndOfParameter(*Walker); - - if (NextDelim == NULL){ - DEBUG_CODE ( - *Walker = NULL; - ); - return (EFI_NOT_FOUND); - } - - StrnCpyS(NextParameter, Length / sizeof(CHAR16), (*Walker), NextDelim - *Walker); - - // - // Add a CHAR_NULL if we didnt get one via the copy - // - if (*NextDelim != CHAR_NULL) { - NextParameter[NextDelim - *Walker] = CHAR_NULL; - } - - // - // Update Walker for the next iteration through the function - // - *Walker = (CHAR16*)NextDelim; - - // - // Remove any non-escaped quotes in the string - // Remove any remaining escape characters in the string - // - for (NextDelim = ShellFindFirstCharacter(NextParameter, L"\"^", FALSE) - ; *NextDelim != CHAR_NULL - ; NextDelim = ShellFindFirstCharacter(NextDelim, L"\"^", FALSE) - ) { - if (*NextDelim == L'^') { - - // - // eliminate the escape ^ - // - CopyMem ((CHAR16*)NextDelim, NextDelim + 1, StrSize (NextDelim + 1)); - NextDelim++; - } else if (*NextDelim == L'\"') { - - // - // eliminate the unescaped quote - // - if (StripQuotation) { - CopyMem ((CHAR16*)NextDelim, NextDelim + 1, StrSize (NextDelim + 1)); - } else { - NextDelim++; - } - } - } - - return EFI_SUCCESS; -} - /** Constructor for the Shell Command library.