/** @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;
}
