/** @file

  EFI_REGULAR_EXPRESSION_PROTOCOL Implementation

  (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "RegularExpressionDxe.h"

STATIC
EFI_REGEX_SYNTAX_TYPE * CONST mSupportedSyntaxes[] = {
  &gEfiRegexSyntaxTypePosixExtendedGuid,
  &gEfiRegexSyntaxTypePerlGuid
};

STATIC
EFI_REGULAR_EXPRESSION_PROTOCOL mProtocolInstance = {
  RegularExpressionMatch,
  RegularExpressionGetInfo
};



#define CHAR16_ENCODING ONIG_ENCODING_UTF16_LE

/**
  Call the Oniguruma regex match API.

  Same parameters as RegularExpressionMatch, except SyntaxType is required.

  @param String         A pointer to a NULL terminated string to match against the
                        regular expression string specified by Pattern.

  @param Pattern        A pointer to a NULL terminated string that represents the
                        regular expression.
  @param SyntaxType     A pointer to the EFI_REGEX_SYNTAX_TYPE that identifies the
                        regular expression syntax type to use. May be NULL in which
                        case the function will use its default regular expression
                        syntax type.

  @param Result         On return, points to TRUE if String fully matches against
                        the regular expression Pattern using the regular expression
                        SyntaxType. Otherwise, points to FALSE.

  @param Captures       A Pointer to an array of EFI_REGEX_CAPTURE objects to receive
                        the captured groups in the event of a match. The full
                        sub-string match is put in Captures[0], and the results of N
                        capturing groups are put in Captures[1:N]. If Captures is
                        NULL, then this function doesn't allocate the memory for the
                        array and does not build up the elements. It only returns the
                        number of matching patterns in CapturesCount. If Captures is
                        not NULL, this function returns a pointer to an array and
                        builds up the elements in the array. CapturesCount is also
                        updated to the number of matching patterns found. It is the
                        caller's responsibility to free the memory pool in Captures
                        and in each CapturePtr in the array elements.

  @param CapturesCount  On output, CapturesCount is the number of matching patterns
                        found in String. Zero means no matching patterns were found
                        in the string.

  @retval  EFI_SUCCESS       Regex compilation and match completed successfully.
  @retval  EFI_DEVICE_ERROR  Regex compilation failed.

**/
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
  )
{
  regex_t         *OnigRegex;
  OnigSyntaxType  *OnigSyntax;
  OnigRegion      *Region;
  INT32           OnigResult;
  OnigErrorInfo   ErrorInfo;
  OnigUChar       ErrorMessage[ONIG_MAX_ERROR_MESSAGE_LEN];
  UINT32          Index;
  OnigUChar       *Start;
  EFI_STATUS      Status;


  Status = EFI_SUCCESS;

  //
  // Detemine the internal syntax type
  //
  OnigSyntax = ONIG_SYNTAX_DEFAULT;
  if (CompareGuid (SyntaxType, &gEfiRegexSyntaxTypePosixExtendedGuid)) {
    OnigSyntax = ONIG_SYNTAX_POSIX_EXTENDED;
  } else if (CompareGuid (SyntaxType, &gEfiRegexSyntaxTypePerlGuid)) {
    OnigSyntax = ONIG_SYNTAX_PERL;
  } else {
    DEBUG ((DEBUG_ERROR, "Unsupported regex syntax - using default\n"));
    return EFI_UNSUPPORTED;
  }

  //
  // Compile pattern
  //
  Start = (OnigUChar*)Pattern;
  OnigResult = onig_new (
                 &OnigRegex,
                 Start,
                 Start + onigenc_str_bytelen_null (CHAR16_ENCODING, Start),
                 ONIG_OPTION_DEFAULT,
                 CHAR16_ENCODING,
                 OnigSyntax,
                 &ErrorInfo
                 );

  if (OnigResult != ONIG_NORMAL) {
    onig_error_code_to_str (ErrorMessage, OnigResult, &ErrorInfo);
    DEBUG ((DEBUG_ERROR, "Regex compilation failed: %a\n", ErrorMessage));
    return EFI_DEVICE_ERROR;
  }

  //
  // Try to match
  //
  Start = (OnigUChar*)String;
  Region = onig_region_new ();
  if (Region == NULL) {
    onig_free (OnigRegex);
    return EFI_OUT_OF_RESOURCES;
  }
  OnigResult = onig_search (
                 OnigRegex,
                 Start,
                 Start + onigenc_str_bytelen_null (CHAR16_ENCODING, Start),
                 Start,
                 Start + onigenc_str_bytelen_null (CHAR16_ENCODING, Start),
                 Region,
                 ONIG_OPTION_NONE
                 );

  if (OnigResult >= 0) {
    *Result = TRUE;
  } else {
    *Result = FALSE;
    if (OnigResult != ONIG_MISMATCH) {
      onig_error_code_to_str (ErrorMessage, OnigResult);
      DEBUG ((DEBUG_ERROR, "Regex match failed: %a\n", ErrorMessage));
      onig_region_free (Region, 1);
      onig_free (OnigRegex);
      return EFI_DEVICE_ERROR;
    }
  }

  //
  // If successful, copy out the region (capture) information
  //
  if (*Result && Captures != NULL) {
    *CapturesCount = Region->num_regs;
    *Captures = AllocateZeroPool (*CapturesCount * sizeof(**Captures));
    if (*Captures != NULL) {
      for (Index = 0; Index < *CapturesCount; ++Index) {
        //
        // Region beg/end values represent bytes, not characters
        //
        (*Captures)[Index].Length = (Region->end[Index] - Region->beg[Index]) / sizeof(CHAR16);
        (*Captures)[Index].CapturePtr = AllocateCopyPool (
                                          ((*Captures)[Index].Length) * sizeof (CHAR16),
                                          (CHAR16*)((UINTN)String + Region->beg[Index])
                                          );
        if ((*Captures)[Index].CapturePtr == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          break;
        }
      }

      if (EFI_ERROR (Status)) {
        for (Index = 0; Index < *CapturesCount; ++Index) {
          if ((*Captures)[Index].CapturePtr != NULL) {
            FreePool ((CHAR16*)(*Captures)[Index].CapturePtr);
          }
        }
        FreePool (*Captures);
      }
    }
  }

  onig_region_free (Region, 1);
  onig_free (OnigRegex);

  return Status;
}

