]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellLib/UefiShellLib.c
ShellPkg: fix string to number conversion with "0 "
[mirror_edk2.git] / ShellPkg / Library / UefiShellLib / UefiShellLib.c
index 4a4c40a92810a3bb52d2ed9cf0811ad0d264be3b..0bf034f682b724a4ca8cfb63ccbb1ac0ac10481e 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Provides interface to shell functionality for shell commands and applications.\r
 \r
-  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
@@ -15,6 +15,7 @@
 #include "UefiShellLib.h"\r
 #include <ShellBase.h>\r
 #include <Library/SortLib.h>\r
+#include <Library/BaseLib.h>\r
 \r
 #define FIND_XXXXX_FILE_BUFFER_SIZE (SIZE_OF_EFI_FILE_INFO + MAX_FILE_NAME_LEN)\r
 \r
@@ -671,6 +672,7 @@ ShellOpenFileByName(
   EFI_DEVICE_PATH_PROTOCOL      *FilePath;\r
   EFI_STATUS                    Status;\r
   EFI_FILE_INFO                 *FileInfo;\r
+  CHAR16                        *FileNameCopy;\r
 \r
   //\r
   // ASSERT if FileName is NULL\r
@@ -682,11 +684,32 @@ ShellOpenFileByName(
   }\r
 \r
   if (gEfiShellProtocol != NULL) {\r
-    if ((OpenMode & EFI_FILE_MODE_CREATE) == EFI_FILE_MODE_CREATE && (Attributes & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) {\r
-      return ShellCreateDirectory(FileName, FileHandle);\r
+    if ((OpenMode & EFI_FILE_MODE_CREATE) == EFI_FILE_MODE_CREATE) {\r
+\r
+      //\r
+      // Create only a directory\r
+      //\r
+      if ((Attributes & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) {\r
+        return ShellCreateDirectory(FileName, FileHandle);\r
+      }\r
+\r
+      //\r
+      // Create the directory to create the file in\r
+      //\r
+      FileNameCopy = AllocateCopyPool (StrSize (FileName), FileName);\r
+      if (FileName == NULL) {\r
+        return (EFI_OUT_OF_RESOURCES);\r
+      }\r
+      PathCleanUpDirectories (FileNameCopy);\r
+      if (PathRemoveLastItem (FileNameCopy)) {\r
+        ShellCreateDirectory (FileNameCopy, FileHandle);\r
+        ShellCloseFile (FileHandle);\r
+      }\r
+      SHELL_FREE_NON_NULL (FileNameCopy);\r
     }\r
+\r
     //\r
-    // Use UEFI Shell 2.0 method\r
+    // Use UEFI Shell 2.0 method to create the file\r
     //\r
     Status = gEfiShellProtocol->OpenFileByName(FileName,\r
                                                FileHandle,\r
@@ -1690,8 +1713,8 @@ ShellFindFilePath (
     if (TestPath == NULL) {\r
       return (NULL);\r
     }\r
-    StrnCpy(TestPath, Path, Size/sizeof(CHAR16) - 1);\r
-    StrnCat(TestPath, FileName, Size/sizeof(CHAR16) - 1 - StrLen(TestPath));\r
+    StrCpyS(TestPath, Size/sizeof(CHAR16), Path);\r
+    StrCatS(TestPath, Size/sizeof(CHAR16), FileName);\r
     Status = ShellOpenFileByName(TestPath, &Handle, EFI_FILE_MODE_READ, 0);\r
     if (!EFI_ERROR(Status)){\r
       if (FileHandleIsDirectory(Handle) != EFI_SUCCESS) {\r
@@ -1723,12 +1746,12 @@ ShellFindFilePath (
           *TempChar = CHAR_NULL;\r
         }\r
         if (TestPath[StrLen(TestPath)-1] != L'\\') {\r
-          StrnCat(TestPath, L"\\", Size/sizeof(CHAR16) - 1 - StrLen(TestPath));\r
+          StrCatS(TestPath, Size/sizeof(CHAR16), L"\\");\r
         }\r
         if (FileName[0] == L'\\') {\r
           FileName++;\r
         }\r
-        StrnCat(TestPath, FileName, Size/sizeof(CHAR16) - 1 - StrLen(TestPath));\r
+        StrCatS(TestPath, Size/sizeof(CHAR16), FileName);\r
         if (StrStr(Walker, L";") != NULL) {\r
           Walker = StrStr(Walker, L";") + 1;\r
         } else {\r
@@ -1797,9 +1820,9 @@ ShellFindFilePathEx (
     return (NULL);\r
   }\r
   for (ExtensionWalker = FileExtension, TempChar2 = (CHAR16*)FileExtension;  TempChar2 != NULL ; ExtensionWalker = TempChar2 + 1){\r
-    StrnCpy(TestPath, FileName, Size/sizeof(CHAR16) - 1);\r
+    StrCpyS(TestPath, Size/sizeof(CHAR16), FileName);\r
     if (ExtensionWalker != NULL) {\r
-      StrnCat(TestPath, ExtensionWalker, Size/sizeof(CHAR16) - 1 - StrLen(TestPath));\r
+      StrCatS(TestPath, Size/sizeof(CHAR16), ExtensionWalker);\r
     }\r
     TempChar = StrStr(TestPath, L";");\r
     if (TempChar != NULL) {\r
@@ -2078,41 +2101,30 @@ InternalCommandLineParse (
           ASSERT(GetItemValue == 0);\r
           break;\r
       }\r
-    } else if (GetItemValue != 0 && !InternalIsFlag(Argv[LoopCounter], AlwaysAllowNumbers, CurrentItemPackage->Type == TypeTimeValue)) {\r
-      ASSERT(CurrentItemPackage != NULL);\r
+    } else if (GetItemValue != 0 && CurrentItemPackage != NULL && !InternalIsFlag(Argv[LoopCounter], AlwaysAllowNumbers, (BOOLEAN)(CurrentItemPackage->Type == TypeTimeValue))) {\r
       //\r
       // get the item VALUE for a previous flag\r
       //\r
-      if (StrStr(Argv[LoopCounter], L" ") == NULL) {\r
-        CurrentValueSize = ValueSize + StrSize(Argv[LoopCounter]) + sizeof(CHAR16);\r
-        CurrentItemPackage->Value = ReallocatePool(ValueSize, CurrentValueSize, CurrentItemPackage->Value);\r
-        ASSERT(CurrentItemPackage->Value != NULL);\r
-        if (ValueSize == 0) {\r
-          StrnCpy(CurrentItemPackage->Value, Argv[LoopCounter], CurrentValueSize/sizeof(CHAR16) - 1);\r
-        } else {\r
-          StrnCat(CurrentItemPackage->Value, L" ", CurrentValueSize/sizeof(CHAR16) - 1 - StrLen(CurrentItemPackage->Value));\r
-          StrnCat(CurrentItemPackage->Value, Argv[LoopCounter], CurrentValueSize/sizeof(CHAR16) - 1 - StrLen(CurrentItemPackage->Value));\r
-        }\r
-        ValueSize += StrSize(Argv[LoopCounter]) + sizeof(CHAR16);\r
+      CurrentValueSize = ValueSize + StrSize(Argv[LoopCounter]) + sizeof(CHAR16);\r
+      CurrentItemPackage->Value = ReallocatePool(ValueSize, CurrentValueSize, CurrentItemPackage->Value);\r
+      ASSERT(CurrentItemPackage->Value != NULL);\r
+      if (ValueSize == 0) {\r
+        StrCpyS( CurrentItemPackage->Value, \r
+                  CurrentValueSize/sizeof(CHAR16), \r
+                  Argv[LoopCounter]\r
+                  );\r
       } else {\r
-        //\r
-        // the parameter has spaces.  must be quoted.\r
-        //\r
-        CurrentValueSize =  ValueSize + StrSize(Argv[LoopCounter]) + sizeof(CHAR16) + sizeof(CHAR16) + sizeof(CHAR16);\r
-        CurrentItemPackage->Value = ReallocatePool(ValueSize, CurrentValueSize, CurrentItemPackage->Value);\r
-        ASSERT(CurrentItemPackage->Value != NULL);\r
-        if (ValueSize == 0) {\r
-          StrnCpy(CurrentItemPackage->Value, L"\"", CurrentValueSize/sizeof(CHAR16) - 1);\r
-          StrnCat(CurrentItemPackage->Value, Argv[LoopCounter], CurrentValueSize/sizeof(CHAR16) - 1 - StrLen(CurrentItemPackage->Value));\r
-          StrnCat(CurrentItemPackage->Value, L"\"", CurrentValueSize/sizeof(CHAR16) - 1 - StrLen(CurrentItemPackage->Value));\r
-        } else {\r
-          StrnCat(CurrentItemPackage->Value, L" ", CurrentValueSize/sizeof(CHAR16) - 1 - StrLen(CurrentItemPackage->Value));\r
-          StrnCat(CurrentItemPackage->Value, L"\"", CurrentValueSize/sizeof(CHAR16) - 1 - StrLen(CurrentItemPackage->Value));\r
-          StrnCat(CurrentItemPackage->Value, Argv[LoopCounter], CurrentValueSize/sizeof(CHAR16) - 1 - StrLen(CurrentItemPackage->Value));\r
-          StrnCat(CurrentItemPackage->Value, L"\"", CurrentValueSize/sizeof(CHAR16) - 1 - StrLen(CurrentItemPackage->Value));\r
-       }\r
-        ValueSize += StrSize(Argv[LoopCounter]) + sizeof(CHAR16);\r
+        StrCatS( CurrentItemPackage->Value, \r
+                  CurrentValueSize/sizeof(CHAR16), \r
+                  L" "\r
+                  );\r
+        StrCatS( CurrentItemPackage->Value, \r
+                  CurrentValueSize/sizeof(CHAR16), \r
+                  Argv[LoopCounter]\r
+                  );\r
       }\r
+      ValueSize += StrSize(Argv[LoopCounter]) + sizeof(CHAR16);\r
+      \r
       GetItemValue--;\r
       if (GetItemValue == 0) {\r
         InsertHeadList(*CheckPackage, &CurrentItemPackage->Link);\r
@@ -2632,14 +2644,14 @@ ShellCopySearchAndReplace(
         FreePool(Replace);\r
         return (EFI_BUFFER_TOO_SMALL);\r
       }\r
-      StrnCat(NewString, Replace, NewSize/sizeof(CHAR16) - 1 - StrLen(NewString));\r
+      StrCatS(NewString, NewSize/sizeof(CHAR16), Replace);\r
     } else {\r
       Size = StrSize(NewString);\r
       if (Size + sizeof(CHAR16) > NewSize) {\r
         FreePool(Replace);\r
         return (EFI_BUFFER_TOO_SMALL);\r
       }\r
-      StrnCat(NewString, SourceString, 1);\r
+      StrnCatS(NewString, NewSize/sizeof(CHAR16), SourceString, 1);\r
       SourceString++;\r
     }\r
   }\r
@@ -3242,7 +3254,8 @@ StrnCatGrow (
       *CurrentSize = NewSize;\r
     }\r
   } else {\r
-    *Destination = AllocateZeroPool((Count+1)*sizeof(CHAR16));\r
+    NewSize = (Count+1)*sizeof(CHAR16);\r
+    *Destination = AllocateZeroPool(NewSize);\r
   }\r
 \r
   //\r
@@ -3251,7 +3264,9 @@ StrnCatGrow (
   if (*Destination == NULL) {\r
     return (NULL);\r
   }\r
-  return StrnCat(*Destination, Source, Count);\r
+  \r
+  StrnCatS(*Destination, NewSize/sizeof(CHAR16), Source, Count);\r
+  return *Destination;\r
 }\r
 \r
 /**\r
@@ -3714,7 +3729,7 @@ InternalShellHexCharToUintn (
 /**\r
   Convert a Null-terminated Unicode hexadecimal string to a value of type UINT64.\r
 \r
-  This function returns a value of type UINTN by interpreting the contents\r
+  This function returns a value of type UINT64 by interpreting the contents\r
   of the Unicode string specified by String as a hexadecimal number.\r
   The format of the input Unicode string String is:\r
 \r
@@ -3782,16 +3797,16 @@ InternalShellStrHexToUint64 (
   Result = 0;\r
 \r
   //\r
-  // Skip spaces if requested\r
+  // there is a space where there should't be\r
   //\r
-  while (StopAtSpace && *String == L' ') {\r
-    String++;\r
+  if (*String == L' ') {\r
+    return (EFI_INVALID_PARAMETER);\r
   }\r
 \r
   while (ShellIsHexaDecimalDigitCharacter (*String)) {\r
     //\r
     // If the Hex Number represented by String overflows according\r
-    // to the range defined by UINTN, then ASSERT().\r
+    // to the range defined by UINT64, then return EFI_DEVICE_ERROR.\r
     //\r
     if (!(Result <= (RShiftU64((((UINT64) ~0) - InternalShellHexCharToUintn (*String)), 4)))) {\r
 //    if (!(Result <= ((((UINT64) ~0) - InternalShellHexCharToUintn (*String)) >> 4))) {\r
@@ -3874,15 +3889,18 @@ InternalShellStrDecimalToUint64 (
   Result = 0;\r
 \r
   //\r
-  // Skip spaces if requested\r
+  // Stop upon space if requested \r
+  // (if the whole value was 0)\r
   //\r
-  while (StopAtSpace && *String == L' ') {\r
-    String++;\r
+  if (StopAtSpace && *String == L' ') {\r
+    *Value = Result;\r
+    return (EFI_SUCCESS);\r
   }\r
+\r
   while (ShellIsDecimalDigitCharacter (*String)) {\r
     //\r
     // If the number represented by String overflows according\r
-    // to the range defined by UINT64, then ASSERT().\r
+    // to the range defined by UINT64, then return EFI_DEVICE_ERROR.\r
     //\r
 \r
     if (!(Result <= (DivU64x32((((UINT64) ~0) - (*String - L'0')),10)))) {\r