From e451aaa637e437ca9e5435e21f2c9493cd1e044e Mon Sep 17 00:00:00 2001 From: Zhaozh1x Date: Tue, 4 Sep 2018 17:26:11 +0800 Subject: [PATCH] BaseTools: add ASSERT checker for array buffer value assignment. V3: Update the error message for array checker. V2: 1. Add comments for each ASSERT. 2. ASSERT need to skip the case of array size of array as zero. For example, TestArray[] in struct in header file. V1: For structure PCD, 1. use compiler time assert to check the array index, report error if array index exceeds the array number. 2. use compiler time assert to check the array size, report error if the user declared size in header file is smaller than the user defined in DEC/DSC file. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: ZhiqiangX Zhao Cc: Liming Gao Cc: Yonghong Zhu Cc: Bob Feng Reviewed-by: Liming Gao --- BaseTools/Source/C/Common/PcdValueCommon.h | 7 +++++++ BaseTools/Source/Python/Workspace/DscBuildData.py | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/BaseTools/Source/C/Common/PcdValueCommon.h b/BaseTools/Source/C/Common/PcdValueCommon.h index 3922428ded..255afdfcc3 100644 --- a/BaseTools/Source/C/Common/PcdValueCommon.h +++ b/BaseTools/Source/C/Common/PcdValueCommon.h @@ -22,6 +22,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #define __ARRAY_ELEMENT_SIZE(TYPE, Field) (sizeof((TYPE *)0)->Field[0]) #define __OFFSET_OF(TYPE, Field) ((UINT32) &(((TYPE *)0)->Field)) #define __FLEXIBLE_SIZE(Size, TYPE, Field, MaxIndex) if (__FIELD_SIZE(TYPE, Field) == 0) Size = MAX((__OFFSET_OF(TYPE, Field) + __ARRAY_ELEMENT_SIZE(TYPE, Field) * (MaxIndex)), Size) +#define __ARRAY_SIZE(Array) (sizeof(Array)/sizeof(Array[0])) + +#if defined(_MSC_EXTENSIONS) +#define __STATIC_ASSERT static_assert +#else +#define __STATIC_ASSERT _Static_assert +#endif VOID PcdEntryPoint ( diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py index 39db945fb8..b7b4b610ca 100644 --- a/BaseTools/Source/Python/Workspace/DscBuildData.py +++ b/BaseTools/Source/Python/Workspace/DscBuildData.py @@ -1832,8 +1832,12 @@ class DscBuildData(PlatformBuildClassObject): # CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName) CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) + CApp = CApp + ' __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName, ValueSize, Pcd.DatumType, FieldName, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize) else: + if '[' in FieldName and ']' in FieldName: + Index = int(FieldName.split('[')[1].split(']')[0]) + CApp = CApp + ' __STATIC_ASSERT((%d < __ARRAY_SIZE(Pcd->%s)) || (__ARRAY_SIZE(Pcd->%s) == 0), "array index exceeds the array number"); // From %s Line %d Index of %s\n' % (Index, FieldName.split('[')[0], FieldName.split('[')[0], FieldList[FieldName][1], FieldList[FieldName][2], FieldName) if ValueSize > 4: CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) else: @@ -1911,8 +1915,12 @@ class DscBuildData(PlatformBuildClassObject): # CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName) CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) + CApp = CApp + ' __STATIC_ASSERT((__FIELD_SIZE(%s, %s) >= %d) || (__FIELD_SIZE(%s, %s) == 0), "Input buffer exceeds the buffer array"); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName, ValueSize, Pcd.DatumType, FieldName, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) CApp = CApp + ' memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize) else: + if '[' in FieldName and ']' in FieldName: + Index = int(FieldName.split('[')[1].split(']')[0]) + CApp = CApp + ' __STATIC_ASSERT((%d < __ARRAY_SIZE(Pcd->%s)) || (__ARRAY_SIZE(Pcd->%s) == 0), "array index exceeds the array number"); // From %s Line %d Index of %s\n' % (Index, FieldName.split('[')[0], FieldName.split('[')[0], FieldList[FieldName][1], FieldList[FieldName][2], FieldName) if ValueSize > 4: CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) else: