]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkCompatibilityPkg/Compatibility/FrameworkHiiOnUefiHiiThunk/UefiIfrParser.c
Add the missing check for NULL pointer before use it.
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiOnUefiHiiThunk / UefiIfrParser.c
index 52b253a5590295dc5fdf99e21033ed5282f3e2ed..f5480d2cb6b85d131489735c57312fc7d686bf55 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 Parser for IFR binary encoding.\r
 \r
-Copyright (c) 2008, Intel Corporation\r
+Copyright (c) 2008 - 2010, Intel Corporation\r
 All rights reserved. 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
@@ -209,6 +209,7 @@ CreateStorage (
   FORMSET_STORAGE  *Storage;\r
 \r
   Storage = AllocateZeroPool (sizeof (FORMSET_STORAGE));\r
+  ASSERT (Storage != NULL);\r
   Storage->Signature = FORMSET_STORAGE_SIGNATURE;\r
   InsertTailList (&FormSet->StorageListHead, &Storage->Link);\r
 \r
@@ -408,9 +409,14 @@ IsExpressionOpCode (
   )\r
 {\r
   if (((Operand >= EFI_IFR_EQ_ID_VAL_OP) && (Operand <= EFI_IFR_NOT_OP)) ||\r
-      ((Operand >= EFI_IFR_MATCH_OP) && (Operand <= EFI_IFR_SPAN_OP)) ||\r
-      (Operand == EFI_IFR_CATENATE_OP)\r
-     ) {\r
+      ((Operand >= EFI_IFR_MATCH_OP) && (Operand <= EFI_IFR_SET_OP))  ||\r
+      ((Operand >= EFI_IFR_EQUAL_OP) && (Operand <= EFI_IFR_SPAN_OP)) ||\r
+      (Operand == EFI_IFR_CATENATE_OP) ||\r
+      (Operand == EFI_IFR_TO_LOWER_OP) ||\r
+      (Operand == EFI_IFR_TO_UPPER_OP) ||\r
+      (Operand == EFI_IFR_MAP_OP)      ||\r
+      (Operand == EFI_IFR_VERSION_OP)  ||\r
+      (Operand == EFI_IFR_SECURITY_OP)) {\r
     return TRUE;\r
   } else {\r
     return FALSE;\r
@@ -502,12 +508,14 @@ ParseOpCodes (
   UINT8                   OneOfType;\r
   EFI_IFR_ONE_OF          *OneOfOpcode;\r
   HII_THUNK_CONTEXT       *ThunkContext;\r
+  EFI_IFR_FORM_MAP_METHOD *MapMethod;\r
 \r
   mInScopeSubtitle = FALSE;\r
   mInScopeSuppress = FALSE;\r
   mInScopeGrayOut  = FALSE;\r
   CurrentDefault   = NULL;\r
   CurrentOption    = NULL;\r
+  MapMethod        = NULL;\r
   ThunkContext     = UefiHiiHandleToThunkContext ((CONST HII_THUNK_PRIVATE_DATA*) mHiiThunkPrivateData, FormSet->HiiHandle);\r
 \r
   //\r
@@ -549,7 +557,7 @@ ParseOpCodes (
     //\r
     // If scope bit set, push onto scope stack\r
     //\r
-    if (Scope) {\r
+    if (Scope != 0) {\r
       PushScope (Operand);\r
     }\r
 \r
@@ -579,6 +587,7 @@ ParseOpCodes (
       // Create a new Form for this FormSet\r
       //\r
       CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));\r
+      ASSERT (CurrentForm != NULL);\r
       CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;\r
 \r
       InitializeListHead (&CurrentForm->StatementListHead);\r
@@ -592,6 +601,49 @@ ParseOpCodes (
       InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);\r
       break;\r
 \r
+    case EFI_IFR_FORM_MAP_OP:\r
+      //\r
+      // Create a new Form Map for this FormSet\r
+      //\r
+      CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));\r
+      CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;\r
+\r
+      InitializeListHead (&CurrentForm->StatementListHead);\r
+\r
+      CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));\r
+      MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));\r
+\r
+      //\r
+      // FormMap Form must contain at least one Map Method.\r
+      //\r
+      if (((EFI_IFR_OP_HEADER *) OpCodeData)->Length < ((UINTN) (UINT8 *) (MapMethod + 1) - (UINTN) OpCodeData)) {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+\r
+      //\r
+      // Try to find the standard form map method.\r
+      //\r
+      while (((UINTN) (UINT8 *) MapMethod - (UINTN) OpCodeData) < ((EFI_IFR_OP_HEADER *) OpCodeData)->Length) {\r
+        if (CompareGuid ((EFI_GUID *) (VOID *) &MapMethod->MethodIdentifier, &gEfiHiiStandardFormGuid)) {\r
+          CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));\r
+          break;\r
+        }\r
+        MapMethod ++;\r
+      }\r
+      //\r
+      // If the standard form map method is not found, the first map method title will be used.\r
+      //\r
+      if (CurrentForm->FormTitle == 0) {\r
+        MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP));\r
+        CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID));\r
+      }\r
+\r
+      //\r
+      // Insert into Form list of this FormSet\r
+      //\r
+      InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);\r
+      break;\r
+\r
     //\r
     // Storage\r
     //\r
@@ -651,6 +703,7 @@ ParseOpCodes (
     //\r
     case EFI_IFR_DEFAULTSTORE_OP:\r
       DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));\r
+      ASSERT (DefaultStore != NULL);\r
       DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;\r
 \r
       CopyMem (&DefaultStore->DefaultId,   &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId,   sizeof (UINT16));\r
@@ -667,15 +720,17 @@ ParseOpCodes (
     //\r
     case EFI_IFR_SUBTITLE_OP:\r
       CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT (CurrentStatement != NULL);\r
       CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;\r
 \r
-      if (Scope) {\r
+      if (Scope != 0) {\r
         mInScopeSubtitle = TRUE;\r
       }\r
       break;\r
 \r
     case EFI_IFR_TEXT_OP:\r
       CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT (CurrentStatement != NULL);\r
 \r
       CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));\r
       break;\r
@@ -685,6 +740,7 @@ ParseOpCodes (
     //\r
     case EFI_IFR_ACTION_OP:\r
       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT (CurrentStatement != NULL);\r
 \r
       if (OpCodeLength == sizeof (EFI_IFR_ACTION_1)) {\r
         //\r
@@ -698,11 +754,13 @@ ParseOpCodes (
 \r
     case EFI_IFR_RESET_BUTTON_OP:\r
       CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT (CurrentStatement != NULL);\r
       CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));\r
       break;\r
 \r
     case EFI_IFR_REF_OP:\r
       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT (CurrentStatement != NULL);\r
 \r
       CopyMem (&CurrentStatement->RefFormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));\r
       if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {\r
@@ -721,6 +779,7 @@ ParseOpCodes (
     case EFI_IFR_ONE_OF_OP:\r
     case EFI_IFR_NUMERIC_OP:\r
       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT (CurrentStatement != NULL);\r
 \r
       CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;\r
       Value = &CurrentStatement->HiiValue;\r
@@ -770,6 +829,7 @@ ParseOpCodes (
 \r
     case EFI_IFR_ORDERED_LIST_OP:\r
       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT (CurrentStatement != NULL);\r
 \r
       CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags;\r
       CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;\r
@@ -787,6 +847,7 @@ ParseOpCodes (
 \r
     case EFI_IFR_CHECKBOX_OP:\r
       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT (CurrentStatement != NULL);\r
 \r
       CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags;\r
       CurrentStatement->StorageWidth = sizeof (BOOLEAN);\r
@@ -796,6 +857,7 @@ ParseOpCodes (
 \r
     case EFI_IFR_STRING_OP:\r
       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT (CurrentStatement != NULL);\r
 \r
       //\r
       // MinSize is the minimum number of characters that can be accepted for this opcode,\r
@@ -814,6 +876,7 @@ ParseOpCodes (
 \r
     case EFI_IFR_PASSWORD_OP:\r
       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT (CurrentStatement != NULL);\r
 \r
       //\r
       // MinSize is the minimum number of characters that can be accepted for this opcode,\r
@@ -831,6 +894,7 @@ ParseOpCodes (
 \r
     case EFI_IFR_DATE_OP:\r
       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT (CurrentStatement != NULL);\r
 \r
       CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags;\r
       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;\r
@@ -839,6 +903,7 @@ ParseOpCodes (
 \r
     case EFI_IFR_TIME_OP:\r
       CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
+      ASSERT (CurrentStatement != NULL);\r
 \r
       CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags;\r
       CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;\r
@@ -855,6 +920,7 @@ ParseOpCodes (
       // A Question may have more than one Default value which have different default types.\r
       //\r
       CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));\r
+      ASSERT (CurrentDefault != NULL);\r
       CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;\r
 \r
       CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;\r
@@ -878,6 +944,7 @@ ParseOpCodes (
       // It create a selection for use in current Question.\r
       //\r
       CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));\r
+      ASSERT (CurrentOption != NULL);\r
       CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;\r
 \r
       CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;\r
@@ -917,6 +984,8 @@ ParseOpCodes (
     // Expression\r
     //\r
     case EFI_IFR_VALUE_OP:\r
+    case EFI_IFR_READ_OP:\r
+    case EFI_IFR_WRITE_OP:\r
       break;\r
 \r
     case EFI_IFR_RULE_OP:\r
@@ -938,6 +1007,7 @@ ParseOpCodes (
         break;\r
 \r
       case EFI_IFR_FORM_OP:\r
+      case EFI_IFR_FORM_MAP_OP:\r
         ImageId = &CurrentForm->ImageId;\r
         break;\r
 \r
@@ -946,10 +1016,17 @@ ParseOpCodes (
         break;\r
 \r
       default:\r
+        //\r
+        // Make sure CurrentStatement is not NULL.\r
+        // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR\r
+        // file is wrongly generated by tools such as VFR Compiler.\r
+        //\r
+        ASSERT (CurrentStatement != NULL);\r
         ImageId = &CurrentStatement->ImageId;\r
         break;\r
       }\r
-\r
+      \r
+      ASSERT (ImageId != NULL);\r
       CopyMem (ImageId, &((EFI_IFR_IMAGE *) OpCodeData)->Id, sizeof (EFI_IMAGE_ID));\r
       break;\r
 \r
@@ -957,6 +1034,7 @@ ParseOpCodes (
     // Refresh\r
     //\r
     case EFI_IFR_REFRESH_OP:\r
+      ASSERT (CurrentStatement != NULL);\r
       CurrentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;\r
       break;\r
 \r
@@ -1040,6 +1118,7 @@ ParseOpCodes (
         break;\r
 \r
       case EFI_IFR_FORM_OP:\r
+      case EFI_IFR_FORM_MAP_OP:\r
         //\r
         // End of Form\r
         //\r