/**
  Returns information about the regular expression syntax types supported
  by the implementation.

  @param This                      A pointer to the EFI_REGULAR_EXPRESSION_PROTOCOL
                                   instance.

  @param  RegExSyntaxTypeListSize  On input, the size in bytes of RegExSyntaxTypeList.
                                   On output with a return code of EFI_SUCCESS, the
                                   size in bytes of the data returned in
                                   RegExSyntaxTypeList. On output with a return code
                                   of EFI_BUFFER_TOO_SMALL, the size of
                                   RegExSyntaxTypeList required to obtain the list.

  @param   RegExSyntaxTypeList     A caller-allocated memory buffer filled by the
                                   driver with one EFI_REGEX_SYNTAX_TYPE element
                                   for each supported Regular expression syntax
                                   type. The list must not change across multiple
                                   calls to the same driver. The first syntax
                                   type in the list is the default type for the
                                   driver.

  @retval EFI_SUCCESS            The regular expression syntax types list
                                 was returned successfully.
  @retval EFI_UNSUPPORTED        The service is not supported by this driver.
  @retval EFI_DEVICE_ERROR       The list of syntax types could not be
                                 retrieved due to a hardware or firmware error.
  @retval EFI_BUFFER_TOO_SMALL   The buffer RegExSyntaxTypeList is too small
                                 to hold the result.
  @retval EFI_INVALID_PARAMETER  RegExSyntaxTypeListSize is NULL

**/
EFI_STATUS
EFIAPI
RegularExpressionGetInfo (
  IN     EFI_REGULAR_EXPRESSION_PROTOCOL *This,
  IN OUT UINTN                           *RegExSyntaxTypeListSize,
  OUT    EFI_REGEX_SYNTAX_TYPE           *RegExSyntaxTypeList
  )
{
  UINTN SyntaxSize;
  UINTN Index;

  if (This == NULL || RegExSyntaxTypeListSize == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (*RegExSyntaxTypeListSize != 0 && RegExSyntaxTypeList == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  SyntaxSize = ARRAY_SIZE (mSupportedSyntaxes) * sizeof(**mSupportedSyntaxes);

  if (*RegExSyntaxTypeListSize < SyntaxSize) {
    *RegExSyntaxTypeListSize = SyntaxSize;
    return EFI_BUFFER_TOO_SMALL;
  }

  for (Index = 0; Index < ARRAY_SIZE (mSupportedSyntaxes); ++Index) {
    CopyMem (&RegExSyntaxTypeList[Index], mSupportedSyntaxes[Index], sizeof(**mSupportedSyntaxes));
  }
  *RegExSyntaxTypeListSize = SyntaxSize;

  return EFI_SUCCESS;
}

/**
  Checks if the input string matches to the regular expression pattern.

  @param This          A pointer to the EFI_REGULAR_EXPRESSION_PROTOCOL instance.
                       Type EFI_REGULAR_EXPRESSION_PROTOCOL is defined in Section
                       XYZ.

  @param String        A pointer to a NULL terminated string to match against the
                       regular expression string specified by Pattern.

  @param Pattern       A pointer to a NULL terminated string that represents the
                       regular expression.

  @param SyntaxType    A pointer to the EFI_REGEX_SYNTAX_TYPE that identifies the
                       regular expression syntax type to use. May be NULL in which
                       case the function will use its default regular expression
                       syntax type.

  @param Result        On return, points to TRUE if String fully matches against
                       the regular expression Pattern using the regular expression
                       SyntaxType. Otherwise, points to FALSE.

  @param Captures      A Pointer to an array of EFI_REGEX_CAPTURE objects to receive
                       the captured groups in the event of a match. The full
                       sub-string match is put in Captures[0], and the results of N
                       capturing groups are put in Captures[1:N]. If Captures is
                       NULL, then this function doesn't allocate the memory for the
                       array and does not build up the elements. It only returns the
                       number of matching patterns in CapturesCount. If Captures is
                       not NULL, this function returns a pointer to an array and
                       builds up the elements in the array. CapturesCount is also
                       updated to the number of matching patterns found. It is the
                       caller's responsibility to free the memory pool in Captures
                       and in each CapturePtr in the array elements.

  @param CapturesCount On output, CapturesCount is the number of matching patterns
                       found in String. Zero means no matching patterns were found
                       in the string.

  @retval EFI_SUCCESS            The regular expression string matching
                                 completed successfully.
  @retval EFI_UNSUPPORTED        The regular expression syntax specified by
                                 SyntaxType is not supported by this driver.
  @retval EFI_DEVICE_ERROR       The regular expression string matching
                                 failed due to a hardware or firmware error.
  @retval EFI_INVALID_PARAMETER  String, Pattern, Result, or CapturesCountis
                                 NULL.

**/
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
  )
{
  EFI_STATUS  Status;
  UINT32      Index;
  BOOLEAN     Supported;

  if (This == NULL || String == NULL || Pattern == NULL || Result == NULL || CapturesCount == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Figure out which syntax to use
  //
  if (SyntaxType == NULL) {
    SyntaxType = mSupportedSyntaxes[0];
  } else {
    Supported = FALSE;
    for (Index = 0; Index < ARRAY_SIZE (mSupportedSyntaxes); ++Index) {
      if (CompareGuid (SyntaxType, mSupportedSyntaxes[Index])) {
        Supported = TRUE;
        break;
      }
    }
    if (!Supported) {
      return EFI_UNSUPPORTED;
    }
  }

  Status = OnigurumaMatch (String, Pattern, SyntaxType, Result, Captures, CapturesCount);

  return Status;
}

/**
  Entry point for RegularExpressionDxe.

  @param ImageHandle     Image handle this driver.
  @param SystemTable     Pointer to SystemTable.

  @retval Status         Whether this function complete successfully.

**/
EFI_STATUS
EFIAPI
RegularExpressionDxeEntry (
  IN  EFI_HANDLE        ImageHandle,
  IN  EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;

  Status = gBS->InstallMultipleProtocolInterfaces (
                  &ImageHandle,
                  &gEfiRegularExpressionProtocolGuid,
                  &mProtocolInstance,
                  NULL
                  );

  return Status;
}
