Hi Eric,

The patch is better, but it is not quite right. It is now allowing the 
full range of values for each integer type.  You can refer to the Two's 
Compliment Wiki article for it additional information 
http://en.wikipedia.org/wiki/Two%27s_complement.


The following code shows that the full range of integers are not being 
allowed by the patch:
        numeric varid = MY_EFI_VARSTORE_DATA.Nothing,
            prompt = STRING_TOKEN(1),
            help = STRING_TOKEN(2),
            flags = DISPLAY_INT_DEC,
            minimum = -128,
            maximum = 127,
            step = 1,
        endnumeric;

A signed integer should be able to store from -128 to 127.  The above 
example results in an error because the patch is checking against 0x7F for 
both negative and non negative numbers.

if (IntDecStyle) {
        if (MinU1 > 0x7F) {
                _PCATCH (VFR_RETURN_INVALID_PARAMETER, I->getLine(), "INT8 
type minimum can small than -0x7F");
        }
}

If you modify the matches to follow the below pattern, than it will allow 
for the full range of negative to positive numbers.

if (IntDecStyle) {
        if (MaxNegative == TRUE && MaxU1 > 0x80) {
                _PCATCH (VFR_RETURN_INVALID_PARAMETER, A->getLine(), "INT8 
type cannot be smaller than -128 (-0x80)");
        } else if (MaxNegative == FALSE && MaxU1 > 0x7F) {
                _PCATCH (VFR_RETURN_INVALID_PARAMETER, A->getLine(), "INT8 
type cannot be bigger than 127 (0x7F)");
        }
}

You can check the Limits.h in your compiler's include folder to see the 
range of values for each integer type

Best Regards,
Aaron



From:   "Dong, Eric" <eric.d...@intel.com>
To:     "edk2-devel@lists.sourceforge.net" 
<edk2-devel@lists.sourceforge.net>, "aaron....@congatec.com" 
<aaron....@congatec.com>, "Gao, Liming" <liming....@intel.com>, 
Date:   05/03/2015 10:59 PM
Subject:        RE: [edk2] [Patch 1/2] BaseTools: Enhance the check for 
numeric opcode  with EFI_IFR_DISPLAY_INT_DEC attribute.



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> 
To:        edk2-devel@lists.sourceforge.net, 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>
---
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
https://lists.sourceforge.net/lists/listinfo/edk2-devel[attachment 
"0001-BaseTools-Enhance-the-check-for-numeric-opcode-with-.patch" deleted 
by Aaron Pop/cus/congatec] [attachment 
"0003-BaseTools-Add-boudary-check-for-minimum-maximum-defa.patch" deleted 
by Aaron Pop/cus/congatec] 
------------------------------------------------------------------------------
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