Reviewed-by: Jaben Carsey <jaben.car...@intel.com>

> -----Original Message-----
> From: Qiu, Shumin
> Sent: Friday, November 06, 2015 12:06 AM
> To: edk2-devel@lists.01.org
> Cc: Qiu, Shumin <shumin....@intel.com>; Carsey, Jaben
> <jaben.car...@intel.com>
> Subject: [PATCH] ShellPkg: Don't strip positional parameters of quotation
> marks.
> Importance: High
> 
> 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.
> 
> Cc: Jaben Carsey <jaben.car...@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Qiu Shumin <shumin....@intel.com>
> ---
>  ShellPkg/Application/Shell/Shell.c                 | 30 ++++++-------
>  ShellPkg/Application/Shell/Shell.h                 |  8 ----
>  .../Application/Shell/ShellParametersProtocol.c    | 52 ++++++++++++++++---
> ---
>  .../Application/Shell/ShellParametersProtocol.h    | 36 ++++++++++-----
>  ShellPkg/Application/Shell/ShellProtocol.c         |  2 +-
>  5 files changed, 80 insertions(+), 48 deletions(-)
> 
> diff --git a/ShellPkg/Application/Shell/Shell.c
> b/ShellPkg/Application/Shell/Shell.c
> index cb9d969..8af6647 100644
> --- a/ShellPkg/Application/Shell/Shell.c
> +++ b/ShellPkg/Application/Shell/Shell.c
> @@ -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) {
> diff --git a/ShellPkg/Application/Shell/Shell.h
> b/ShellPkg/Application/Shell/Shell.h
> index 7c87651..5726320 100644
> --- a/ShellPkg/Application/Shell/Shell.h
> +++ b/ShellPkg/Application/Shell/Shell.h
> @@ -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.
> 
> diff --git a/ShellPkg/Application/Shell/ShellParametersProtocol.c
> b/ShellPkg/Application/Shell/ShellParametersProtocol.c
> index 9c502f8..56dd792 100644
> --- a/ShellPkg/Application/Shell/ShellParametersProtocol.c
> +++ b/ShellPkg/Application/Shell/ShellParametersProtocol.c
> @@ -74,10 +74,12 @@ FindEndOfParameter(
> 
>    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, 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
> @@ -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
>        //
> -      CopyMem ((CHAR16*)NextDelim, NextDelim + 1, StrSize (NextDelim + 1));
> +      if (StripQuotation) {
> +        CopyMem ((CHAR16*)NextDelim, NextDelim + 1, StrSize (NextDelim +
> 1));
> +       } else{
> +        NextDelim++;
> +       }
>      }
>    }
> 
> @@ -178,9 +185,11 @@ DEBUG_CODE_END();
>    All special character processing (alias, environment variable, redirection,
>    etc... must be complete before calling this API.
> 
> -  @param[in] CommandLine         String of command line to parse
> -  @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
> +  @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
> 
>    @return EFI_SUCCESS           the operation was sucessful
>    @return EFI_OUT_OF_RESOURCES  a memory allocation failed.
> @@ -189,8 +198,9 @@ EFI_STATUS
>  EFIAPI
>  ParseCommandLineToArgs(
>    IN CONST CHAR16 *CommandLine,
> -  IN OUT CHAR16 ***Argv,
> -  IN OUT UINTN *Argc
> +  IN BOOLEAN      StripQuotation,
> +  IN OUT CHAR16   ***Argv,
> +  IN OUT UINTN    *Argc
>    )
>  {
>    UINTN       Count;
> @@ -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)
> +                                );
>  }
> 
>  /**
> diff --git a/ShellPkg/Application/Shell/ShellParametersProtocol.h
> b/ShellPkg/Application/Shell/ShellParametersProtocol.h
> index 2fd8f8c..926f362 100644
> --- a/ShellPkg/Application/Shell/ShellParametersProtocol.h
> +++ b/ShellPkg/Application/Shell/ShellParametersProtocol.h
> @@ -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
>    );
> @@ -162,9 +172,11 @@ RestoreStdInStdOutStdErr (
>    parameters for inclusion in EFI_SHELL_PARAMETERS_PROTOCOL.  this
> supports space
>    delimited and quote surrounded parameter definition.
> 
> -  @param[in] CommandLine         String of command line to parse
> -  @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
> +  @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
> 
>    @return EFI_SUCCESS           the operation was sucessful
>    @return EFI_OUT_OF_RESOURCES  a memory allocation failed.
> @@ -173,8 +185,9 @@ EFI_STATUS
>  EFIAPI
>  ParseCommandLineToArgs(
>    IN CONST CHAR16 *CommandLine,
> -  IN OUT CHAR16 ***Argv,
> -  IN OUT UINTN *Argc
> +  IN BOOLEAN      StripQuotation,
> +  IN OUT CHAR16   ***Argv,
> +  IN OUT UINTN    *Argc
>    );
> 
>  /**
> @@ -187,10 +200,12 @@ ParseCommandLineToArgs(
>    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, 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
> @@ -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_
> diff --git a/ShellPkg/Application/Shell/ShellProtocol.c
> b/ShellPkg/Application/Shell/ShellProtocol.c
> index fc13595..9c370cc 100644
> --- a/ShellPkg/Application/Shell/ShellProtocol.c
> +++ b/ShellPkg/Application/Shell/ShellProtocol.c
> @@ -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:
> --
> 1.9.5.msysgit.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to