ShellPkg: Don't strip positional parameters of quotation marks.

Per Shell SPEC 2.1 'Double-quotation marks that surround arguments are not stripped in positional parameters'. This patch makes Shell implementation to follow SPEC.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Qiu Shumin <shumin.qiu@intel.com>
Reviewed-by: Jaben Carsey <jaben.carsey@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18742 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Qiu Shumin 2015-11-09 02:29:31 +00:00 committed by shenshushi
parent 3ec97ca490
commit d1c275c651
5 changed files with 80 additions and 48 deletions

View File

@ -1863,7 +1863,7 @@ IsValidSplit(
return (EFI_OUT_OF_RESOURCES);
}
TempWalker = (CHAR16*)Temp;
if (!EFI_ERROR(GetNextParameter(&TempWalker, &FirstParameter, StrSize(CmdLine)))) {
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);
@ -2029,7 +2029,7 @@ DoHelpUpdate(
Walker = *CmdLine;
while(Walker != NULL && *Walker != CHAR_NULL) {
if (!EFI_ERROR(GetNextParameter(&Walker, &CurrentParameter, StrSize(*CmdLine)))) {
if (!EFI_ERROR(GetNextParameter(&Walker, &CurrentParameter, StrSize(*CmdLine), TRUE))) {
if (StrStr(CurrentParameter, L"-?") == CurrentParameter) {
CurrentParameter[0] = L' ';
CurrentParameter[1] = L' ';
@ -2173,7 +2173,7 @@ RunInternalCommand(
//
// get the argc and argv updated for internal commands
//
Status = UpdateArgcArgv(ParamProtocol, NewCmdLine, &Argv, &Argc);
Status = UpdateArgcArgv(ParamProtocol, NewCmdLine, Internal_Command, &Argv, &Argc);
if (!EFI_ERROR(Status)) {
//
// Run the internal command.
@ -2520,7 +2520,7 @@ RunShellCommand(
return (EFI_OUT_OF_RESOURCES);
}
TempWalker = CleanOriginal;
if (!EFI_ERROR(GetNextParameter(&TempWalker, &FirstParameter, StrSize(CleanOriginal)))) {
if (!EFI_ERROR(GetNextParameter(&TempWalker, &FirstParameter, StrSize(CleanOriginal), TRUE))) {
//
// Depending on the first parameter we change the behavior
//
@ -2767,34 +2767,34 @@ RunScriptFileHandle (
if (NewScriptFile->Argv != NULL) {
switch (NewScriptFile->Argc) {
default:
Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PrintBuffSize, L"%9", NewScriptFile->Argv[9], FALSE, TRUE);
Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PrintBuffSize, L"%9", NewScriptFile->Argv[9], FALSE, FALSE);
ASSERT_EFI_ERROR(Status);
case 9:
Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PrintBuffSize, L"%8", NewScriptFile->Argv[8], FALSE, TRUE);
Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PrintBuffSize, L"%8", NewScriptFile->Argv[8], FALSE, FALSE);
ASSERT_EFI_ERROR(Status);
case 8:
Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PrintBuffSize, L"%7", NewScriptFile->Argv[7], FALSE, TRUE);
Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PrintBuffSize, L"%7", NewScriptFile->Argv[7], FALSE, FALSE);
ASSERT_EFI_ERROR(Status);
case 7:
Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PrintBuffSize, L"%6", NewScriptFile->Argv[6], FALSE, TRUE);
Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PrintBuffSize, L"%6", NewScriptFile->Argv[6], FALSE, FALSE);
ASSERT_EFI_ERROR(Status);
case 6:
Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PrintBuffSize, L"%5", NewScriptFile->Argv[5], FALSE, TRUE);
Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PrintBuffSize, L"%5", NewScriptFile->Argv[5], FALSE, FALSE);
ASSERT_EFI_ERROR(Status);
case 5:
Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PrintBuffSize, L"%4", NewScriptFile->Argv[4], FALSE, TRUE);
Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PrintBuffSize, L"%4", NewScriptFile->Argv[4], FALSE, FALSE);
ASSERT_EFI_ERROR(Status);
case 4:
Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PrintBuffSize, L"%3", NewScriptFile->Argv[3], FALSE, TRUE);
Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PrintBuffSize, L"%3", NewScriptFile->Argv[3], FALSE, FALSE);
ASSERT_EFI_ERROR(Status);
case 3:
Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PrintBuffSize, L"%2", NewScriptFile->Argv[2], FALSE, TRUE);
Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PrintBuffSize, L"%2", NewScriptFile->Argv[2], FALSE, FALSE);
ASSERT_EFI_ERROR(Status);
case 2:
Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PrintBuffSize, L"%1", NewScriptFile->Argv[1], FALSE, TRUE);
Status = ShellCopySearchAndReplace(CommandLine2, CommandLine, PrintBuffSize, L"%1", NewScriptFile->Argv[1], FALSE, FALSE);
ASSERT_EFI_ERROR(Status);
case 1:
Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PrintBuffSize, L"%0", NewScriptFile->Argv[0], FALSE, TRUE);
Status = ShellCopySearchAndReplace(CommandLine, CommandLine2, PrintBuffSize, L"%0", NewScriptFile->Argv[0], FALSE, FALSE);
ASSERT_EFI_ERROR(Status);
break;
case 0:
@ -2944,7 +2944,7 @@ RunScriptFile (
//
// get the argc and argv updated for scripts
//
Status = UpdateArgcArgv(ParamProtocol, CmdLine, &Argv, &Argc);
Status = UpdateArgcArgv(ParamProtocol, CmdLine, Script_File_Name, &Argv, &Argc);
if (!EFI_ERROR(Status)) {
if (Handle == NULL) {

View File

@ -124,14 +124,6 @@ typedef struct {
extern SHELL_INFO ShellInfoObject;
typedef enum {
Internal_Command,
Script_File_Name,
Efi_Application,
File_Sys_Change,
Unknown_Invalid
} SHELL_OPERATION_TYPES;
/**
Converts the command line to it's post-processed form. this replaces variables and alias' per UEFI Shell spec.

View File

@ -78,6 +78,8 @@ FindEndOfParameter(
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
@ -87,7 +89,8 @@ EFIAPI
GetNextParameter(
IN OUT CHAR16 **Walker,
IN OUT CHAR16 **TempParameter,
IN CONST UINTN Length
IN CONST UINTN Length,
IN BOOLEAN StripQuotation
)
{
CONST CHAR16 *NextDelim;
@ -161,7 +164,11 @@ DEBUG_CODE_END();
//
// eliminate the unescaped quote
//
if (StripQuotation) {
CopyMem ((CHAR16*)NextDelim, NextDelim + 1, StrSize (NextDelim + 1));
} else{
NextDelim++;
}
}
}
@ -179,6 +186,8 @@ DEBUG_CODE_END();
etc... must be complete before calling this API.
@param[in] CommandLine String of command line to parse
@param[in] StripQuotation if TRUE then strip the quotation marks surrounding
the parameters.
@param[in, out] Argv pointer to array of strings; one for each parameter
@param[in, out] Argc pointer to number of strings in Argv array
@ -189,6 +198,7 @@ EFI_STATUS
EFIAPI
ParseCommandLineToArgs(
IN CONST CHAR16 *CommandLine,
IN BOOLEAN StripQuotation,
IN OUT CHAR16 ***Argv,
IN OUT UINTN *Argc
)
@ -228,7 +238,7 @@ ParseCommandLineToArgs(
; Walker != NULL && *Walker != CHAR_NULL
; Count++
) {
if (EFI_ERROR(GetNextParameter(&Walker, &TempParameter, Size))) {
if (EFI_ERROR(GetNextParameter(&Walker, &TempParameter, Size, TRUE))) {
break;
}
}
@ -246,7 +256,7 @@ ParseCommandLineToArgs(
Walker = (CHAR16*)NewCommandLine;
while(Walker != NULL && *Walker != CHAR_NULL) {
SetMem16(TempParameter, Size, CHAR_NULL);
if (EFI_ERROR(GetNextParameter(&Walker, &TempParameter, Size))) {
if (EFI_ERROR(GetNextParameter(&Walker, &TempParameter, Size, StripQuotation))) {
Status = EFI_INVALID_PARAMETER;
goto Done;
}
@ -375,6 +385,7 @@ CreatePopulateInstallShellParametersProtocol (
// Populate Argc and Argv
//
Status = ParseCommandLineToArgs(FullCommandLine,
TRUE,
&(*NewShellParameters)->Argv,
&(*NewShellParameters)->Argc);
@ -1369,6 +1380,7 @@ RestoreStdInStdOutStdErr (
@param[in, out] ShellParameters Pointer to parameter structure to modify.
@param[in] NewCommandLine The new command line to parse and use.
@param[in] Type The type of operation.
@param[out] OldArgv Pointer to old list of parameters.
@param[out] OldArgc Pointer to old number of items in Argv list.
@ -1380,11 +1392,15 @@ EFIAPI
UpdateArgcArgv(
IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
IN CONST CHAR16 *NewCommandLine,
IN SHELL_OPERATION_TYPES Type,
OUT CHAR16 ***OldArgv OPTIONAL,
OUT UINTN *OldArgc OPTIONAL
)
{
BOOLEAN StripParamQuotation;
ASSERT(ShellParameters != NULL);
StripParamQuotation = TRUE;
if (OldArgc != NULL) {
*OldArgc = ShellParameters->Argc;
@ -1393,7 +1409,15 @@ UpdateArgcArgv(
*OldArgv = ShellParameters->Argv;
}
return (ParseCommandLineToArgs(NewCommandLine, &(ShellParameters->Argv), &(ShellParameters->Argc)));
if (Type == Script_File_Name) {
StripParamQuotation = FALSE;
}
return ParseCommandLineToArgs( NewCommandLine,
StripParamQuotation,
&(ShellParameters->Argv),
&(ShellParameters->Argc)
);
}
/**

View File

@ -18,6 +18,14 @@
#include "Shell.h"
typedef enum {
Internal_Command,
Script_File_Name,
Efi_Application,
File_Sys_Change,
Unknown_Invalid
} SHELL_OPERATION_TYPES;
/**
creates a new EFI_SHELL_PARAMETERS_PROTOCOL instance and populates it and then
installs it on our handle and if there is an existing version of the protocol
@ -66,6 +74,7 @@ CleanUpShellParametersProtocol (
@param[in, out] ShellParameters pointer to parameter structure to modify
@param[in] NewCommandLine the new command line to parse and use
@param[in] Type the type of operation.
@param[out] OldArgv pointer to old list of parameters
@param[out] OldArgc pointer to old number of items in Argv list
@ -77,6 +86,7 @@ EFIAPI
UpdateArgcArgv(
IN OUT EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
IN CONST CHAR16 *NewCommandLine,
IN SHELL_OPERATION_TYPES Type,
OUT CHAR16 ***OldArgv,
OUT UINTN *OldArgc
);
@ -163,6 +173,8 @@ RestoreStdInStdOutStdErr (
delimited and quote surrounded parameter definition.
@param[in] CommandLine String of command line to parse
@param[in] StripQuotation if TRUE then strip the quotation marks surrounding
the parameters.
@param[in, out] Argv pointer to array of strings; one for each parameter
@param[in, out] Argc pointer to number of strings in Argv array
@ -173,6 +185,7 @@ EFI_STATUS
EFIAPI
ParseCommandLineToArgs(
IN CONST CHAR16 *CommandLine,
IN BOOLEAN StripQuotation,
IN OUT CHAR16 ***Argv,
IN OUT UINTN *Argc
);
@ -191,6 +204,8 @@ ParseCommandLineToArgs(
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
@ -200,7 +215,8 @@ EFIAPI
GetNextParameter(
IN OUT CHAR16 **Walker,
IN OUT CHAR16 **TempParameter,
IN CONST UINTN Length
IN CONST UINTN Length,
IN BOOLEAN StripQuotation
);
#endif //_SHELL_PARAMETERS_PROTOCOL_PROVIDER_HEADER_

View File

@ -1501,7 +1501,7 @@ InternalShellExecuteDevicePath(
ShellParamsProtocol.StdIn = ShellInfoObject.NewShellParametersProtocol->StdIn;
ShellParamsProtocol.StdOut = ShellInfoObject.NewShellParametersProtocol->StdOut;
ShellParamsProtocol.StdErr = ShellInfoObject.NewShellParametersProtocol->StdErr;
Status = UpdateArgcArgv(&ShellParamsProtocol, NewCmdLine, NULL, NULL);
Status = UpdateArgcArgv(&ShellParamsProtocol, NewCmdLine, Efi_Application, NULL, NULL);
ASSERT_EFI_ERROR(Status);
//
// Replace Argv[0] with the full path of the binary we're executing: