MdeModulePkg/UefiHiiLib: Validate question with bit fields

REF:https://bugzilla.tianocore.org/show_bug.cgi?id=545

In UefiHiiLib, there are codes to validate the current setting of
questions, now update the logic to handle question with bit storage.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Dandan Bi <dandan.bi@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
This commit is contained in:
Dandan Bi 2017-09-20 19:43:45 +08:00 committed by Eric Dong
parent 01723271a8
commit 95a7135191
3 changed files with 182 additions and 77 deletions

View File

@ -1169,6 +1169,13 @@ ValidateQuestionFromVfr (
UINTN Index;
CHAR16 *QuestionName;
CHAR16 *StringPtr;
UINT16 BitOffset;
UINT16 BitWidth;
UINT16 TotalBits;
UINTN StartBit;
UINTN EndBit;
BOOLEAN QuestionReferBitField;
UINT32 BufferValue;
//
// Initialize the local variables.
@ -1182,6 +1189,9 @@ ValidateQuestionFromVfr (
IfrEfiVarStore = NULL;
ZeroMem (&VarStoreData, sizeof (IFR_VARSTORAGE_DATA));
ZeroMem (&VarBlockData, sizeof (VarBlockData));
BitOffset = 0;
BitWidth = 0;
QuestionReferBitField = FALSE;
//
// Check IFR value is in block data, then Validate Value
@ -1345,8 +1355,19 @@ ValidateQuestionFromVfr (
//
// Get Offset by Question header and Width by DataType Flags
//
if (QuestionReferBitField) {
//
// Get the byte offset/width for bit field.
//
BitOffset = IfrOneOf->Question.VarStoreInfo.VarOffset;
BitWidth = IfrOneOf->Flags & EDKII_IFR_NUMERIC_SIZE_BIT;
Offset = BitOffset / 8;
TotalBits = BitOffset % 8 + BitWidth;
Width = (TotalBits % 8 == 0 ? TotalBits / 8: TotalBits / 8 + 1);
} else {
Offset = IfrOneOf->Question.VarStoreInfo.VarOffset;
Width = (UINT16) (1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE));
}
//
// Check whether this question is in current block array.
//
@ -1370,8 +1391,18 @@ ValidateQuestionFromVfr (
// Get the current value for oneof opcode
//
VarValue = 0;
if (QuestionReferBitField) {
//
// Get the value in bit fields.
//
StartBit = BitOffset % 8;
EndBit = StartBit + BitWidth - 1;
CopyMem ((UINT8 *) &BufferValue, VarBuffer + Offset, Width);
VarValue = BitFieldRead32 (BufferValue, StartBit, EndBit);
} else {
CopyMem (&VarValue, VarBuffer + Offset, Width);
}
}
//
// Set Block Data, to be checked in the following Oneof option opcode.
//
@ -1416,8 +1447,19 @@ ValidateQuestionFromVfr (
//
// Get Offset by Question header and Width by DataType Flags
//
if (QuestionReferBitField) {
//
// Get the byte offset/width for bit field.
//
BitOffset = IfrNumeric->Question.VarStoreInfo.VarOffset;
BitWidth = IfrNumeric->Flags & EDKII_IFR_NUMERIC_SIZE_BIT;
Offset = BitOffset / 8;
TotalBits = BitOffset % 8 + BitWidth;
Width = (TotalBits % 8 == 0 ? TotalBits / 8: TotalBits / 8 + 1);
} else {
Offset = IfrNumeric->Question.VarStoreInfo.VarOffset;
Width = (UINT16) (1 << (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE));
}
//
// Check whether this question is in current block array.
//
@ -1441,8 +1483,38 @@ ValidateQuestionFromVfr (
// Check the current value is in the numeric range.
//
VarValue = 0;
if (QuestionReferBitField) {
//
// Get the value in the bit fields.
//
StartBit = BitOffset % 8;
EndBit = StartBit + BitWidth - 1;
CopyMem ((UINT8 *) &BufferValue, VarBuffer + Offset, Width);
VarValue = BitFieldRead32 (BufferValue, StartBit, EndBit);
} else {
CopyMem (&VarValue, VarBuffer + Offset, Width);
}
}
if ( QuestionReferBitField) {
//
// Value in bit fields was stored as UINt32 type.
//
if ((IfrNumeric->Flags & EDKII_IFR_DISPLAY_BIT) == 0) {
if ((INT32) VarValue < (INT32) IfrNumeric->data.u32.MinValue || (INT32) VarValue > (INT32) IfrNumeric->data.u32.MaxValue) {
//
// Not in the valid range.
//
return EFI_INVALID_PARAMETER;
}
} else {
if (VarValue < IfrNumeric->data.u32.MinValue || VarValue > IfrNumeric->data.u32.MaxValue) {
//
// Not in the valid range.
//
return EFI_INVALID_PARAMETER;
}
}
} else {
if ((IfrNumeric->Flags & EFI_IFR_DISPLAY) == 0) {
switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) {
case EFI_IFR_NUMERIC_SIZE_1:
@ -1514,6 +1586,7 @@ ValidateQuestionFromVfr (
break;
}
}
}
break;
case EFI_IFR_CHECKBOX_OP:
//
@ -1554,8 +1627,19 @@ ValidateQuestionFromVfr (
//
// Get Offset by Question header
//
if (QuestionReferBitField) {
//
// Get the byte offset/width for bit field.
//
BitOffset = IfrCheckBox->Question.VarStoreInfo.VarOffset;
BitWidth = 1;
Offset = BitOffset / 8;
TotalBits = BitOffset % 8 + BitWidth;
Width = (TotalBits % 8 == 0 ? TotalBits / 8: TotalBits / 8 + 1);
} else {
Offset = IfrCheckBox->Question.VarStoreInfo.VarOffset;
Width = (UINT16) sizeof (BOOLEAN);
}
//
// Check whether this question is in current block array.
//
@ -1578,8 +1662,18 @@ ValidateQuestionFromVfr (
// Check the current value is in the numeric range.
//
VarValue = 0;
if (QuestionReferBitField) {
//
// Get the value in bit fields.
//
StartBit = BitOffset % 8;
EndBit = StartBit + BitWidth - 1;
CopyMem ((UINT8 *) &BufferValue, VarBuffer + Offset, Width);
VarValue = BitFieldRead32 (BufferValue, StartBit, EndBit);
} else {
CopyMem (&VarValue, VarBuffer + Offset, Width);
}
}
//
// Boolean type, only 1 and 0 is valid.
//
@ -1703,6 +1797,7 @@ ValidateQuestionFromVfr (
}
break;
case EFI_IFR_END_OP:
QuestionReferBitField = FALSE;
//
// Decrease opcode scope for the validated opcode
//
@ -1717,6 +1812,11 @@ ValidateQuestionFromVfr (
return EFI_INVALID_PARAMETER;
}
break;
case EFI_IFR_GUID_OP:
if (CompareGuid ((EFI_GUID *)((UINT8*)IfrOpHdr + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarstoreGuid)) {
QuestionReferBitField = TRUE;
}
break;
default:
//
// Increase Scope for the validated opcode

View File

@ -1,7 +1,7 @@
/** @file
Internal include file for the HII Library instance.
Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@ -20,6 +20,8 @@
#include <Protocol/DevicePath.h>
#include <Protocol/FormBrowser2.h>
#include <Guid/MdeModuleHii.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/HiiLib.h>

View File

@ -1,7 +1,7 @@
## @file
# HII Library implementation using UEFI HII protocols and services.
#
# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
@ -51,3 +51,6 @@
[Protocols]
gEfiFormBrowser2ProtocolGuid ## SOMETIMES_CONSUMES
gEfiDevicePathProtocolGuid ## SOMETIMES_CONSUMES
[Guids]
gEdkiiIfrBitVarstoreGuid ## SOMETIMES_CONSUMES ## GUID