TianoCore EDK2 master
Loading...
Searching...
No Matches
RegularExpressionDxe.c
Go to the documentation of this file.
1
12
14EFI_REGEX_SYNTAX_TYPE *CONST mSupportedSyntaxes[] = {
15 &gEfiRegexSyntaxTypePosixExtendedGuid,
16 &gEfiRegexSyntaxTypePerlGuid
17};
18
20EFI_REGULAR_EXPRESSION_PROTOCOL mProtocolInstance = {
23};
24
25#define CHAR16_ENCODING ONIG_ENCODING_UTF16_LE
26
70 IN CHAR16 *String,
71 IN CHAR16 *Pattern,
72 IN EFI_REGEX_SYNTAX_TYPE *SyntaxType,
73 OUT BOOLEAN *Result,
74 OUT EFI_REGEX_CAPTURE **Captures OPTIONAL,
75 OUT UINTN *CapturesCount
76 )
77{
78 regex_t *OnigRegex;
79 OnigSyntaxType *OnigSyntax;
80 OnigRegion *Region;
81 INT32 OnigResult;
82 OnigErrorInfo ErrorInfo;
83 OnigUChar ErrorMessage[ONIG_MAX_ERROR_MESSAGE_LEN];
84 UINT32 Index;
85 OnigUChar *Start;
86 EFI_STATUS Status;
87
88 Status = EFI_SUCCESS;
89
90 //
91 // Detemine the internal syntax type
92 //
93 OnigSyntax = ONIG_SYNTAX_DEFAULT;
94 if (CompareGuid (SyntaxType, &gEfiRegexSyntaxTypePosixExtendedGuid)) {
95 OnigSyntax = ONIG_SYNTAX_POSIX_EXTENDED;
96 } else if (CompareGuid (SyntaxType, &gEfiRegexSyntaxTypePerlGuid)) {
97 OnigSyntax = ONIG_SYNTAX_PERL;
98 } else {
99 DEBUG ((DEBUG_ERROR, "Unsupported regex syntax - using default\n"));
100 return EFI_UNSUPPORTED;
101 }
102
103 //
104 // Compile pattern
105 //
106 Start = (OnigUChar *)Pattern;
107 OnigResult = onig_new (
108 &OnigRegex,
109 Start,
110 Start + onigenc_str_bytelen_null (CHAR16_ENCODING, Start),
111 ONIG_OPTION_DEFAULT,
112 CHAR16_ENCODING,
113 OnigSyntax,
114 &ErrorInfo
115 );
116
117 if (OnigResult != ONIG_NORMAL) {
118 onig_error_code_to_str (ErrorMessage, OnigResult, &ErrorInfo);
119 DEBUG ((DEBUG_ERROR, "Regex compilation failed: %a\n", ErrorMessage));
120 return EFI_DEVICE_ERROR;
121 }
122
123 //
124 // Try to match
125 //
126 Start = (OnigUChar *)String;
127 Region = onig_region_new ();
128 if (Region == NULL) {
129 onig_free (OnigRegex);
130 return EFI_OUT_OF_RESOURCES;
131 }
132
133 OnigResult = onig_search (
134 OnigRegex,
135 Start,
136 Start + onigenc_str_bytelen_null (CHAR16_ENCODING, Start),
137 Start,
138 Start + onigenc_str_bytelen_null (CHAR16_ENCODING, Start),
139 Region,
140 ONIG_OPTION_NONE
141 );
142
143 if (OnigResult >= 0) {
144 *Result = TRUE;
145 } else {
146 *Result = FALSE;
147 if (OnigResult != ONIG_MISMATCH) {
148 onig_error_code_to_str (ErrorMessage, OnigResult);
149 DEBUG ((DEBUG_ERROR, "Regex match failed: %a\n", ErrorMessage));
150 onig_region_free (Region, 1);
151 onig_free (OnigRegex);
152 return EFI_DEVICE_ERROR;
153 }
154 }
155
156 //
157 // If successful, copy out the region (capture) information
158 //
159 if (*Result && (Captures != NULL)) {
160 *CapturesCount = Region->num_regs;
161 *Captures = AllocateZeroPool (*CapturesCount * sizeof (**Captures));
162 if (*Captures != NULL) {
163 for (Index = 0; Index < *CapturesCount; ++Index) {
164 //
165 // Region beg/end values represent bytes, not characters
166 //
167 (*Captures)[Index].Length = (Region->end[Index] - Region->beg[Index]) / sizeof (CHAR16);
168 (*Captures)[Index].CapturePtr = AllocateCopyPool (
169 ((*Captures)[Index].Length) * sizeof (CHAR16),
170 (CHAR16 *)((UINTN)String + Region->beg[Index])
171 );
172 if ((*Captures)[Index].CapturePtr == NULL) {
173 Status = EFI_OUT_OF_RESOURCES;
174 break;
175 }
176 }
177
178 if (EFI_ERROR (Status)) {
179 for (Index = 0; Index < *CapturesCount; ++Index) {
180 if ((*Captures)[Index].CapturePtr != NULL) {
181 FreePool ((CHAR16 *)(*Captures)[Index].CapturePtr);
182 }
183 }
184
185 FreePool (*Captures);
186 }
187 }
188 }
189
190 onig_region_free (Region, 1);
191 onig_free (OnigRegex);
192
193 return Status;
194}
195
229EFIAPI
232 IN OUT UINTN *RegExSyntaxTypeListSize,
233 OUT EFI_REGEX_SYNTAX_TYPE *RegExSyntaxTypeList
234 )
235{
236 UINTN SyntaxSize;
237 UINTN Index;
238
239 if ((This == NULL) || (RegExSyntaxTypeListSize == NULL)) {
240 return EFI_INVALID_PARAMETER;
241 }
242
243 if ((*RegExSyntaxTypeListSize != 0) && (RegExSyntaxTypeList == NULL)) {
244 return EFI_INVALID_PARAMETER;
245 }
246
247 SyntaxSize = ARRAY_SIZE (mSupportedSyntaxes) * sizeof (**mSupportedSyntaxes);
248
249 if (*RegExSyntaxTypeListSize < SyntaxSize) {
250 *RegExSyntaxTypeListSize = SyntaxSize;
251 return EFI_BUFFER_TOO_SMALL;
252 }
253
254 for (Index = 0; Index < ARRAY_SIZE (mSupportedSyntaxes); ++Index) {
255 CopyMem (&RegExSyntaxTypeList[Index], mSupportedSyntaxes[Index], sizeof (**mSupportedSyntaxes));
256 }
257
258 *RegExSyntaxTypeListSize = SyntaxSize;
259
260 return EFI_SUCCESS;
261}
262
313EFIAPI
316 IN CHAR16 *String,
317 IN CHAR16 *Pattern,
318 IN EFI_REGEX_SYNTAX_TYPE *SyntaxType OPTIONAL,
319 OUT BOOLEAN *Result,
320 OUT EFI_REGEX_CAPTURE **Captures OPTIONAL,
321 OUT UINTN *CapturesCount
322 )
323{
324 EFI_STATUS Status;
325 UINT32 Index;
326 BOOLEAN Supported;
327
328 if ((This == NULL) || (String == NULL) || (Pattern == NULL) || (Result == NULL) || (CapturesCount == NULL)) {
329 return EFI_INVALID_PARAMETER;
330 }
331
332 //
333 // Figure out which syntax to use
334 //
335 if (SyntaxType == NULL) {
336 SyntaxType = mSupportedSyntaxes[0];
337 } else {
338 Supported = FALSE;
339 for (Index = 0; Index < ARRAY_SIZE (mSupportedSyntaxes); ++Index) {
340 if (CompareGuid (SyntaxType, mSupportedSyntaxes[Index])) {
341 Supported = TRUE;
342 break;
343 }
344 }
345
346 if (!Supported) {
347 return EFI_UNSUPPORTED;
348 }
349 }
350
351 Status = OnigurumaMatch (String, Pattern, SyntaxType, Result, Captures, CapturesCount);
352
353 return Status;
354}
355
366EFIAPI
368 IN EFI_HANDLE ImageHandle,
369 IN EFI_SYSTEM_TABLE *SystemTable
370 )
371{
372 EFI_STATUS Status;
373
374 Status = gBS->InstallMultipleProtocolInterfaces (
375 &ImageHandle,
376 &gEfiRegularExpressionProtocolGuid,
377 &mProtocolInstance,
378 NULL
379 );
380
381 return Status;
382}
UINT64 UINTN
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define ARRAY_SIZE(Array)
Definition: Base.h:1393
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
STATIC EFI_STATUS OnigurumaMatch(IN CHAR16 *String, IN CHAR16 *Pattern, IN EFI_REGEX_SYNTAX_TYPE *SyntaxType, OUT BOOLEAN *Result, OUT EFI_REGEX_CAPTURE **Captures OPTIONAL, OUT UINTN *CapturesCount)
EFI_STATUS EFIAPI RegularExpressionGetInfo(IN EFI_REGULAR_EXPRESSION_PROTOCOL *This, IN OUT UINTN *RegExSyntaxTypeListSize, OUT EFI_REGEX_SYNTAX_TYPE *RegExSyntaxTypeList)
EFI_STATUS EFIAPI RegularExpressionDxeEntry(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
EFI_STATUS EFIAPI RegularExpressionMatch(IN EFI_REGULAR_EXPRESSION_PROTOCOL *This, IN CHAR16 *String, IN CHAR16 *Pattern, IN EFI_REGEX_SYNTAX_TYPE *SyntaxType OPTIONAL, OUT BOOLEAN *Result, OUT EFI_REGEX_CAPTURE **Captures OPTIONAL, OUT UINTN *CapturesCount)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
Definition: Base.h:213