]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - BaseTools/Source/C/VfrCompile/VfrError.cpp
BaseTools/VfrCompile: Add/refine boundary checks for strcpy/strcat
[mirror_edk2.git] / BaseTools / Source / C / VfrCompile / VfrError.cpp
... / ...
CommitLineData
1/** @file\r
2 \r
3 VfrCompiler error handler.\r
4\r
5Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>\r
6This program and the accompanying materials \r
7are licensed and made available under the terms and conditions of the BSD License \r
8which accompanies this distribution. The full text of the license may be found at \r
9http://opensource.org/licenses/bsd-license.php \r
10 \r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
13\r
14**/\r
15\r
16#include "stdio.h"\r
17#include "string.h"\r
18#include "stdlib.h"\r
19#include "VfrError.h"\r
20#include "EfiUtilityMsgs.h"\r
21\r
22static SVFR_ERROR_HANDLE VFR_ERROR_HANDLE_TABLE [] = {\r
23 { VFR_RETURN_SUCCESS, NULL },\r
24 { VFR_RETURN_ERROR_SKIPED, NULL },\r
25 { VFR_RETURN_FATAL_ERROR, ": fatal error!!" },\r
26\r
27 { VFR_RETURN_MISMATCHED, ": unexpected token" },\r
28 { VFR_RETURN_INVALID_PARAMETER, ": invalid parameter" },\r
29 { VFR_RETURN_OUT_FOR_RESOURCES, ": system out of memory" },\r
30 { VFR_RETURN_UNSUPPORTED, ": unsupported" },\r
31 { VFR_RETURN_REDEFINED, ": already defined" },\r
32 { VFR_RETURN_FORMID_REDEFINED, ": form id already defined" },\r
33 { VFR_RETURN_QUESTIONID_REDEFINED, ": question id already defined" },\r
34 { VFR_RETURN_VARSTOREID_REDEFINED, ": varstore id already defined" },\r
35 { VFR_RETURN_UNDEFINED, ": undefined" },\r
36 { VFR_RETURN_VAR_NOTDEFINED_BY_QUESTION, ": some variable has not defined by a question"},\r
37 { VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR, ": Data Structure is defined by more than one varstores, it can't be referred as varstore, only varstore name could be used."},\r
38 { VFR_RETURN_GET_EFIVARSTORE_ERROR, ": get efi varstore error"},\r
39 { VFR_RETURN_EFIVARSTORE_USE_ERROR, ": can not use the efi varstore like this" },\r
40 { VFR_RETURN_EFIVARSTORE_SIZE_ERROR, ": unsupport efi varstore size should be <= 8 bytes" },\r
41 { VFR_RETURN_GET_NVVARSTORE_ERROR, ": get name value varstore error" },\r
42 { VFR_RETURN_QVAR_REUSE, ": variable reused by more than one question" },\r
43 { VFR_RETURN_FLAGS_UNSUPPORTED, ": flags unsupported" },\r
44 { VFR_RETURN_ERROR_ARRARY_NUM, ": array number error, the valid value is in (0 ~ MAX_INDEX-1) for UEFI vfr and in (1 ~ MAX_INDEX) for Framework Vfr" },\r
45 { VFR_RETURN_DATA_STRING_ERROR, ": data field string error or not support"},\r
46 { VFR_RETURN_DEFAULT_VALUE_REDEFINED, ": default value re-defined with different value"},\r
47 { VFR_RETURN_CONSTANT_ONLY, ": only constant is allowed in the expression"},\r
48 { VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR, ": Varstore name is defined by more than one varstores, it can't be referred as varstore, only varstore strucure name could be used."},\r
49 { VFR_RETURN_BIT_WIDTH_ERROR, ": bit width must be <= sizeof (type) * 8 and the max width can not > 32" },\r
50 { VFR_RETURN_CODEUNDEFINED, ": undefined Error Code" }\r
51};\r
52\r
53static SVFR_WARNING_HANDLE VFR_WARNING_HANDLE_TABLE [] = {\r
54 { VFR_WARNING_DEFAULT_VALUE_REDEFINED, ": default value re-defined with different value"},\r
55 { VFR_WARNING_STRING_TO_UINT_OVERFLOW, ": String to UINT* Overflow"},\r
56 { VFR_WARNING_ACTION_WITH_TEXT_TWO, ": Action opcode should not have TextTwo part"},\r
57 { VFR_WARNING_OBSOLETED_FRAMEWORK_OPCODE, ": Not recommend to use obsoleted framework opcode"},\r
58 { VFR_WARNING_CODEUNDEFINED, ": undefined Warning Code" }\r
59};\r
60\r
61CVfrErrorHandle::CVfrErrorHandle (\r
62 VOID\r
63 )\r
64{\r
65 mInputFileName = NULL;\r
66 mScopeRecordListHead = NULL;\r
67 mScopeRecordListTail = NULL;\r
68 mVfrErrorHandleTable = VFR_ERROR_HANDLE_TABLE;\r
69 mVfrWarningHandleTable = VFR_WARNING_HANDLE_TABLE;\r
70}\r
71\r
72CVfrErrorHandle::~CVfrErrorHandle (\r
73 VOID\r
74 )\r
75{\r
76 SVfrFileScopeRecord *pNode = NULL;\r
77\r
78 if (mInputFileName != NULL) {\r
79 delete mInputFileName;\r
80 }\r
81\r
82 while (mScopeRecordListHead != NULL) {\r
83 pNode = mScopeRecordListHead;\r
84 mScopeRecordListHead = mScopeRecordListHead->mNext;\r
85 delete pNode;\r
86 }\r
87\r
88 mScopeRecordListHead = NULL;\r
89 mScopeRecordListTail = NULL;\r
90 mVfrErrorHandleTable = NULL;\r
91 mVfrWarningHandleTable = NULL;\r
92}\r
93\r
94VOID\r
95CVfrErrorHandle::SetWarningAsError (\r
96 IN BOOLEAN WarningAsError\r
97 )\r
98{\r
99 mWarningAsError = WarningAsError;\r
100}\r
101\r
102VOID\r
103CVfrErrorHandle::SetInputFile (\r
104 IN CHAR8 *InputFile\r
105 )\r
106{\r
107 if (InputFile != NULL) {\r
108 mInputFileName = new CHAR8[strlen(InputFile) + 1];\r
109 strcpy (mInputFileName, InputFile);\r
110 }\r
111}\r
112\r
113SVfrFileScopeRecord::SVfrFileScopeRecord (\r
114 IN CHAR8 *Record, \r
115 IN UINT32 LineNum\r
116 )\r
117{\r
118 UINT32 Index;\r
119 CHAR8 *FileName = NULL;\r
120 CHAR8 *Str = NULL;\r
121\r
122 mWholeScopeLine = LineNum;\r
123 mNext = NULL;\r
124\r
125 Str = strchr (Record, ' ');\r
126 mScopeLineStart = atoi (++Str);\r
127\r
128 Str = strchr (Str, '\"');\r
129 FileName = ++Str;\r
130\r
131 while((Str = strstr (FileName, "\\\\")) != NULL) {\r
132 FileName = Str + 2;\r
133 }\r
134 if ((mFileName = new CHAR8[strlen(FileName)]) != NULL) {\r
135 for (Index = 0; FileName[Index] != '\"'; Index++) {\r
136 mFileName[Index] = FileName[Index];\r
137 }\r
138 mFileName[Index] = '\0';\r
139 }\r
140\r
141 return;\r
142}\r
143\r
144SVfrFileScopeRecord::~SVfrFileScopeRecord (\r
145 VOID\r
146 )\r
147{\r
148 if (mFileName != NULL) {\r
149 delete[] mFileName;\r
150 }\r
151}\r
152\r
153VOID\r
154CVfrErrorHandle::ParseFileScopeRecord (\r
155 IN CHAR8 *Record, \r
156 IN UINT32 WholeScopeLine\r
157 )\r
158{\r
159 SVfrFileScopeRecord *pNode = NULL;\r
160\r
161 if (Record == NULL) {\r
162 return;\r
163 }\r
164\r
165 if ((pNode = new SVfrFileScopeRecord(Record, WholeScopeLine)) == NULL) {\r
166 return;\r
167 }\r
168\r
169 if (mScopeRecordListHead == NULL) {\r
170 mScopeRecordListTail = mScopeRecordListHead = pNode;\r
171 } else {\r
172 mScopeRecordListTail->mNext = pNode;\r
173 mScopeRecordListTail = pNode;\r
174 }\r
175}\r
176\r
177VOID\r
178CVfrErrorHandle::GetFileNameLineNum (\r
179 IN UINT32 LineNum,\r
180 OUT CHAR8 **FileName,\r
181 OUT UINT32 *FileLine\r
182 )\r
183{\r
184 SVfrFileScopeRecord *pNode = NULL;\r
185\r
186 if ((FileName == NULL) || (FileLine == NULL)) {\r
187 return;\r
188 }\r
189\r
190 *FileName = NULL;\r
191 *FileLine = 0xFFFFFFFF;\r
192\r
193 //\r
194 // Some errors occur before scope record list been built.\r
195 //\r
196 if (mScopeRecordListHead == NULL) {\r
197 *FileLine = LineNum;\r
198 *FileName = mInputFileName;\r
199 return ;\r
200 }\r
201\r
202 for (pNode = mScopeRecordListHead; pNode->mNext != NULL; pNode = pNode->mNext) {\r
203 if ((LineNum > pNode->mWholeScopeLine) && (pNode->mNext->mWholeScopeLine > LineNum)) {\r
204 *FileName = pNode->mFileName;\r
205 *FileLine = LineNum - pNode->mWholeScopeLine + pNode->mScopeLineStart - 1;\r
206 return ;\r
207 }\r
208 }\r
209\r
210 *FileName = pNode->mFileName;\r
211 *FileLine = LineNum - pNode->mWholeScopeLine + pNode->mScopeLineStart - 1;\r
212}\r
213\r
214VOID\r
215CVfrErrorHandle::PrintMsg (\r
216 IN UINT32 LineNum,\r
217 IN CHAR8 *TokName,\r
218 IN CONST CHAR8 *MsgType,\r
219 IN CONST CHAR8 *ErrorMsg\r
220 )\r
221{\r
222 CHAR8 *FileName = NULL;\r
223 UINT32 FileLine;\r
224 \r
225 if (strncmp ("Warning", MsgType, strlen ("Warning")) == 0) {\r
226 VerboseMsg ((CHAR8 *) ErrorMsg);\r
227 return;\r
228 }\r
229 GetFileNameLineNum (LineNum, &FileName, &FileLine);\r
230 Error (FileName, FileLine, 0x3000, TokName, (CHAR8 *) "\t%s\n", (CHAR8 *) ErrorMsg);\r
231}\r
232\r
233UINT8\r
234CVfrErrorHandle::HandleError (\r
235 IN EFI_VFR_RETURN_CODE ErrorCode,\r
236 IN UINT32 LineNum,\r
237 IN CHAR8 *TokName\r
238 )\r
239{\r
240 UINT32 Index;\r
241 CHAR8 *FileName = NULL;\r
242 UINT32 FileLine;\r
243 CONST CHAR8 *ErrorMsg = NULL;\r
244\r
245 if (mVfrErrorHandleTable == NULL) {\r
246 return 1;\r
247 }\r
248\r
249 for (Index = 0; mVfrErrorHandleTable[Index].mErrorCode != VFR_RETURN_CODEUNDEFINED; Index++) {\r
250 if (ErrorCode == mVfrErrorHandleTable[Index].mErrorCode) {\r
251 ErrorMsg = mVfrErrorHandleTable[Index].mErrorMsg;\r
252 break;\r
253 }\r
254 }\r
255\r
256 if (ErrorMsg != NULL) {\r
257 GetFileNameLineNum (LineNum, &FileName, &FileLine);\r
258 Error (FileName, FileLine, 0x3000, TokName, (CHAR8 *) "\t%s\n", (CHAR8 *) ErrorMsg);\r
259 return 1;\r
260 } else {\r
261 return 0;\r
262 }\r
263}\r
264\r
265UINT8\r
266CVfrErrorHandle::HandleWarning (\r
267 IN EFI_VFR_WARNING_CODE WarningCode,\r
268 IN UINT32 LineNum,\r
269 IN CHAR8 *TokName\r
270 )\r
271{\r
272 UINT32 Index;\r
273 CHAR8 *FileName = NULL;\r
274 UINT32 FileLine;\r
275 CONST CHAR8 *WarningMsg = NULL;\r
276\r
277 if (mVfrWarningHandleTable == NULL) {\r
278 return 1;\r
279 }\r
280\r
281 GetFileNameLineNum (LineNum, &FileName, &FileLine);\r
282\r
283 if (mWarningAsError) {\r
284 Error (FileName, FileLine, 0x2220, (CHAR8 *) "warning treated as error", NULL);\r
285 }\r
286\r
287 for (Index = 0; mVfrWarningHandleTable[Index].mWarningCode != VFR_WARNING_CODEUNDEFINED; Index++) {\r
288 if (WarningCode == mVfrWarningHandleTable[Index].mWarningCode) {\r
289 WarningMsg = mVfrWarningHandleTable[Index].mWarningMsg;\r
290 break;\r
291 }\r
292 }\r
293\r
294 if (WarningMsg != NULL) {\r
295 Warning (FileName, FileLine, 0, TokName, (CHAR8 *) "\t%s\n", (CHAR8 *) WarningMsg);\r
296 return 1;\r
297 } else {\r
298 return 0;\r
299 }\r
300}\r
301\r
302CVfrErrorHandle gCVfrErrorHandle;\r