Aaron,

Thanks for your comments. I check the code you provide, I found the input 
maximum value(200) is bigger than the allowed maximum value(0x7F). So 
vfrcompiler assume the maximum value is (INT (200) = -38) which is small than 
minimum value(0), and the error raised.
Now I add code to do bound check first. Please review this new patch which add 
bound check.

Thanks,
Eric
From: aaron....@congatec.com [mailto:aaron....@congatec.com]
Sent: Friday, May 01, 2015 1:33 AM
To: edk2-devel@lists.sourceforge.net
Subject: Re: [edk2] [Patch 1/2] BaseTools: Enhance the check for numeric opcode 
with EFI_IFR_DISPLAY_INT_DEC attribute.

Hi Eric,

I think this patch still needs some work because it isn't enforcing the min/max 
of signed integers.  In the below example, the following error is generated:
typedef struct {
        UINT8        Nothing[1];
} MY_EFI_VARSTORE_DATA;

        numeric varid = MY_EFI_VARSTORE_DATA.Nothing,
            prompt = STRING_TOKEN(1),
            help = STRING_TOKEN(2),
            flags = DISPLAY_INT_DEC,
            minimum = 0,
            maximum = 200,
            step = 1,
        endnumeric;

ERROR 12288: Maximum can't be less than Minimum
        : invalid parameter

The patch appears to not be bounds checking the values against the maximum 
value that can be stored in the type.  From limits.h:

#define _I8_MIN     (-127i8 - 1)    /* minimum signed 8 bit value */
#define _I8_MAX       127i8         /* maximum signed 8 bit value */


        numeric varid = MY_EFI_VARSTORE_DATA.Nothing,
            prompt = STRING_TOKEN(1),
            help = STRING_TOKEN(2),
            flags = DISPLAY_INT_DEC,
            minimum = -100,
            maximum = 200,
            step = 1,
        endnumeric;
And this is allowed to compile successfully even though 200 is above the 
maximum 127 that can be stored in a signed integer.

Best Regards,
Aaron



From:        Eric Dong <eric.d...@intel.com<mailto:eric.d...@intel.com>>
To:        
edk2-devel@lists.sourceforge.net<mailto:edk2-devel@lists.sourceforge.net>, 
liming....@intel.com<mailto:liming....@intel.com>,
Date:        04/29/2015 10:57 PM
Subject:        [edk2] [Patch 1/2] BaseTools: Enhance the check for numeric 
opcode        with EFI_IFR_DISPLAY_INT_DEC attribute.
________________________________



Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Eric Dong <eric.d...@intel.com<mailto:eric.d...@intel.com>>
---
BaseTools/Source/C/VfrCompile/VfrFormPkg.h |   8 ++
BaseTools/Source/C/VfrCompile/VfrSyntax.g  | 170 +++++++++++++++++++++++++----
2 files changed, 156 insertions(+), 22 deletions(-)

diff --git a/BaseTools/Source/C/VfrCompile/VfrFormPkg.h 
b/BaseTools/Source/C/VfrCompile/VfrFormPkg.h
index 3d2def8..e64ef1b 100644
--- a/BaseTools/Source/C/VfrCompile/VfrFormPkg.h
+++ b/BaseTools/Source/C/VfrCompile/VfrFormPkg.h
@@ -308,10 +308,14 @@ public:
  }

  VOID UpdateHeader (IN EFI_IFR_OP_HEADER *Header) {
    mHeader = Header;
  }
+
+  UINT8 GetOpCode () {
+    return mHeader->OpCode;
+  }
};

extern UINT8 gScopeCount;

/*
@@ -1356,10 +1360,14 @@ public:
    } else {
      mNumeric->Flags = LFlags;
    }
    return VFR_RETURN_SUCCESS;
  }
+
+  UINT8 GetNumericFlags () {
+    return mNumeric->Flags;
+  }
};

class CIfrOneOf : public CIfrObj, public CIfrOpHeader, public 
CIfrQuestionHeader, public CIfrMinMaxStepData {
private:
  EFI_IFR_ONE_OF *mOneOf;
diff --git a/BaseTools/Source/C/VfrCompile/VfrSyntax.g 
b/BaseTools/Source/C/VfrCompile/VfrSyntax.g
index 2255d6f..d014aff 100644
--- a/BaseTools/Source/C/VfrCompile/VfrSyntax.g
+++ b/BaseTools/Source/C/VfrCompile/VfrSyntax.g
@@ -1394,24 +1394,40 @@ vfrQuestionDataFieldName [EFI_QUESTION_ID &QId, UINT32 
&Mask, CHAR8 *&VarIdStr,
  ;

vfrConstantValueField[UINT8 Type] > [EFI_IFR_TYPE_VALUE Value] :
  <<
    EFI_GUID Guid;
+    BOOLEAN  Negative = FALSE;
  >>
+    {
+      "\-"                                          << Negative = TRUE;  >>
+    }
    N1:Number                                       <<
                                                       switch ($Type) {
                                                       case 
EFI_IFR_TYPE_NUM_SIZE_8 :
-                                                         $Value.u8     = 
_STOU8(N1->getText(), N1->getLine());
+                                                         $Value.u8 = 
_STOU8(N1->getText(), N1->getLine());
+                                                         if (Negative) {
+                                                           $Value.u8 = 
~$Value.u8 + 1;
+                                                         }
                                                       break;
                                                       case 
EFI_IFR_TYPE_NUM_SIZE_16 :
-                                                         $Value.u16    = 
_STOU16(N1->getText(), N1->getLine());
+                                                         $Value.u16 = 
_STOU16(N1->getText(), N1->getLine());
+                                                         if (Negative) {
+                                                           $Value.u16 = 
~$Value.u16 + 1;
+                                                         }
                                                       break;
                                                       case 
EFI_IFR_TYPE_NUM_SIZE_32 :
                                                         $Value.u32    = 
_STOU32(N1->getText(), N1->getLine());
+                                                         if (Negative) {
+                                                           $Value.u32 = 
~$Value.u32 + 1;
+                                                         }
                                                       break;
                                                       case 
EFI_IFR_TYPE_NUM_SIZE_64 :
                                                         $Value.u64    = 
_STOU64(N1->getText(), N1->getLine());
+                                                         if (Negative) {
+                                                           $Value.u64 = 
~$Value.u64 + 1;
+                                                         }
                                                       break;
                                                       case 
EFI_IFR_TYPE_BOOLEAN :
                                                         $Value.b      = 
_STOU8(N1->getText(), N1->getLine());
                                                       break;
                                                       case EFI_IFR_TYPE_STRING 
:
@@ -1531,20 +1547,53 @@ vfrStatementDefault :
     EFI_DEFAULT_ID        DefaultId     = EFI_HII_DEFAULT_CLASS_STANDARD;
     CHAR8                 *VarStoreName = NULL;
     EFI_VFR_VARSTORE_TYPE VarStoreType  = EFI_VFR_VARSTORE_INVALID;
     UINT32                Size          = 0;
     EFI_GUID              *VarGuid      = NULL;
+     CIfrNumeric           *NumericQst   = NULL;
  >>
  D:Default
  (
    (
      "=" vfrConstantValueField[_GET_CURRQEST_DATATYPE()] > [Val] ","
                                                    <<
                                                        if (gCurrentMinMaxData 
!= NULL && gCurrentMinMaxData->IsNumericOpcode()) {
                                                          //check default value 
is valid for Numeric Opcode
-                                                          if (Val.u64 < 
gCurrentMinMaxData->GetMinData(_GET_CURRQEST_DATATYPE()) || Val.u64 > 
gCurrentMinMaxData->GetMaxData(_GET_CURRQEST_DATATYPE())) {
-                                                            _PCATCH 
(VFR_RETURN_INVALID_PARAMETER, D->getLine(), "Numeric default value must be 
between MinValue and MaxValue.");
+                                                          NumericQst = 
(CIfrNumeric *) gCurrentQuestion;
+                                                          if 
((NumericQst->GetNumericFlags() & EFI_IFR_DISPLAY) == 0) {
+                                                            switch 
(_GET_CURRQEST_DATATYPE()) {
+                                                            case 
EFI_IFR_TYPE_NUM_SIZE_8:
+                                                              if (((INT8) 
Val.u8 < (INT8) gCurrentMinMaxData->GetMinData(_GET_CURRQEST_DATATYPE())) ||
+                                                                  ((INT8) 
Val.u8 > (INT8) gCurrentMinMaxData->GetMaxData(_GET_CURRQEST_DATATYPE()))) {
+                                                                _PCATCH 
(VFR_RETURN_INVALID_PARAMETER, D->getLine(), "Numeric default value must be 
between MinValue and MaxValue.");
+                                                              }
+                                                              break;
+                                                            case 
EFI_IFR_TYPE_NUM_SIZE_16:
+                                                              if (((INT16) 
Val.u16 < (INT16) gCurrentMinMaxData->GetMinData(_GET_CURRQEST_DATATYPE())) ||
+                                                                  ((INT16) 
Val.u16 > (INT16) gCurrentMinMaxData->GetMaxData(_GET_CURRQEST_DATATYPE()))) {
+                                                                _PCATCH 
(VFR_RETURN_INVALID_PARAMETER, D->getLine(), "Numeric default value must be 
between MinValue and MaxValue.");
+                                                              }
+                                                              break;
+                                                            case 
EFI_IFR_TYPE_NUM_SIZE_32:
+                                                              if (((INT32) 
Val.u32 < (INT32) gCurrentMinMaxData->GetMinData(_GET_CURRQEST_DATATYPE())) ||
+                                                                  ((INT32) 
Val.u32 > (INT32) gCurrentMinMaxData->GetMaxData(_GET_CURRQEST_DATATYPE()))) {
+                                                                _PCATCH 
(VFR_RETURN_INVALID_PARAMETER, D->getLine(), "Numeric default value must be 
between MinValue and MaxValue.");
+                                                              }
+                                                              break;
+                                                            case 
EFI_IFR_TYPE_NUM_SIZE_64:
+                                                              if (((INT64) 
Val.u64 < (INT64) gCurrentMinMaxData->GetMinData(_GET_CURRQEST_DATATYPE())) ||
+                                                                  ((INT64) 
Val.u64 > (INT64) gCurrentMinMaxData->GetMaxData(_GET_CURRQEST_DATATYPE()))) {
+                                                                _PCATCH 
(VFR_RETURN_INVALID_PARAMETER, D->getLine(), "Numeric default value must be 
between MinValue and MaxValue.");
+                                                              }
+                                                              break;
+                                                            default:
+                                                              break;
+                                                            }
+                                                          } else {
+                                                            if (Val.u64 < 
gCurrentMinMaxData->GetMinData(_GET_CURRQEST_DATATYPE()) || Val.u64 > 
gCurrentMinMaxData->GetMaxData(_GET_CURRQEST_DATATYPE())) {
+                                                              _PCATCH 
(VFR_RETURN_INVALID_PARAMETER, D->getLine(), "Numeric default value must be 
between MinValue and MaxValue.");
+                                                            }
                                                          }
                                                        }
                                                        if 
(_GET_CURRQEST_DATATYPE() == EFI_IFR_TYPE_OTHER) {
                                                          _PCATCH 
(VFR_RETURN_FATAL_ERROR, D->getLine(), "Default data type error.");
                                                          Size = sizeof 
(EFI_IFR_TYPE_VALUE);
@@ -2218,45 +2267,122 @@ vfrSetMinMaxStep[CIfrMinMaxStepData & MMSDObj] :
  <<
     UINT64 MaxU8 = 0, MinU8 = 0, StepU8 = 0;
     UINT32 MaxU4 = 0, MinU4 = 0, StepU4 = 0;
     UINT16 MaxU2 = 0, MinU2 = 0, StepU2 = 0;
     UINT8  MaxU1 = 0, MinU1 = 0, StepU1 = 0;
+     BOOLEAN IntDecStyle = FALSE;
+     CIfrNumeric *NObj = (CIfrNumeric *) (&MMSDObj);
+     if ((NObj->GetOpCode() == EFI_IFR_NUMERIC_OP) && 
((NObj->GetNumericFlags() & EFI_IFR_DISPLAY) == 0)) {
+       IntDecStyle = TRUE;
+     }
+     BOOLEAN MinNegative = FALSE;
+     BOOLEAN MaxNegative = FALSE;
  >>
-  Minimum   "=" I:Number ","
-                                                       <<
+  Minimum   "="
+  {
+    "\-"                                               << MinNegative = TRUE; 
>>
+  }
+  I:Number ","                                         <<
+                                                          if (!IntDecStyle &&  
MinNegative) {
+                                                            _PCATCH 
(VFR_RETURN_INVALID_PARAMETER, I->getLine(), "\"-\" can't be used when not in 
int decimal type. ");
+                                                          }
                                                          switch 
(_GET_CURRQEST_DATATYPE()) {
-                                                          case 
EFI_IFR_TYPE_NUM_SIZE_64 : MinU8 = _STOU64(I->getText(), I->getLine()); break;
-                                                          case 
EFI_IFR_TYPE_NUM_SIZE_32 : MinU4 = _STOU32(I->getText(), I->getLine()); break;
-                                                          case 
EFI_IFR_TYPE_NUM_SIZE_16 : MinU2 = _STOU16(I->getText(), I->getLine()); break;
-                                                          case 
EFI_IFR_TYPE_NUM_SIZE_8 :  MinU1 = _STOU8(I->getText(), I->getLine());  break;
+                                                          case 
EFI_IFR_TYPE_NUM_SIZE_64 :
+                                                            MinU8 = 
_STOU64(I->getText(), I->getLine());
+                                                            if (MinNegative) {
+                                                              MinU8 = ~MinU8 + 
1;
+                                                            }
+                                                            break;
+                                                          case 
EFI_IFR_TYPE_NUM_SIZE_32 :
+                                                            MinU4 = 
_STOU32(I->getText(), I->getLine());
+                                                            if (MinNegative) {
+                                                              MinU4 = ~MinU4 + 
1;
+                                                            }
+                                                            break;
+                                                          case 
EFI_IFR_TYPE_NUM_SIZE_16 :
+                                                            MinU2 = 
_STOU16(I->getText(), I->getLine());
+                                                            if (MinNegative) {
+                                                              MinU2 = ~MinU2 + 
1;
+                                                            }
+                                                            break;
+                                                          case 
EFI_IFR_TYPE_NUM_SIZE_8 :
+                                                            MinU1 = 
_STOU8(I->getText(), I->getLine());
+                                                            if (MinNegative) {
+                                                              MinU1 = ~MinU1 + 
1;
+                                                            }
+                                                            break;
                                                          }
                                                       >>
-  Maximum   "=" A:Number ","
-                                                       <<
+  Maximum   "="
+  {
+    "\-"                                               << MaxNegative = TRUE; 
>>
+  }
+  A:Number ","                                         <<
+                                                          if (!IntDecStyle &&  
MaxNegative) {
+                                                            _PCATCH 
(VFR_RETURN_INVALID_PARAMETER, A->getLine(), "\"-\" can't be used when not in 
int decimal type. ");
+                                                          }
+
                                                          switch 
(_GET_CURRQEST_DATATYPE()) {
                                                          case 
EFI_IFR_TYPE_NUM_SIZE_64 :
                                                            MaxU8 = 
_STOU64(A->getText(), A->getLine());
-                                                            if (MaxU8 < MinU8) 
{
-                                                              _PCATCH 
(VFR_RETURN_INVALID_PARAMETER, A->getLine(), "Maximum can't be less than 
Minimum");
+                                                            if (MaxNegative) {
+                                                              MaxU8 = ~MaxU8 + 
1;
+                                                            }
+                                                            if (IntDecStyle) {
+                                                              if ((INT64) 
MaxU8 < (INT64) MinU8) {
+                                                                _PCATCH 
(VFR_RETURN_INVALID_PARAMETER, A->getLine(), "Maximum can't be less than 
Minimum");
+                                                              }
+                                                            } else {
+                                                              if (MaxU8 < 
MinU8) {
+                                                                _PCATCH 
(VFR_RETURN_INVALID_PARAMETER, A->getLine(), "Maximum can't be less than 
Minimum");
+                                                              }
                                                            }
                                                            break;
                                                          case 
EFI_IFR_TYPE_NUM_SIZE_32 :
-                                                            MaxU4 = 
_STOU32(A->getText(), A->getLine());
-                                                            if (MaxU4 < MinU4) 
{
-                                                              _PCATCH 
(VFR_RETURN_INVALID_PARAMETER, A->getLine(), "Maximum can't be less than 
Minimum");
+                                                            MaxU4 = 
_STOU32(A->getText(), A->getLine());
+                                                            if (MaxNegative) {
+                                                              MaxU4 = ~MaxU4 + 
1;
+                                                            }
+                                                            if (IntDecStyle) {
+                                                              if ((INT32) 
MaxU4 < (INT32) MinU4) {
+                                                                _PCATCH 
(VFR_RETURN_INVALID_PARAMETER, A->getLine(), "Maximum can't be less than 
Minimum");
+                                                              }
+                                                            } else {
+                                                              if (MaxU4 < 
MinU4) {
+                                                                _PCATCH 
(VFR_RETURN_INVALID_PARAMETER, A->getLine(), "Maximum can't be less than 
Minimum");
+                                                              }
                                                            }
                                                            break;
                                                          case 
EFI_IFR_TYPE_NUM_SIZE_16 :
                                                            MaxU2 = 
_STOU16(A->getText(), A->getLine());
-                                                            if (MaxU2 < MinU2) 
{
-                                                              _PCATCH 
(VFR_RETURN_INVALID_PARAMETER, A->getLine(), "Maximum can't be less than 
Minimum");
+                                                            if (MaxNegative) {
+                                                              MaxU2 = ~MaxU2 + 
1;
+                                                            }
+
+                                                            if (IntDecStyle) {
+                                                              if ((INT16) 
MaxU2 < (INT16) MinU2) {
+                                                                _PCATCH 
(VFR_RETURN_INVALID_PARAMETER, A->getLine(), "Maximum can't be less than 
Minimum");
+                                                              }
+                                                            } else {
+                                                              if (MaxU2 < 
MinU2) {
+                                                                _PCATCH 
(VFR_RETURN_INVALID_PARAMETER, A->getLine(), "Maximum can't be less than 
Minimum");
+                                                              }
                                                            }
                                                            break;
                                                          case 
EFI_IFR_TYPE_NUM_SIZE_8 :
-                                                            MaxU1 = 
_STOU8(A->getText(), A->getLine());
-                                                            if (MaxU1 < MinU1) 
{
-                                                              _PCATCH 
(VFR_RETURN_INVALID_PARAMETER, A->getLine(), "Maximum can't be less than 
Minimum");
+                                                            MaxU1 = 
_STOU8(A->getText(), A->getLine());
+                                                            if (MaxNegative) {
+                                                              MaxU1 = ~MaxU1 + 
1;
+                                                            }
+                                                            if (IntDecStyle) {
+                                                              if ((INT8) MaxU1 
< (INT8) MinU1) {
+                                                                _PCATCH 
(VFR_RETURN_INVALID_PARAMETER, A->getLine(), "Maximum can't be less than 
Minimum");
+                                                              }
+                                                            } else {
+                                                              if (MaxU1 < 
MinU1) {
+                                                                _PCATCH 
(VFR_RETURN_INVALID_PARAMETER, A->getLine(), "Maximum can't be less than 
Minimum");
+                                                              }
                                                            }
                                                            break;
                                                          }
                                                       >>
  {
--
1.9.5.msysgit.1


------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net<mailto:edk2-devel@lists.sourceforge.net>
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Attachment: 0001-BaseTools-Enhance-the-check-for-numeric-opcode-with-.patch
Description: 0001-BaseTools-Enhance-the-check-for-numeric-opcode-with-.patch

Attachment: 0003-BaseTools-Add-boudary-check-for-minimum-maximum-defa.patch
Description: 0003-BaseTools-Add-boudary-check-for-minimum-maximum-defa.patch

------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud 
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to