]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellLevel2CommandsLib/TimeDate.c
pointer verification (not NULL) and buffer overrun fixes.
[mirror_edk2.git] / ShellPkg / Library / UefiShellLevel2CommandsLib / TimeDate.c
index c8de9cf066e4d1e59197892312136b43aec39282..780b39e2fd7cdd8183085b274df21c2fd6bbd70e 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Main file for time, timezone, and date shell level 2 and shell level 3 functions.\r
 \r
-  Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2009 - 2011, 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
 \r
 #include "UefiShellLevel2CommandsLib.h"\r
 \r
-INT16\r
-EFIAPI\r
-AbsVal(\r
-  INT16 v\r
-  )\r
-{\r
-  if (v>0) {\r
-    return (v);\r
-  }\r
-  return ((INT16)(-v));\r
-}\r
+/**\r
+  Determine if String is a valid representation for a time or date.\r
+\r
+  @param[in] String     The pointer to the string to test.\r
+  @param[in] Char       The delimeter character.\r
+  @param[in] Min        The minimum value allowed.\r
+  @param[in] Max        The maximum value allowed.\r
+  @param[in] MinusOk    Whether negative numbers are permitted.\r
 \r
+  @retval TRUE    String is a valid representation.\r
+  @retval FALSE   String is invalid.\r
+**/\r
 BOOLEAN\r
 EFIAPI\r
 InternalIsTimeLikeString (\r
@@ -75,6 +75,16 @@ InternalIsTimeLikeString (
   return (TRUE);\r
 }\r
 \r
+/**\r
+  Verify that the DateString is valid and if so set that as the current \r
+  date.\r
+\r
+  @param[in] DateString     The pointer to a string representation of the date.\r
+\r
+  @retval SHELL_INVALID_PARAMETER   DateString was NULL.\r
+  @retval SHELL_INVALID_PARAMETER   DateString was mis-formatted.\r
+  @retval SHELL_SUCCESS             The operation was successful.\r
+**/\r
 SHELL_STATUS\r
 EFIAPI\r
 CheckAndSetDate (\r
@@ -83,7 +93,9 @@ CheckAndSetDate (
 {\r
   EFI_TIME      TheTime;\r
   EFI_STATUS    Status;\r
-  CONST CHAR16  *Walker;\r
+  CHAR16        *DateStringCopy;\r
+  CHAR16        *Walker;\r
+  CHAR16        *Walker1;\r
 \r
   if (!InternalIsTimeLikeString(DateString, L'/', 2, 2, FALSE)) {\r
     return (SHELL_INVALID_PARAMETER);\r
@@ -92,25 +104,41 @@ CheckAndSetDate (
   Status = gRT->GetTime(&TheTime, NULL);\r
   ASSERT_EFI_ERROR(Status);\r
 \r
-  Walker = DateString;\r
+  DateStringCopy = NULL;\r
+  DateStringCopy = StrnCatGrow(&DateStringCopy, NULL, DateString, 0);\r
+  if (DateStringCopy == NULL) {\r
+    return (SHELL_OUT_OF_RESOURCES);\r
+  }\r
+  Walker = DateStringCopy;\r
 \r
   TheTime.Month = 0xFF;\r
   TheTime.Day   = 0xFF;\r
   TheTime.Year  = 0xFFFF;\r
 \r
-  TheTime.Month = (UINT8)StrDecimalToUintn (Walker);\r
-  Walker = StrStr(Walker, L"/");\r
-  if (Walker != NULL && *Walker == L'/') {\r
-    Walker = Walker + 1;\r
+  Walker1 = StrStr(Walker, L"/");\r
+  if (Walker1 != NULL && *Walker1 == L'/') {\r
+    *Walker1 = CHAR_NULL;\r
+  }\r
+\r
+  TheTime.Month = (UINT8)ShellStrToUintn (Walker);\r
+  if (Walker1 != NULL) {\r
+    Walker = Walker1 + 1;\r
+  }\r
+  Walker1 = Walker!=NULL?StrStr(Walker, L"/"):NULL;\r
+  if (Walker1 != NULL && *Walker1 == L'/') {\r
+    *Walker1 = CHAR_NULL;\r
   }\r
   if (Walker != NULL && Walker[0] != CHAR_NULL) {\r
-    TheTime.Day = (UINT8)StrDecimalToUintn (Walker);\r
-    Walker = StrStr(Walker, L"/");\r
-    if (Walker != NULL && *Walker == L'/') {\r
-      Walker = Walker + 1;\r
+    TheTime.Day = (UINT8)ShellStrToUintn (Walker);\r
+    if (Walker1 != NULL) {\r
+      Walker = Walker1 + 1;\r
+    }\r
+    Walker1 = Walker!=NULL?StrStr(Walker, L"/"):NULL;\r
+    if (Walker1 != NULL && *Walker1 == L'/') {\r
+      *Walker1 = CHAR_NULL;\r
     }\r
     if (Walker != NULL && Walker[0] != CHAR_NULL) {\r
-      TheTime.Year = (UINT16)StrDecimalToUintn (Walker);\r
+      TheTime.Year = (UINT16)ShellStrToUintn (Walker);\r
     }\r
   }\r
 \r
@@ -241,6 +269,18 @@ STATIC CONST SHELL_PARAM_ITEM TimeParamList3[] = {
   {NULL, TypeMax}\r
   };\r
 \r
+/**\r
+  Verify that the TimeString is valid and if so set that as the current \r
+  time.\r
+\r
+  @param[in] TimeString     The pointer to a string representation of the time.\r
+  @param[in] Tz             The value to set for TimeZone.\r
+  @param[in] Daylight       The value to set for Daylight.\r
+\r
+  @retval SHELL_INVALID_PARAMETER   TimeString was NULL.\r
+  @retval SHELL_INVALID_PARAMETER   TimeString was mis-formatted.\r
+  @retval SHELL_SUCCESS             The operation was successful.\r
+**/\r
 SHELL_STATUS\r
 EFIAPI\r
 CheckAndSetTime (\r
@@ -251,43 +291,58 @@ CheckAndSetTime (
 {\r
   EFI_TIME      TheTime;\r
   EFI_STATUS    Status;\r
-  CONST CHAR16  *Walker;\r
+  CHAR16        *TimeStringCopy;\r
+  CHAR16        *Walker1;\r
+  CHAR16        *Walker2;\r
 \r
   if (TimeString != NULL && !InternalIsTimeLikeString(TimeString, L':', 1, 2, FALSE)) {\r
     return (SHELL_INVALID_PARAMETER);\r
   }\r
+  if (((Daylight & (EFI_TIME_IN_DAYLIGHT|EFI_TIME_ADJUST_DAYLIGHT)) != Daylight)) {\r
+    return (SHELL_INVALID_PARAMETER);\r
+  }\r
 \r
   Status = gRT->GetTime(&TheTime, NULL);\r
   ASSERT_EFI_ERROR(Status);\r
 \r
   if (TimeString != NULL) {\r
-    Walker          = TimeString;\r
+    TimeStringCopy = NULL;\r
+    TimeStringCopy = StrnCatGrow(&TimeStringCopy, NULL, TimeString, 0);\r
+    Walker1          = TimeStringCopy;\r
     TheTime.Hour    = 0xFF;\r
     TheTime.Minute  = 0xFF;\r
 \r
-    TheTime.Hour    = (UINT8)StrDecimalToUintn (Walker);\r
-    Walker          = StrStr(Walker, L":");\r
-    if (Walker != NULL && *Walker == L':') {\r
-      Walker = Walker + 1;\r
+    Walker2          = Walker1!=NULL?StrStr(Walker1, L":"):NULL;\r
+    if (Walker2 != NULL && *Walker2 == L':') {\r
+      *Walker2 = CHAR_NULL;\r
     }\r
-    if (Walker != NULL && Walker[0] != CHAR_NULL) {\r
-      TheTime.Minute = (UINT8)StrDecimalToUintn (Walker);\r
-      Walker = StrStr(Walker, L":");\r
-      if (Walker != NULL && *Walker == L':') {\r
-        Walker = Walker + 1;\r
+    TheTime.Hour    = (UINT8)ShellStrToUintn (Walker1);\r
+    if (Walker2 != NULL) {\r
+      Walker1 = Walker2 + 1;\r
+    }\r
+    Walker2          = Walker1!=NULL?StrStr(Walker1, L":"):NULL;\r
+    if (Walker2 != NULL && *Walker2 == L':') {\r
+      *Walker2 = CHAR_NULL;\r
+    }\r
+    if (Walker1 != NULL && Walker1[0] != CHAR_NULL) {\r
+      TheTime.Minute = (UINT8)ShellStrToUintn (Walker1);\r
+      if (Walker2 != NULL) {\r
+        Walker1 = Walker2 + 1;\r
       }\r
-      if (Walker != NULL && Walker[0] != CHAR_NULL) {\r
-        TheTime.Second = (UINT8)StrDecimalToUintn (Walker);\r
+      if (Walker1 != NULL && Walker1[0] != CHAR_NULL) {\r
+        TheTime.Second = (UINT8)ShellStrToUintn (Walker1);\r
       }\r
     }\r
+    SHELL_FREE_NON_NULL(TimeStringCopy);\r
   }\r
 \r
-  if ((Tz >= -1440 && Tz <= 1440)||(Tz == 2047)) {\r
+\r
+  if ((Tz >= -1440 && Tz <= 1440)||(Tz == 0x7FF)) {\r
     TheTime.TimeZone = Tz;\r
   }\r
-  if (Daylight <= 3 && Daylight != 2) {\r
-    TheTime.Daylight = Daylight;\r
-  }\r
+\r
+  TheTime.Daylight = Daylight;\r
+\r
   Status = gRT->SetTime(&TheTime);\r
 \r
   if (!EFI_ERROR(Status)){\r
@@ -376,7 +431,7 @@ ShellCommandRunTime (
         if (TheTime.TimeZone == 2047) {\r
           TzMinutes = 0;\r
         } else {\r
-          TzMinutes = AbsVal(TheTime.TimeZone) % 60;\r
+          TzMinutes = (ABS(TheTime.TimeZone)) % 60;\r
         }\r
 \r
         ShellPrintHiiEx (\r
@@ -389,7 +444,7 @@ ShellCommandRunTime (
           TheTime.Minute,\r
           TheTime.Second,\r
           TheTime.TimeZone==2047?L" ":(TheTime.TimeZone > 0?L"-":L"+"),\r
-          TheTime.TimeZone==2047?0:AbsVal(TheTime.TimeZone) / 60,\r
+          TheTime.TimeZone==2047?0:(ABS(TheTime.TimeZone)) / 60,\r
           TzMinutes\r
          );\r
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_CRLF), gShellLevel2HiiHandle);\r
@@ -397,7 +452,7 @@ ShellCommandRunTime (
         if (TheTime.TimeZone == 2047) {\r
           TzMinutes = 0;\r
         } else {\r
-          TzMinutes = AbsVal(TheTime.TimeZone) % 60;\r
+          TzMinutes = (ABS(TheTime.TimeZone)) % 60;\r
         }\r
 \r
         ShellPrintHiiEx (\r
@@ -410,18 +465,21 @@ ShellCommandRunTime (
           TheTime.Minute,\r
           TheTime.Second,\r
           TheTime.TimeZone==2047?L" ":(TheTime.TimeZone > 0?L"-":L"+"),\r
-          TheTime.TimeZone==2047?0:AbsVal(TheTime.TimeZone) / 60,\r
+          TheTime.TimeZone==2047?0:(ABS(TheTime.TimeZone)) / 60,\r
           TzMinutes\r
          );\r
           switch (TheTime.Daylight) {\r
             case 0:\r
-              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TIME_DSTNA), gShellLevel2HiiHandle);\r
+              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TIME_DST0), gShellLevel2HiiHandle);\r
               break;\r
             case EFI_TIME_ADJUST_DAYLIGHT:\r
-              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TIME_DSTST), gShellLevel2HiiHandle);\r
+              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TIME_DST1), gShellLevel2HiiHandle);\r
               break;\r
             case EFI_TIME_IN_DAYLIGHT:\r
-              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TIME_DSTDT), gShellLevel2HiiHandle);\r
+              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TIME_DST2), gShellLevel2HiiHandle);\r
+              break;\r
+            case EFI_TIME_IN_DAYLIGHT|EFI_TIME_ADJUST_DAYLIGHT:\r
+              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_TIME_DST3), gShellLevel2HiiHandle);\r
               break;\r
             default:\r
               ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_UEFI_FUNC_ERROR), gShellLevel2HiiHandle, L"gRT->GetTime", L"TheTime.Daylight", TheTime.Daylight);\r
@@ -436,12 +494,12 @@ ShellCommandRunTime (
           //\r
           if ((TempLocation = ShellCommandLineGetValue(Package, L"-tz")) != NULL) {\r
             if (TempLocation[0] == L'-') {\r
-              Tz = (INT16)(0 - StrDecimalToUintn(++TempLocation));\r
+              Tz = (INT16)(0 - ShellStrToUintn(++TempLocation));\r
             } else {\r
-              Tz = (INT16)StrDecimalToUintn(TempLocation);\r
+              Tz = (INT16)ShellStrToUintn(TempLocation);\r
             }\r
             if (!(Tz >= -1440 && Tz <= 1440) && Tz != 2047) {\r
-              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"-d");\r
+              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellLevel2HiiHandle, L"-tz");\r
               ShellStatus = SHELL_INVALID_PARAMETER;\r
             }\r
           } else {\r
@@ -452,9 +510,9 @@ ShellCommandRunTime (
           }\r
           TempLocation = ShellCommandLineGetValue(Package, L"-d");\r
           if (TempLocation != NULL) {\r
-            Daylight = (UINT8)StrDecimalToUintn(TempLocation);\r
+            Daylight = (UINT8)ShellStrToUintn(TempLocation);\r
             if (Daylight != 0 && Daylight != 1 && Daylight != 3) {\r
-              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"-d");\r
+              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellLevel2HiiHandle, L"-d");\r
               ShellStatus = SHELL_INVALID_PARAMETER;\r
             }\r
           } else {\r
@@ -539,8 +597,18 @@ STATIC CONST SHELL_PARAM_ITEM TimeZoneParamList3[] = {
     {-720 , STRING_TOKEN (STR_TIMEZONE_P12)},\r
     {-780 , STRING_TOKEN (STR_TIMEZONE_P13)},\r
     {-840 , STRING_TOKEN (STR_TIMEZONE_P14)}\r
-  };\r
+};\r
+\r
+/**\r
+  Verify that the TimeZoneString is valid and if so set that as the current \r
+  timezone.\r
 \r
+  @param[in] TimeZoneString     The pointer to a string representation of the timezone.\r
+\r
+  @retval SHELL_INVALID_PARAMETER   TimeZoneString was NULL.\r
+  @retval SHELL_INVALID_PARAMETER   TimeZoneString was mis-formatted.\r
+  @retval SHELL_SUCCESS             The operation was successful.\r
+**/\r
 SHELL_STATUS\r
 EFIAPI\r
 CheckAndSetTimeZone (\r
@@ -549,7 +617,9 @@ CheckAndSetTimeZone (
 {\r
   EFI_TIME      TheTime;\r
   EFI_STATUS    Status;\r
-  CONST CHAR16  *Walker;\r
+  CHAR16        *TimeZoneCopy;\r
+  CHAR16        *Walker;\r
+  CHAR16        *Walker2;\r
   UINTN         LoopVar;\r
 \r
   if (TimeZoneString == NULL) {\r
@@ -563,21 +633,26 @@ CheckAndSetTimeZone (
   Status = gRT->GetTime(&TheTime, NULL);\r
   ASSERT_EFI_ERROR(Status);\r
 \r
-  Walker = TimeZoneString;\r
+  TimeZoneCopy = NULL;\r
+  TimeZoneCopy = StrnCatGrow(&TimeZoneCopy, NULL, TimeZoneString, 0);\r
+  Walker = TimeZoneCopy;\r
+  Walker2 = StrStr(Walker, L":");\r
+  if (Walker2 != NULL && *Walker2 == L':') {\r
+    *Walker2 = CHAR_NULL;\r
+  }\r
   if (*Walker == L'-') {\r
-    TheTime.TimeZone = (INT16)((StrDecimalToUintn (++Walker)) * 60);\r
+    TheTime.TimeZone = (INT16)((ShellStrToUintn (++Walker)) * 60);\r
   } else {\r
-    TheTime.TimeZone = (INT16)((StrDecimalToUintn (Walker)) * -60);\r
+    TheTime.TimeZone = (INT16)((ShellStrToUintn (Walker)) * -60);\r
   }\r
-  Walker = StrStr(Walker, L":");\r
-  if (Walker != NULL && *Walker == L':') {\r
-    Walker = Walker + 1;\r
+  if (Walker2 != NULL) {\r
+    Walker = Walker2 + 1;\r
   }\r
   if (Walker != NULL && Walker[0] != CHAR_NULL) {\r
     if (TheTime.TimeZone < 0) {\r
-      TheTime.TimeZone = (INT16)(TheTime.TimeZone - (UINT8)StrDecimalToUintn (Walker));\r
+      TheTime.TimeZone = (INT16)(TheTime.TimeZone - (UINT8)ShellStrToUintn (Walker));\r
     } else {\r
-      TheTime.TimeZone = (INT16)(TheTime.TimeZone + (UINT8)StrDecimalToUintn (Walker));\r
+      TheTime.TimeZone = (INT16)(TheTime.TimeZone + (UINT8)ShellStrToUintn (Walker));\r
     }\r
   }\r
 \r
@@ -593,6 +668,8 @@ CheckAndSetTimeZone (
     }\r
   }\r
 \r
+  FreePool(TimeZoneCopy);\r
+\r
   if (!EFI_ERROR(Status)){\r
     return (SHELL_SUCCESS);\r
   }\r
@@ -716,7 +793,7 @@ ShellCommandRunTimeZone (
               if (TheTime.TimeZone == 2047) {\r
                 TzMinutes = 0;\r
               } else {\r
-                TzMinutes = AbsVal(TheTime.TimeZone) % 60;\r
+                TzMinutes = (ABS(TheTime.TimeZone)) % 60;\r
               }\r
 \r
               ShellPrintHiiEx (\r
@@ -726,7 +803,7 @@ ShellCommandRunTimeZone (
                 STRING_TOKEN(STR_TIMEZONE_SIMPLE),\r
                 gShellLevel2HiiHandle,\r
                 TheTime.TimeZone==2047?0:(TheTime.TimeZone > 0?L"-":L"+"),\r
-                TheTime.TimeZone==2047?0:AbsVal(TheTime.TimeZone) / 60,\r
+                TheTime.TimeZone==2047?0:(ABS(TheTime.TimeZone)) / 60,\r
                 TzMinutes);\r
             }\r
             Found = TRUE;\r
@@ -740,7 +817,7 @@ ShellCommandRunTimeZone (
           if (TheTime.TimeZone == 2047) {\r
             TzMinutes = 0;\r
           } else {\r
-            TzMinutes = AbsVal(TheTime.TimeZone) % 60;\r
+            TzMinutes = (ABS(TheTime.TimeZone)) % 60;\r
           }\r
           ShellPrintHiiEx (\r
             -1,\r
@@ -749,7 +826,7 @@ ShellCommandRunTimeZone (
             STRING_TOKEN(STR_TIMEZONE_SIMPLE),\r
             gShellLevel2HiiHandle,\r
             TheTime.TimeZone==2047?0:(TheTime.TimeZone > 0?L"-":L"+"),\r
-            TheTime.TimeZone==2047?0:AbsVal(TheTime.TimeZone) / 60,\r
+            TheTime.TimeZone==2047?0:(ABS(TheTime.TimeZone)) / 60,\r
             TzMinutes);\r
           if (ShellCommandLineGetFlag(Package, L"-f")) {\r
             ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN(STR_TIMEZONE_NI), gShellLevel2HiiHandle);\r