X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=ShellPkg%2FApplication%2FShell%2FShell.c;h=ef821a5c5d021bc5ce20dfb8abb6ba37774af35b;hp=fe722e955448bd0c60d6901da4bf3f9d350e85fc;hb=6fa0da7d52815979be31b8252aae839883dc7b0c;hpb=806c49db0538080ac397892c750b86d1c55d32af diff --git a/ShellPkg/Application/Shell/Shell.c b/ShellPkg/Application/Shell/Shell.c index fe722e9554..ef821a5c5d 100644 --- a/ShellPkg/Application/Shell/Shell.c +++ b/ShellPkg/Application/Shell/Shell.c @@ -91,9 +91,9 @@ TrimSpaces( } // - // Remove any spaces at the end of the (*String). + // Remove any spaces and tabs at the end of the (*String). // - while ((*String)[StrLen((*String))-1] == L' ') { + while ((StrLen (*String) > 0) && (((*String)[StrLen((*String))-1] == L' ') || ((*String)[StrLen((*String))-1] == L'\t'))) { (*String)[StrLen((*String))-1] = CHAR_NULL; } @@ -1596,6 +1596,96 @@ GetOperationType( return (UNKNOWN_INVALID); } +EFI_STATUS +EFIAPI +IsValidSplit( + IN CONST CHAR16 *CmdLine + ) +{ + CHAR16 *Temp; + CHAR16 *FirstParameter; + CHAR16 *TempWalker; + EFI_STATUS Status; + + Temp = NULL; + + Temp = StrnCatGrow(&Temp, NULL, CmdLine, 0); + if (Temp == NULL) { + return (EFI_OUT_OF_RESOURCES); + } + + FirstParameter = StrStr(Temp, L"|"); + if (FirstParameter != NULL) { + *FirstParameter = CHAR_NULL; + } + + FirstParameter = NULL; + + // + // Process the command line + // + Status = ProcessCommandLineToFinal(&Temp); + + if (!EFI_ERROR(Status)) { + FirstParameter = AllocateZeroPool(StrSize(CmdLine)); + if (FirstParameter == NULL) { + SHELL_FREE_NON_NULL(Temp); + return (EFI_OUT_OF_RESOURCES); + } + TempWalker = (CHAR16*)Temp; + GetNextParameter(&TempWalker, &FirstParameter); + + if (GetOperationType(FirstParameter) == UNKNOWN_INVALID) { + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter); + SetLastError(SHELL_NOT_FOUND); + Status = EFI_NOT_FOUND; + } + } + + SHELL_FREE_NON_NULL(Temp); + SHELL_FREE_NON_NULL(FirstParameter); + return Status; +} + +/** + Determine if a command line contains with a split contains only valid commands + + @param[in] CmdLine The command line to parse. + + @retval EFI_SUCCESS CmdLine has only valid commands, application, or has no split. + @retval EFI_ABORTED CmdLine has at least one invalid command or application. +**/ +EFI_STATUS +EFIAPI +VerifySplit( + IN CONST CHAR16 *CmdLine + ) +{ + CONST CHAR16 *TempSpot; + EFI_STATUS Status; + + // + // Verify up to the pipe or end character + // + Status = IsValidSplit(CmdLine); + if (EFI_ERROR(Status)) { + return (Status); + } + + // + // If this was the only item, then get out + // + if (!ContainsSplit(CmdLine)) { + return (EFI_SUCCESS); + } + + // + // recurse to verify the next item + // + TempSpot = FindSplit(CmdLine)+1; + return (VerifySplit(TempSpot)); +} + /** Process a split based operation. @@ -1613,6 +1703,11 @@ ProcessNewSplitCommandLine( SPLIT_LIST *Split; EFI_STATUS Status; + Status = VerifySplit(CmdLine); + if (EFI_ERROR(Status)) { + return (Status); + } + Split = NULL; // @@ -1728,7 +1823,7 @@ DoHelpUpdate( EFI_STATUS EFIAPI SetLastError( - IN CONST UINT64 ErrorCode + IN CONST SHELL_STATUS ErrorCode ) { CHAR16 LeString[19]; @@ -1754,7 +1849,7 @@ SetLastError( **/ EFI_STATUS EFIAPI -ProcessCommandLineAliasVariable( +ProcessCommandLineToFinal( IN OUT CHAR16 **CmdLine ) { @@ -1840,8 +1935,19 @@ RunInternalCommand( // Pass thru the exitcode from the app. // if (ShellCommandGetExit()) { + // + // An Exit was requested ("exit" command), pass its value up. + // Status = CommandReturnedStatus; - } else if (CommandReturnedStatus != 0 && IsScriptOnlyCommand(FirstParameter)) { + } else if (CommandReturnedStatus != SHELL_SUCCESS && IsScriptOnlyCommand(FirstParameter)) { + // + // Always abort when a script only command fails for any reason + // + Status = EFI_ABORTED; + } else if (ShellCommandGetCurrentScriptFile() != NULL && CommandReturnedStatus == SHELL_ABORTED) { + // + // Abort when in a script and a command aborted + // Status = EFI_ABORTED; } } @@ -1853,11 +1959,17 @@ RunInternalCommand( // RestoreArgcArgv(ParamProtocol, &Argv, &Argc); - if (ShellCommandGetCurrentScriptFile() != NULL && !IsScriptOnlyCommand(FirstParameter)) { - // - // if this is NOT a scipt only command return success so the script won't quit. - // prevent killing the script - this is the only place where we know the actual command name (after alias and variable replacement...) - // + // + // If a script is running and the command is not a scipt only command, then + // change return value to success so the script won't halt (unless aborted). + // + // Script only commands have to be able halt the script since the script will + // not operate if they are failing. + // + if ( ShellCommandGetCurrentScriptFile() != NULL + && !IsScriptOnlyCommand(FirstParameter) + && Status != EFI_ABORTED + ) { Status = EFI_SUCCESS; } @@ -1926,7 +2038,7 @@ RunCommandOrFile( // if (!EFI_ERROR(ShellIsDirectory(CommandWithPath))) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter); - SetLastError(EFI_NOT_FOUND); + SetLastError(SHELL_NOT_FOUND); } switch (Type) { case SCRIPT_FILE_NAME: @@ -1960,8 +2072,18 @@ RunCommandOrFile( // SetLastError(StatusCode); break; + default: + // + // Do nothing. + // + break; } break; + default: + // + // Do nothing. + // + break; } SHELL_FREE_NON_NULL(CommandWithPath); @@ -2069,7 +2191,7 @@ RunCommand( return (EFI_SUCCESS); } - Status = ProcessCommandLineAliasVariable(&CleanOriginal); + Status = ProcessCommandLineToFinal(&CleanOriginal); if (EFI_ERROR(Status)) { SHELL_FREE_NON_NULL(CleanOriginal); return (Status); @@ -2112,7 +2234,7 @@ RunCommand( // Whatever was typed, it was invalid. // ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter); - SetLastError(EFI_NOT_FOUND); + SetLastError(SHELL_NOT_FOUND); break; }