X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=ShellPkg%2FApplication%2FShell%2FShell.c;h=627fab0ad03550e5e990c037994a783f42d0f679;hb=9d66ee4d177307ca59f08d242e592ec95a325d26;hp=fa7201642a1cf07c22ea724b7cf8a3358cb2fca2;hpb=d6e88a6c60f49c73bea31a0f653d85c6f358ff0d;p=mirror_edk2.git diff --git a/ShellPkg/Application/Shell/Shell.c b/ShellPkg/Application/Shell/Shell.c index fa7201642a..627fab0ad0 100644 --- a/ShellPkg/Application/Shell/Shell.c +++ b/ShellPkg/Application/Shell/Shell.c @@ -509,6 +509,7 @@ UefiMain ( // Reset page break back to default. // ShellInfoObject.PageBreakEnabled = PcdGetBool(PcdShellPageBreakDefault); + ASSERT (ShellInfoObject.ConsoleInfo != NULL); ShellInfoObject.ConsoleInfo->Enabled = TRUE; ShellInfoObject.ConsoleInfo->RowCounter = 0; @@ -835,9 +836,13 @@ ProcessCommandLine( ShellInfoObject.ShellInitSettings.BitUnion.Bits.Exit = FALSE; ShellInfoObject.ShellInitSettings.Delay = 5; - // Start LoopVar at 1 to ignore Argv[0] which is the name of this binary - // (probably "Shell.efi") - for (LoopVar = 1 ; LoopVar < gEfiShellParametersProtocol->Argc ; LoopVar++) { + // + // Start LoopVar at 0 to parse only optional arguments at Argv[0] + // and parse other parameters from Argv[1]. This is for use case that + // UEFI Shell boot option is created, and OptionalData is provided + // that starts with shell command-line options. + // + for (LoopVar = 0 ; LoopVar < gEfiShellParametersProtocol->Argc ; LoopVar++) { CurrentArg = gEfiShellParametersProtocol->Argv[LoopVar]; if (UnicodeCollation->StriColl ( UnicodeCollation, @@ -925,7 +930,14 @@ ProcessCommandLine( ); return EFI_INVALID_PARAMETER; } else { - ShellInfoObject.ShellInitSettings.FileName = AllocateZeroPool(StrSize(CurrentArg)); + // + // First argument should be Shell.efi image name + // + if (LoopVar == 0) { + continue; + } + + ShellInfoObject.ShellInitSettings.FileName = AllocateCopyPool(StrSize(CurrentArg), CurrentArg); if (ShellInfoObject.ShellInitSettings.FileName == NULL) { return (EFI_OUT_OF_RESOURCES); } @@ -933,8 +945,6 @@ ProcessCommandLine( // We found `file-name`. // ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoStartup = 1; - - StrCpy (ShellInfoObject.ShellInitSettings.FileName, CurrentArg); LoopVar++; // Add `file-name-options` @@ -1015,10 +1025,10 @@ DoStartupScript( if (FileStringPath == NULL) { return (EFI_OUT_OF_RESOURCES); } - StrCpy(FileStringPath, ShellInfoObject.ShellInitSettings.FileName); + StrnCpy(FileStringPath, ShellInfoObject.ShellInitSettings.FileName, NewSize/sizeof(CHAR16) -1); if (ShellInfoObject.ShellInitSettings.FileOptions != NULL) { - StrCat(FileStringPath, L" "); - StrCat(FileStringPath, ShellInfoObject.ShellInitSettings.FileOptions); + StrnCat(FileStringPath, L" ", NewSize/sizeof(CHAR16) - StrLen(FileStringPath) -1); + StrnCat(FileStringPath, ShellInfoObject.ShellInitSettings.FileOptions, NewSize/sizeof(CHAR16) - StrLen(FileStringPath) -1); } Status = RunCommand(FileStringPath, ExitStatus); FreePool(FileStringPath); @@ -1235,9 +1245,8 @@ AddLineToCommandHistory( Node = AllocateZeroPool(sizeof(BUFFER_LIST)); ASSERT(Node != NULL); - Node->Buffer = AllocateZeroPool(StrSize(Buffer)); + Node->Buffer = AllocateCopyPool(StrSize(Buffer), Buffer); ASSERT(Node->Buffer != NULL); - StrCpy(Node->Buffer, Buffer); InsertTailList(&ShellInfoObject.ViewingSettings.CommandHistory.Link, &Node->Link); } @@ -1268,11 +1277,10 @@ ShellConvertAlias( return (EFI_SUCCESS); } FreePool(*CommandString); - *CommandString = AllocateZeroPool(StrSize(NewString)); + *CommandString = AllocateCopyPool(StrSize(NewString), NewString); if (*CommandString == NULL) { return (EFI_OUT_OF_RESOURCES); } - StrCpy(*CommandString, NewString); return (EFI_SUCCESS); } @@ -1367,14 +1375,14 @@ StripUnreplacedEnvironmentVariables( } ASSERT(FirstPercent < FirstQuote); if (SecondPercent < FirstQuote) { - // - // We need to remove from FirstPercent to SecondPercent - // - CopyMem(FirstPercent, SecondPercent + 1, StrSize(SecondPercent + 1)); + FirstPercent[0] = L'\"'; + SecondPercent[0] = L'\"'; // - // dont need to update the locator. both % characters are gone. + // We need to remove from FirstPercent to SecondPercent // + CopyMem(FirstPercent + 1, SecondPercent, StrSize(SecondPercent)); + CurrentLocator = FirstPercent + 2; continue; } ASSERT(FirstQuote < SecondPercent); @@ -1465,7 +1473,7 @@ ShellConvertVariables ( // // now do the replacements... // - NewCommandLine1 = AllocateZeroPool(NewSize); + NewCommandLine1 = AllocateCopyPool(NewSize, OriginalCommandLine); NewCommandLine2 = AllocateZeroPool(NewSize); ItemTemp = AllocateZeroPool(ItemSize+(2*sizeof(CHAR16))); if (NewCommandLine1 == NULL || NewCommandLine2 == NULL || ItemTemp == NULL) { @@ -1474,16 +1482,15 @@ ShellConvertVariables ( SHELL_FREE_NON_NULL(ItemTemp); return (NULL); } - StrCpy(NewCommandLine1, OriginalCommandLine); for (MasterEnvList = EfiShellGetEnv(NULL) - ; MasterEnvList != NULL && *MasterEnvList != CHAR_NULL //&& *(MasterEnvList+1) != CHAR_NULL + ; MasterEnvList != NULL && *MasterEnvList != CHAR_NULL ; MasterEnvList += StrLen(MasterEnvList) + 1 ){ - StrCpy(ItemTemp, L"%"); - StrCat(ItemTemp, MasterEnvList); - StrCat(ItemTemp, L"%"); + StrnCpy(ItemTemp, L"%", ((ItemSize+(2*sizeof(CHAR16)))/sizeof(CHAR16))-1); + StrnCat(ItemTemp, MasterEnvList, ((ItemSize+(2*sizeof(CHAR16)))/sizeof(CHAR16))-1 - StrLen(ItemTemp)); + StrnCat(ItemTemp, L"%", ((ItemSize+(2*sizeof(CHAR16)))/sizeof(CHAR16))-1 - StrLen(ItemTemp)); ShellCopySearchAndReplace(NewCommandLine1, NewCommandLine2, NewSize, ItemTemp, EfiShellGetEnv(MasterEnvList), TRUE, FALSE); - StrCpy(NewCommandLine1, NewCommandLine2); + StrnCpy(NewCommandLine1, NewCommandLine2, NewSize/sizeof(CHAR16)-1); } if (CurrentScriptFile != NULL) { for (AliasListNode = (ALIAS_LIST*)GetFirstNode(&CurrentScriptFile->SubstList) @@ -1491,7 +1498,7 @@ ShellConvertVariables ( ; AliasListNode = (ALIAS_LIST*)GetNextNode(&CurrentScriptFile->SubstList, &AliasListNode->Link) ){ ShellCopySearchAndReplace(NewCommandLine1, NewCommandLine2, NewSize, AliasListNode->Alias, AliasListNode->CommandString, TRUE, FALSE); - StrCpy(NewCommandLine1, NewCommandLine2); + StrnCpy(NewCommandLine1, NewCommandLine2, NewSize/sizeof(CHAR16)-1); } // @@ -1504,7 +1511,7 @@ ShellConvertVariables ( // Now cleanup any straggler intentionally ignored "%" characters // ShellCopySearchAndReplace(NewCommandLine1, NewCommandLine2, NewSize, L"^%", L"%", TRUE, FALSE); - StrCpy(NewCommandLine1, NewCommandLine2); + StrnCpy(NewCommandLine1, NewCommandLine2, NewSize/sizeof(CHAR16)-1); FreePool(NewCommandLine2); FreePool(ItemTemp); @@ -1838,7 +1845,7 @@ IsValidSplit( return (EFI_OUT_OF_RESOURCES); } TempWalker = (CHAR16*)Temp; - GetNextParameter(&TempWalker, &FirstParameter); + GetNextParameter(&TempWalker, &FirstParameter, StrSize(CmdLine)); if (GetOperationType(FirstParameter) == Unknown_Invalid) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, FirstParameter); @@ -2006,7 +2013,7 @@ DoHelpUpdate( Walker = *CmdLine; while(Walker != NULL && *Walker != CHAR_NULL) { LastWalker = Walker; - GetNextParameter(&Walker, &CurrentParameter); + GetNextParameter(&Walker, &CurrentParameter, StrSize(*CmdLine)); if (StrStr(CurrentParameter, L"-?") == CurrentParameter) { LastWalker[0] = L' '; LastWalker[1] = L' '; @@ -2015,8 +2022,12 @@ DoHelpUpdate( Status = EFI_OUT_OF_RESOURCES; break; } - StrCpy(NewCommandLine, L"help "); - StrCat(NewCommandLine, *CmdLine); + + // + // We know the space is sufficient since we just calculated it. + // + StrnCpy(NewCommandLine, L"help ", 5); + StrnCat(NewCommandLine, *CmdLine, StrLen(*CmdLine)); SHELL_FREE_NON_NULL(*CmdLine); *CmdLine = NewCommandLine; break; @@ -2080,6 +2091,7 @@ ProcessCommandLineToFinal( if (EFI_ERROR(Status)) { return (Status); } + ASSERT (*CmdLine != NULL); TrimSpaces(CmdLine); @@ -2220,6 +2232,7 @@ RunCommandOrFile( ) { EFI_STATUS Status; + EFI_STATUS StartStatus; CHAR16 *CommandWithPath; EFI_DEVICE_PATH_PROTOCOL *DevPath; SHELL_STATUS CalleeExitStatus; @@ -2297,6 +2310,7 @@ RunCommandOrFile( DevPath, CmdLine, NULL, + &StartStatus, NULL, NULL ); @@ -2306,7 +2320,7 @@ RunCommandOrFile( if(EFI_ERROR (Status)) { CalleeExitStatus = (SHELL_STATUS) (Status & (~MAX_BIT)); } else { - CalleeExitStatus = SHELL_SUCCESS; + CalleeExitStatus = (SHELL_STATUS) StartStatus; } // @@ -2378,6 +2392,7 @@ SetupAndRunCommandOrFile( // Now run the command, script, or application // if (!EFI_ERROR(Status)) { + TrimSpaces(&CmdLine); Status = RunCommandOrFile( Type, CmdLine, @@ -2442,6 +2457,24 @@ RunCommand( TrimSpaces(&CleanOriginal); + // + // NULL out comments (leveraged from RunScriptFileHandle() ). + // The # character on a line is used to denote that all characters on the same line + // and to the right of the # are to be ignored by the shell. + // Afterward, again remove spaces, in case any were between the last command-parameter and '#'. + // + for (TempWalker = CleanOriginal; TempWalker != NULL && *TempWalker != CHAR_NULL; TempWalker++) { + if (*TempWalker == L'^') { + if (*(TempWalker + 1) == L'#') { + CopyMem (TempWalker, TempWalker + 1, StrSize (TempWalker) - sizeof (TempWalker[0])); + } + } else if (*TempWalker == L'#') { + *TempWalker = CHAR_NULL; + } + } + + TrimSpaces(&CleanOriginal); + // // Handle case that passed in command line is just 1 or more " " characters. // @@ -2474,7 +2507,7 @@ RunCommand( return (EFI_OUT_OF_RESOURCES); } TempWalker = CleanOriginal; - GetNextParameter(&TempWalker, &FirstParameter); + GetNextParameter(&TempWalker, &FirstParameter, StrSize(CleanOriginal)); // // Depending on the first parameter we change the behavior @@ -2670,7 +2703,7 @@ RunScriptFileHandle ( ; // conditional increment in the body of the loop ){ ASSERT(CommandLine2 != NULL); - StrCpy(CommandLine2, NewScriptFile->CurrentCommand->Cl); + StrnCpy(CommandLine2, NewScriptFile->CurrentCommand->Cl, PcdGet16(PcdShellPrintBufferSize)/sizeof(CHAR16)-1); // // NULL out comments @@ -2689,7 +2722,7 @@ RunScriptFileHandle ( // // Due to variability in starting the find and replace action we need to have both buffers the same. // - StrCpy(CommandLine, CommandLine2); + StrnCpy(CommandLine, CommandLine2, PcdGet16(PcdShellPrintBufferSize)/sizeof(CHAR16)-1); // // Remove the %0 to %9 from the command line (if we have some arguments) @@ -2697,34 +2730,34 @@ RunScriptFileHandle ( if (NewScriptFile->Argv != NULL) { switch (NewScriptFile->Argc) { default: - Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%9", NewScriptFile->Argv[9], FALSE, TRUE); + Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%9", NewScriptFile->Argv[9], FALSE, FALSE); ASSERT_EFI_ERROR(Status); case 9: - Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%8", NewScriptFile->Argv[8], FALSE, TRUE); + Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%8", NewScriptFile->Argv[8], FALSE, FALSE); ASSERT_EFI_ERROR(Status); case 8: - Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%7", NewScriptFile->Argv[7], FALSE, TRUE); + Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%7", NewScriptFile->Argv[7], FALSE, FALSE); ASSERT_EFI_ERROR(Status); case 7: - Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%6", NewScriptFile->Argv[6], FALSE, TRUE); + Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%6", NewScriptFile->Argv[6], FALSE, FALSE); ASSERT_EFI_ERROR(Status); case 6: - Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%5", NewScriptFile->Argv[5], FALSE, TRUE); + Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%5", NewScriptFile->Argv[5], FALSE, FALSE); ASSERT_EFI_ERROR(Status); case 5: - Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%4", NewScriptFile->Argv[4], FALSE, TRUE); + Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%4", NewScriptFile->Argv[4], FALSE, FALSE); ASSERT_EFI_ERROR(Status); case 4: - Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%3", NewScriptFile->Argv[3], FALSE, TRUE); + Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%3", NewScriptFile->Argv[3], FALSE, FALSE); ASSERT_EFI_ERROR(Status); case 3: - Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%2", NewScriptFile->Argv[2], FALSE, TRUE); + Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%2", NewScriptFile->Argv[2], FALSE, FALSE); ASSERT_EFI_ERROR(Status); case 2: - Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%1", NewScriptFile->Argv[1], FALSE, TRUE); + Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%1", NewScriptFile->Argv[1], FALSE, FALSE); ASSERT_EFI_ERROR(Status); case 1: - Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%0", NewScriptFile->Argv[0], FALSE, TRUE); + Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%0", NewScriptFile->Argv[0], FALSE, FALSE); ASSERT_EFI_ERROR(Status); break; case 0: @@ -2741,7 +2774,7 @@ RunScriptFileHandle ( Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PcdGet16 (PcdShellPrintBufferSize), L"%8", L"\"\"", FALSE, FALSE); Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PcdGet16 (PcdShellPrintBufferSize), L"%9", L"\"\"", FALSE, FALSE); - StrCpy(CommandLine2, CommandLine); + StrnCpy(CommandLine2, CommandLine, PcdGet16(PcdShellPrintBufferSize)/sizeof(CHAR16)-1); LastCommand = NewScriptFile->CurrentCommand;