From 0960ba17e596812f211ba334cc6699d45bada328 Mon Sep 17 00:00:00 2001 From: Qiu Shumin Date: Wed, 17 Sep 2014 07:58:31 +0000 Subject: [PATCH] ShellPkg: Remove redundant quotes in file path string for Shell command parameters. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Qiu Shumin Reviewed-by: Jaben Carsey git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16122 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Library/UefiShellLevel2CommandsLib/Cd.c | 7 ++ .../Library/UefiShellLevel2CommandsLib/Cp.c | 73 ++++++++++++------- .../Library/UefiShellLevel2CommandsLib/Mv.c | 13 +++- .../UefiShellLevel2CommandsLib.c | 39 ++++++++++ .../UefiShellLevel2CommandsLib.h | 17 +++++ ShellPkg/Library/UefiShellLib/UefiShellLib.c | 55 +++++++++++++- ShellPkg/Library/UefiShellLib/UefiShellLib.h | 18 +++++ 7 files changed, 192 insertions(+), 30 deletions(-) diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c index aa5a20857f..21976211e6 100644 --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/Cd.c @@ -38,6 +38,7 @@ ShellCommandRunCd ( SHELL_FILE_HANDLE Handle; CONST CHAR16 *Param1; CHAR16 *Param1Copy; + CHAR16* Walker; ProblemParam = NULL; ShellStatus = SHELL_SUCCESS; @@ -96,6 +97,12 @@ ShellCommandRunCd ( } } else { Param1Copy = CatSPrint(NULL, L"%s", Param1, NULL); + for (Walker = Param1Copy; Walker != NULL && *Walker != CHAR_NULL ; Walker++) { + if (*Walker == L'\"') { + CopyMem(Walker, Walker+1, StrSize(Walker) - sizeof(Walker[0])); + } + } + if (Param1Copy != NULL) { Param1Copy = PathCleanUpDirectories(Param1Copy); } diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/Cp.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/Cp.c index 3a00683939..52c1de8a96 100644 --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/Cp.c +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/Cp.c @@ -295,11 +295,13 @@ ValidateAndCopyFiles( CHAR16 *HiiResultOk; CONST EFI_SHELL_FILE_INFO *Node; SHELL_STATUS ShellStatus; + EFI_STATUS Status; CHAR16 *DestPath; VOID *Response; UINTN PathSize; CONST CHAR16 *Cwd; UINTN NewSize; + CHAR16 *CleanFilePathStr; if (Resp == NULL) { Response = NULL; @@ -315,14 +317,25 @@ ValidateAndCopyFiles( ASSERT(FileList != NULL); ASSERT(DestDir != NULL); + + Status = ShellLevel2StripQuotes (DestDir, &CleanFilePathStr); + if (EFI_ERROR (Status)) { + if (Status == EFI_OUT_OF_RESOURCES) { + return SHELL_OUT_OF_RESOURCES; + } else { + return SHELL_INVALID_PARAMETER; + } + } + // // If we are trying to copy multiple files... make sure we got a directory for the target... // - if (EFI_ERROR(ShellIsDirectory(DestDir)) && FileList->Link.ForwardLink != FileList->Link.BackLink) { + if (EFI_ERROR(ShellIsDirectory(CleanFilePathStr)) && FileList->Link.ForwardLink != FileList->Link.BackLink) { // // Error for destination not a directory // - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_DIR), gShellLevel2HiiHandle, DestDir); + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_DIR), gShellLevel2HiiHandle, CleanFilePathStr); + FreePool (CleanFilePathStr); return (SHELL_INVALID_PARAMETER); } for (Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&FileList->Link) @@ -336,7 +349,7 @@ ValidateAndCopyFiles( continue; } - NewSize = StrSize(DestDir); + NewSize = StrSize(CleanFilePathStr); NewSize += StrSize(Node->FullName); NewSize += (Cwd == NULL)? 0 : StrSize(Cwd); if (NewSize > PathSize) { @@ -348,17 +361,19 @@ ValidateAndCopyFiles( // if (!RecursiveMode && !EFI_ERROR(ShellIsDirectory(Node->FullName))) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_CP_DIR_REQ), gShellLevel2HiiHandle); + FreePool (CleanFilePathStr); return (SHELL_INVALID_PARAMETER); } // // make sure got dest as dir if needed // - if (!EFI_ERROR(ShellIsDirectory(Node->FullName)) && EFI_ERROR(ShellIsDirectory(DestDir))) { + if (!EFI_ERROR(ShellIsDirectory(Node->FullName)) && EFI_ERROR(ShellIsDirectory(CleanFilePathStr))) { // // Error for destination not a directory // - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_DIR), gShellLevel2HiiHandle, DestDir); + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NOT_DIR), gShellLevel2HiiHandle, CleanFilePathStr); + FreePool (CleanFilePathStr); return (SHELL_INVALID_PARAMETER); } } @@ -371,6 +386,7 @@ ValidateAndCopyFiles( SHELL_FREE_NON_NULL(DestPath); SHELL_FREE_NON_NULL(HiiOutput); SHELL_FREE_NON_NULL(HiiResultOk); + FreePool (CleanFilePathStr); return (SHELL_OUT_OF_RESOURCES); } @@ -395,26 +411,27 @@ ValidateAndCopyFiles( } if (FileList->Link.ForwardLink == FileList->Link.BackLink // 1 item - && EFI_ERROR(ShellIsDirectory(DestDir)) // not an existing directory + && EFI_ERROR(ShellIsDirectory(CleanFilePathStr)) // not an existing directory ) { - if (StrStr(DestDir, L":") == NULL) { + if (StrStr(CleanFilePathStr, L":") == NULL) { // // simple copy of a single file // if (Cwd != NULL) { StrnCpy(DestPath, Cwd, PathSize/sizeof(CHAR16)-1); } else { - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, DestDir); + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, CleanFilePathStr); + FreePool (CleanFilePathStr); return (SHELL_INVALID_PARAMETER); } - if (DestPath[StrLen(DestPath)-1] != L'\\' && DestDir[0] != L'\\') { + if (DestPath[StrLen(DestPath)-1] != L'\\' && CleanFilePathStr[0] != L'\\') { StrnCat(DestPath, L"\\", PathSize/sizeof(CHAR16) - StrLen(DestPath) -1); - } else if (DestPath[StrLen(DestPath)-1] == L'\\' && DestDir[0] == L'\\') { + } else if (DestPath[StrLen(DestPath)-1] == L'\\' && CleanFilePathStr[0] == L'\\') { ((CHAR16*)DestPath)[StrLen(DestPath)-1] = CHAR_NULL; } - StrnCat(DestPath, DestDir, PathSize/sizeof(CHAR16) - StrLen(DestPath) -1); + StrnCat(DestPath, CleanFilePathStr, PathSize/sizeof(CHAR16) - StrLen(DestPath) -1); } else { - StrnCpy(DestPath, DestDir, PathSize/sizeof(CHAR16) -1); + StrnCpy(DestPath, CleanFilePathStr, PathSize/sizeof(CHAR16) -1); } } else { // @@ -424,50 +441,52 @@ ValidateAndCopyFiles( // // Check for leading slash // - if (DestDir[0] == L'\\') { + if (CleanFilePathStr[0] == L'\\') { // // Copy to the root of CWD // if (Cwd != NULL) { StrnCpy(DestPath, Cwd, PathSize/sizeof(CHAR16) -1); } else { - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, DestDir); + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, CleanFilePathStr); + FreePool(CleanFilePathStr); return (SHELL_INVALID_PARAMETER); } while (PathRemoveLastItem(DestPath)); - StrnCat(DestPath, DestDir+1, PathSize/sizeof(CHAR16) - StrLen(DestPath) -1); + StrnCat(DestPath, CleanFilePathStr+1, PathSize/sizeof(CHAR16) - StrLen(DestPath) -1); StrnCat(DestPath, Node->FileName, PathSize/sizeof(CHAR16) - StrLen(DestPath) -1); - } else if (StrStr(DestDir, L":") == NULL) { + } else if (StrStr(CleanFilePathStr, L":") == NULL) { if (Cwd != NULL) { StrnCpy(DestPath, Cwd, PathSize/sizeof(CHAR16) -1); } else { - ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, DestDir); + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_DIR_NF), gShellLevel2HiiHandle, CleanFilePathStr); + FreePool(CleanFilePathStr); return (SHELL_INVALID_PARAMETER); } - if (DestPath[StrLen(DestPath)-1] != L'\\' && DestDir[0] != L'\\') { + if (DestPath[StrLen(DestPath)-1] != L'\\' && CleanFilePathStr[0] != L'\\') { StrnCat(DestPath, L"\\", PathSize/sizeof(CHAR16) - StrLen(DestPath) -1); - } else if (DestPath[StrLen(DestPath)-1] == L'\\' && DestDir[0] == L'\\') { + } else if (DestPath[StrLen(DestPath)-1] == L'\\' && CleanFilePathStr[0] == L'\\') { ((CHAR16*)DestPath)[StrLen(DestPath)-1] = CHAR_NULL; } - StrnCat(DestPath, DestDir, PathSize/sizeof(CHAR16) - StrLen(DestPath) -1); - if (DestDir[StrLen(DestDir)-1] != L'\\' && Node->FileName[0] != L'\\') { + StrnCat(DestPath, CleanFilePathStr, PathSize/sizeof(CHAR16) - StrLen(DestPath) -1); + if (CleanFilePathStr[StrLen(CleanFilePathStr)-1] != L'\\' && Node->FileName[0] != L'\\') { StrnCat(DestPath, L"\\", PathSize/sizeof(CHAR16) - StrLen(DestPath) -1); - } else if (DestDir[StrLen(DestDir)-1] == L'\\' && Node->FileName[0] == L'\\') { + } else if (CleanFilePathStr[StrLen(CleanFilePathStr)-1] == L'\\' && Node->FileName[0] == L'\\') { ((CHAR16*)DestPath)[StrLen(DestPath)-1] = CHAR_NULL; } StrnCat(DestPath, Node->FileName, PathSize/sizeof(CHAR16) - StrLen(DestPath) -1); } else { - StrnCpy(DestPath, DestDir, PathSize/sizeof(CHAR16) -1); - if (DestDir[StrLen(DestDir)-1] != L'\\' && Node->FileName[0] != L'\\') { + StrnCpy(DestPath, CleanFilePathStr, PathSize/sizeof(CHAR16) -1); + if (CleanFilePathStr[StrLen(CleanFilePathStr)-1] != L'\\' && Node->FileName[0] != L'\\') { StrnCat(DestPath, L"\\", PathSize/sizeof(CHAR16) - StrLen(DestPath) -1); - } else if (DestDir[StrLen(DestDir)-1] == L'\\' && Node->FileName[0] == L'\\') { - ((CHAR16*)DestDir)[StrLen(DestDir)-1] = CHAR_NULL; + } else if (CleanFilePathStr[StrLen(CleanFilePathStr)-1] == L'\\' && Node->FileName[0] == L'\\') { + ((CHAR16*)CleanFilePathStr)[StrLen(CleanFilePathStr)-1] = CHAR_NULL; } StrnCat(DestPath, Node->FileName, PathSize/sizeof(CHAR16) - StrLen(DestPath) -1); } } - + FreePool (CleanFilePathStr); // // Make sure the path exists // diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/Mv.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/Mv.c index f9b83e6fa4..fcf5f657b8 100644 --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/Mv.c +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/Mv.c @@ -270,6 +270,7 @@ ValidateAndMoveFiles( UINTN Length; VOID *Response; SHELL_FILE_HANDLE DestHandle; + CHAR16 *CleanFilePathStr; ASSERT(FileList != NULL); ASSERT(DestDir != NULL); @@ -278,10 +279,20 @@ ValidateAndMoveFiles( Cwd = ShellGetCurrentDir(NULL); Response = *Resp; + Status = ShellLevel2StripQuotes (DestDir, &CleanFilePathStr); + if (EFI_ERROR (Status)) { + if (Status == EFI_OUT_OF_RESOURCES) { + return SHELL_OUT_OF_RESOURCES; + } else { + return SHELL_INVALID_PARAMETER; + } + } + // // Get and validate the destination location // - ShellStatus = GetDestinationLocation(DestDir, &DestPath, Cwd); + ShellStatus = GetDestinationLocation(CleanFilePathStr, &DestPath, Cwd); + FreePool (CleanFilePathStr); if (ShellStatus != SHELL_SUCCESS) { return (ShellStatus); } diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.c index 48b1cf84b8..4ac7e67007 100644 --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.c +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.c @@ -309,3 +309,42 @@ StrniCmp( return (NULL); } + +/** + Cleans off all the quotes in the string. + + @param[in] OriginalString pointer to the string to be cleaned. + @param[out] CleanString The new string with all quotes removed. + Memory allocated in the function and free + by caller. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +EFIAPI +ShellLevel2StripQuotes ( + IN CONST CHAR16 *OriginalString, + OUT CHAR16 **CleanString + ) +{ + CHAR16 *Walker; + + if (OriginalString == NULL || CleanString == NULL) { + return EFI_INVALID_PARAMETER; + } + + *CleanString = AllocateCopyPool (StrSize (OriginalString), OriginalString); + if (*CleanString == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + for (Walker = *CleanString; Walker != NULL && *Walker != CHAR_NULL ; Walker++) { + if (*Walker == L'\"') { + CopyMem(Walker, Walker+1, StrSize(Walker) - sizeof(Walker[0])); + } + } + + return EFI_SUCCESS; +} + + diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.h b/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.h index 8abf7e02a8..d6f23187be 100644 --- a/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.h +++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.h @@ -300,6 +300,23 @@ StrniCmp( IN CONST UINTN Count ); +/** + Cleans off all the quotes in the string. + + @param[in] OriginalString pointer to the string to be cleaned. + @param[out] CleanString The new string with all quotes removed. + Memory allocated in the function and free + by caller. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +EFIAPI +ShellLevel2StripQuotes ( + IN CONST CHAR16 *OriginalString, + OUT CHAR16 **CleanString + ); + /** Function for 'Vol' command. diff --git a/ShellPkg/Library/UefiShellLib/UefiShellLib.c b/ShellPkg/Library/UefiShellLib/UefiShellLib.c index 819c9f03ac..dc36db0349 100644 --- a/ShellPkg/Library/UefiShellLib/UefiShellLib.c +++ b/ShellPkg/Library/UefiShellLib/UefiShellLib.c @@ -1494,6 +1494,7 @@ ShellOpenFileMetaArg ( { EFI_STATUS Status; LIST_ENTRY mOldStyleFileList; + CHAR16 *CleanFilePathStr; // // ASSERT that Arg and ListHead are not NULL @@ -1501,6 +1502,11 @@ ShellOpenFileMetaArg ( ASSERT(Arg != NULL); ASSERT(ListHead != NULL); + Status = InternalShellStripQuotes (Arg, &CleanFilePathStr); + if (EFI_ERROR (Status)) { + return Status; + } + // // Check for UEFI Shell 2.0 protocols // @@ -1508,11 +1514,12 @@ ShellOpenFileMetaArg ( if (*ListHead == NULL) { *ListHead = (EFI_SHELL_FILE_INFO*)AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO)); if (*ListHead == NULL) { + FreePool(CleanFilePathStr); return (EFI_OUT_OF_RESOURCES); } InitializeListHead(&((*ListHead)->Link)); } - Status = gEfiShellProtocol->OpenFileList(Arg, + Status = gEfiShellProtocol->OpenFileList(CleanFilePathStr, OpenMode, ListHead); if (EFI_ERROR(Status)) { @@ -1522,9 +1529,11 @@ ShellOpenFileMetaArg ( } if (*ListHead != NULL && IsListEmpty(&(*ListHead)->Link)) { FreePool(*ListHead); + FreePool(CleanFilePathStr); *ListHead = NULL; return (EFI_NOT_FOUND); } + FreePool(CleanFilePathStr); return (Status); } @@ -1540,15 +1549,17 @@ ShellOpenFileMetaArg ( // // Get the EFI Shell list of files // - Status = mEfiShellEnvironment2->FileMetaArg(Arg, &mOldStyleFileList); + Status = mEfiShellEnvironment2->FileMetaArg(CleanFilePathStr, &mOldStyleFileList); if (EFI_ERROR(Status)) { *ListHead = NULL; + FreePool(CleanFilePathStr); return (Status); } if (*ListHead == NULL) { *ListHead = (EFI_SHELL_FILE_INFO *)AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO)); if (*ListHead == NULL) { + FreePool(CleanFilePathStr); return (EFI_OUT_OF_RESOURCES); } InitializeListHead(&((*ListHead)->Link)); @@ -1569,9 +1580,11 @@ ShellOpenFileMetaArg ( *ListHead = NULL; Status = EFI_NOT_FOUND; } + FreePool(CleanFilePathStr); return (Status); } + FreePool(CleanFilePathStr); return (EFI_UNSUPPORTED); } /** @@ -4240,3 +4253,41 @@ ShellDeleteFileByName( return(Status); } + +/** + Cleans off all the quotes in the string. + + @param[in] OriginalString pointer to the string to be cleaned. + @param[out] CleanString The new string with all quotes removed. + Memory allocated in the function and free + by caller. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +EFIAPI +InternalShellStripQuotes ( + IN CONST CHAR16 *OriginalString, + OUT CHAR16 **CleanString + ) +{ + CHAR16 *Walker; + + if (OriginalString == NULL || CleanString == NULL) { + return EFI_INVALID_PARAMETER; + } + + *CleanString = AllocateCopyPool (StrSize (OriginalString), OriginalString); + if (*CleanString == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + for (Walker = *CleanString; Walker != NULL && *Walker != CHAR_NULL ; Walker++) { + if (*Walker == L'\"') { + CopyMem(Walker, Walker+1, StrSize(Walker) - sizeof(Walker[0])); + } + } + + return EFI_SUCCESS; +} + diff --git a/ShellPkg/Library/UefiShellLib/UefiShellLib.h b/ShellPkg/Library/UefiShellLib/UefiShellLib.h index 32f1c6596d..c70e6cb91e 100644 --- a/ShellPkg/Library/UefiShellLib/UefiShellLib.h +++ b/ShellPkg/Library/UefiShellLib/UefiShellLib.h @@ -72,5 +72,23 @@ InternalShellIsHexOrDecimalNumber ( IN CONST BOOLEAN StopAtSpace ); +/** + Cleans off all the quotes in the string. + + @param[in] OriginalString pointer to the string to be cleaned. + @param[out] CleanString The new string with all quotes removed. + Memory allocated in the function and free + by caller. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +EFIAPI +InternalShellStripQuotes ( + IN CONST CHAR16 *OriginalString, + OUT CHAR16 **CleanString + ); + + #endif -- 2.39.2