]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/Misc.c
pointer verification (not NULL) and buffer overrun fixes.
[mirror_edk2.git] / ShellPkg / Library / UefiShellDebug1CommandsLib / HexEdit / Misc.c
CommitLineData
632820d1 1/** @file\r
2 Implementation of various string and line routines\r
3 \r
4 Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved. <BR>\r
5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "HexEditor.h"\r
16\r
17extern BOOLEAN HEditorMouseAction;\r
18\r
19VOID\r
20HEditorClearLine (\r
21 IN UINTN Row\r
22 )\r
23/*++\r
24\r
25Routine Description: \r
26\r
27 Clear line at Row\r
28\r
29Arguments: \r
30\r
31 Row -- row number to be cleared ( start from 1 )\r
32\r
33Returns: \r
34\r
35 EFI_SUCCESS\r
36\r
37--*/\r
38{\r
39 CHAR16 Line[200];\r
40 UINTN Index;\r
41 UINTN Limit;\r
42 UINTN StartCol;\r
43\r
44 if (HEditorMouseAction) {\r
45 Limit = 3 * 0x10;\r
46 StartCol = 10;\r
47 } else {\r
48 Limit = HMainEditor.ScreenSize.Column;\r
49 StartCol = 1;\r
50 }\r
51 //\r
52 // prepare a blank line\r
53 //\r
54 for (Index = 0; Index < Limit; Index++) {\r
55 Line[Index] = ' ';\r
56 }\r
57\r
58 if (Row == HMainEditor.ScreenSize.Row && Limit == HMainEditor.ScreenSize.Column) {\r
59 //\r
60 // if '\0' is still at position 80, it will cause first line error\r
61 //\r
62 Line[Limit - 1] = '\0';\r
63 } else {\r
64 Line[Limit] = '\0';\r
65 }\r
66 //\r
67 // print out the blank line\r
68 //\r
69 ShellPrintEx ((INT32)StartCol - 1, (INT32)Row - 1, Line);\r
70}\r
71\r
72HEFI_EDITOR_LINE *\r
73HLineDup (\r
74 IN HEFI_EDITOR_LINE *Src\r
75 )\r
76/*++\r
77\r
78Routine Description: \r
79\r
80 Duplicate a line\r
81\r
82Arguments: \r
83\r
84 Src -- line to be duplicated\r
85\r
86Returns: \r
87\r
88 NULL -- wrong\r
89 Not NULL -- line created\r
90\r
91--*/\r
92{\r
93 HEFI_EDITOR_LINE *Dest;\r
94\r
95 //\r
96 // allocate for the line structure\r
97 //\r
98 Dest = AllocateZeroPool (sizeof (HEFI_EDITOR_LINE));\r
99 if (Dest == NULL) {\r
100 return NULL;\r
101 }\r
102\r
103 Dest->Signature = EFI_EDITOR_LINE_LIST;\r
104 Dest->Size = Src->Size;\r
105\r
106 CopyMem (Dest->Buffer, Src->Buffer, 0x10);\r
107\r
108 Dest->Link = Src->Link;\r
109\r
110 return Dest;\r
111}\r
112\r
113VOID\r
114HLineFree (\r
115 IN HEFI_EDITOR_LINE *Src\r
116 )\r
117/*++\r
118\r
119Routine Description: \r
120\r
121 Free a line and it's internal buffer\r
122\r
123Arguments: \r
124\r
125 Src -- line to be freed\r
126\r
127Returns: \r
128\r
129 None\r
130\r
131--*/\r
132{\r
133 if (Src == NULL) {\r
134 return ;\r
135 }\r
136\r
137 SHELL_FREE_NON_NULL (Src);\r
138\r
139}\r
140\r
141HEFI_EDITOR_LINE *\r
142_HLineAdvance (\r
143 IN UINTN Count\r
144 )\r
145/*++\r
146\r
147Routine Description: \r
148\r
149 Advance to the next Count lines\r
150\r
151Arguments: \r
152\r
153 Count -- line number to advance\r
154\r
155Returns: \r
156\r
157 NULL -- wrong\r
158 Not NULL -- line after advance\r
159\r
160--*/\r
161{\r
162 UINTN Index;\r
163 HEFI_EDITOR_LINE *Line;\r
164\r
165 Line = HMainEditor.BufferImage->CurrentLine;\r
166 if (Line == NULL) {\r
167 return NULL;\r
168 }\r
169\r
170 for (Index = 0; Index < Count; Index++) {\r
171 //\r
172 // if already last line\r
173 //\r
174 if (Line->Link.ForwardLink == HMainEditor.BufferImage->ListHead) {\r
175 return NULL;\r
176 }\r
177\r
178 Line = CR (Line->Link.ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
179 }\r
180\r
181 return Line;\r
182}\r
183\r
184HEFI_EDITOR_LINE *\r
185_HLineRetreat (\r
186 IN UINTN Count\r
187 )\r
188/*++\r
189\r
190Routine Description: \r
191\r
192 Retreat to the previous Count lines\r
193\r
194Arguments: \r
195\r
196 Count -- line number to retreat\r
197\r
198Returns: \r
199\r
200 NULL -- wrong\r
201 Not NULL -- line after retreat\r
202\r
203--*/\r
204{\r
205 UINTN Index;\r
206 HEFI_EDITOR_LINE *Line;\r
207\r
208 Line = HMainEditor.BufferImage->CurrentLine;\r
209 if (Line == NULL) {\r
210 return NULL;\r
211 }\r
212\r
213 for (Index = 0; Index < Count; Index++) {\r
214 //\r
215 // already the first line\r
216 //\r
217 if (Line->Link.BackLink == HMainEditor.BufferImage->ListHead) {\r
218 return NULL;\r
219 }\r
220\r
221 Line = CR (Line->Link.BackLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
222 }\r
223\r
224 return Line;\r
225}\r
226\r
227HEFI_EDITOR_LINE *\r
228HMoveLine (\r
229 IN INTN Count\r
230 )\r
231/*++\r
232\r
233Routine Description: \r
234\r
235 Advance/Retreat lines\r
236\r
237Arguments: \r
238\r
239 Count -- line number to advance/retreat\r
240 >0 : advance\r
241 <0: retreat \r
242\r
243Returns: \r
244\r
245 NULL -- wrong\r
246 Not NULL -- line after advance\r
247\r
248--*/\r
249{\r
250 HEFI_EDITOR_LINE *Line;\r
251 UINTN AbsCount;\r
252\r
253 //\r
254 // difference with MoveCurrentLine\r
255 // just return Line\r
256 // do not set currentline to Line\r
257 //\r
258 if (Count <= 0) {\r
33c031ee 259 AbsCount = (UINTN)ABS(Count);\r
632820d1 260 Line = _HLineRetreat (AbsCount);\r
261 } else {\r
33c031ee 262 Line = _HLineAdvance ((UINTN)Count);\r
632820d1 263 }\r
264\r
265 return Line;\r
266}\r
267\r
268HEFI_EDITOR_LINE *\r
269HMoveCurrentLine (\r
270 IN INTN Count\r
271 )\r
272/*++\r
273\r
274Routine Description: \r
275\r
276 Advance/Retreat lines and set CurrentLine in BufferImage to it\r
277\r
278Arguments: \r
279\r
280 Count -- line number to advance/retreat\r
281 >0 : advance\r
282 <0: retreat\r
283\r
284Returns: \r
285\r
286 NULL -- wrong\r
287 Not NULL -- line after advance\r
288\r
289\r
290--*/\r
291{\r
292 HEFI_EDITOR_LINE *Line;\r
293 UINTN AbsCount;\r
294\r
295 //\r
296 // <0: retreat\r
297 // >0: advance\r
298 //\r
299 if (Count <= 0) {\r
33c031ee 300 AbsCount = (UINTN)ABS(Count);\r
632820d1 301 Line = _HLineRetreat (AbsCount);\r
302 } else {\r
33c031ee 303 Line = _HLineAdvance ((UINTN)Count);\r
632820d1 304 }\r
305\r
306 if (Line == NULL) {\r
307 return NULL;\r
308 }\r
309\r
310 HMainEditor.BufferImage->CurrentLine = Line;\r
311\r
312 return Line;\r
313}\r
314\r
315\r
316EFI_STATUS\r
317HFreeLines (\r
318 IN LIST_ENTRY *ListHead,\r
319 IN HEFI_EDITOR_LINE *Lines\r
320 )\r
321/*++\r
322\r
323Routine Description: \r
324\r
325 Free all the lines in HBufferImage\r
326 Fields affected:\r
327 Lines\r
328 CurrentLine\r
329 NumLines\r
330 ListHead \r
331\r
332Arguments: \r
333\r
334 ListHead - The list head\r
335 Lines - The lines\r
336\r
337Returns: \r
338\r
339 EFI_SUCCESS\r
340\r
341--*/\r
342{\r
343 LIST_ENTRY *Link;\r
344 HEFI_EDITOR_LINE *Line;\r
345\r
346 //\r
347 // release all the lines\r
348 //\r
349 if (Lines != NULL) {\r
350\r
351 Line = Lines;\r
352 Link = &(Line->Link);\r
353 do {\r
354 Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);\r
355 Link = Link->ForwardLink;\r
356 HLineFree (Line);\r
357 } while (Link != ListHead);\r
358 }\r
359\r
360 ListHead->ForwardLink = ListHead;\r
361 ListHead->BackLink = ListHead;\r
362\r
363 return EFI_SUCCESS;\r
364}\r
365\r
366UINTN\r
367HStrStr (\r
368 IN CHAR16 *Str,\r
369 IN CHAR16 *Pat\r
370 )\r
371/*++\r
372\r
373Routine Description: \r
374\r
375 Search Pat in Str\r
376\r
377Arguments: \r
378\r
379 Str -- mother string\r
380 Pat -- search pattern\r
381\r
382\r
383Returns: \r
384\r
385 0 : not found\r
386 >= 1 : found position + 1\r
387\r
388--*/\r
389{\r
390 INTN *Failure;\r
391 INTN i;\r
392 INTN j;\r
393 INTN Lenp;\r
394 INTN Lens;\r
395\r
396 //\r
397 // this function copies from some lib\r
398 //\r
399 Lenp = StrLen (Pat);\r
400 Lens = StrLen (Str);\r
401\r
33c031ee 402 Failure = AllocateZeroPool ((UINTN)(Lenp * sizeof (INTN)));\r
403 if (Failure == NULL) {\r
404 return 0;\r
405 }\r
632820d1 406 Failure[0] = -1;\r
407 for (j = 1; j < Lenp; j++) {\r
408 i = Failure[j - 1];\r
409 while ((Pat[j] != Pat[i + 1]) && (i >= 0)) {\r
410 i = Failure[i];\r
411 }\r
412\r
413 if (Pat[j] == Pat[i + 1]) {\r
414 Failure[j] = i + 1;\r
415 } else {\r
416 Failure[j] = -1;\r
417 }\r
418 }\r
419\r
420 i = 0;\r
421 j = 0;\r
422 while (i < Lens && j < Lenp) {\r
423 if (Str[i] == Pat[j]) {\r
424 i++;\r
425 j++;\r
426 } else if (j == 0) {\r
427 i++;\r
428 } else {\r
429 j = Failure[j - 1] + 1;\r
430 }\r
431 }\r
432\r
433 FreePool (Failure);\r
434\r
435 //\r
436 // 0: not found\r
437 // >=1 : found position + 1\r
438 //\r
439 return ((j == Lenp) ? (i - Lenp) : -1) + 1;\r
440\r
441}\r
442\r
443INT32\r
444HGetTextX (\r
445 IN INT32 GuidX\r
446 )\r
447{\r
448 INT32 Gap;\r
449\r
450 HMainEditor.MouseAccumulatorX += GuidX;\r
451 Gap = (HMainEditor.MouseAccumulatorX * (INT32) HMainEditor.ScreenSize.Column) / (INT32) (50 * (INT32) HMainEditor.MouseInterface->Mode->ResolutionX);\r
452 HMainEditor.MouseAccumulatorX = (HMainEditor.MouseAccumulatorX * (INT32) HMainEditor.ScreenSize.Column) % (INT32) (50 * (INT32) HMainEditor.MouseInterface->Mode->ResolutionX);\r
453 HMainEditor.MouseAccumulatorX = HMainEditor.MouseAccumulatorX / (INT32) HMainEditor.ScreenSize.Column;\r
454 return Gap;\r
455}\r
456\r
457INT32\r
458HGetTextY (\r
459 IN INT32 GuidY\r
460 )\r
461{\r
462 INT32 Gap;\r
463\r
464 HMainEditor.MouseAccumulatorY += GuidY;\r
465 Gap = (HMainEditor.MouseAccumulatorY * (INT32) HMainEditor.ScreenSize.Row) / (INT32) (50 * (INT32) HMainEditor.MouseInterface->Mode->ResolutionY);\r
466 HMainEditor.MouseAccumulatorY = (HMainEditor.MouseAccumulatorY * (INT32) HMainEditor.ScreenSize.Row) % (INT32) (50 * (INT32) HMainEditor.MouseInterface->Mode->ResolutionY);\r
467 HMainEditor.MouseAccumulatorY = HMainEditor.MouseAccumulatorY / (INT32) HMainEditor.ScreenSize.Row;\r
468\r
469 return Gap;\r
470}\r
471\r
472EFI_STATUS\r
473HXtoi (\r
474 IN CHAR16 *Str,\r
475 OUT UINTN *Value\r
476 )\r
477/*++\r
478Routine Description:\r
479\r
480 convert hex string to uint\r
481 \r
482Arguments:\r
483\r
484 Str - The string\r
485 Value - The value\r
486\r
487Returns:\r
488\r
489\r
490--*/\r
491{\r
492 UINT64 u;\r
493 CHAR16 c;\r
494 UINTN Size;\r
495\r
496 Size = sizeof (UINTN);\r
497\r
498 //\r
499 // skip leading white space\r
500 //\r
501 while (*Str && *Str == ' ') {\r
502 Str += 1;\r
503 }\r
504\r
505 if (StrLen (Str) > Size * 2) {\r
506 return EFI_LOAD_ERROR;\r
507 }\r
508 //\r
509 // convert hex digits\r
510 //\r
511 u = 0;\r
512 c = *Str;\r
513 while (c) {\r
514 c = *Str;\r
515 Str++;\r
516\r
517 if (c == 0) {\r
518 break;\r
519 }\r
520 //\r
521 // not valid char\r
522 //\r
523 if (!((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') || (c >= '0' && c <= '9') || (c == '\0'))) {\r
524 return EFI_LOAD_ERROR;\r
525 }\r
526\r
527 if (c >= 'a' && c <= 'f') {\r
528 c -= 'a' - 'A';\r
529 }\r
530\r
531 if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')) {\r
532 u = LShiftU64 (u, 4) + (c - (c >= 'A' ? 'A' - 10 : '0'));\r
533 } else {\r
534 //\r
535 // '\0'\r
536 //\r
537 break;\r
538 }\r
539 }\r
540\r
541 *Value = (UINTN) u;\r
542\r
543 return EFI_SUCCESS;\r
544}\r