/** @file GRUB environment block parser. Copyright (c) 2021, Mike Beaton. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause **/ #include #include #include "LinuxBootInternal.h" /* grubenv processing states. */ typedef enum GRUBENV_STATE_ { GRUBENV_NEXT_LINE, GRUBENV_KEY, GRUBENV_VAR, GRUBENV_COMMENT } GRUBENV_STATE; EFI_STATUS InternalProcessGrubEnv ( IN OUT CHAR8 *Content, IN CONST UINTN Length ) { EFI_STATUS Status; UINTN Pos; UINTN KeyStart; UINTN VarStart; GRUBENV_STATE State; State = GRUBENV_NEXT_LINE; // // In a valid grubenv block the last comment, if present, is not // \n terminated, but all var lines must be. // for (Pos = 0; Pos < Length && Content[Pos] != '\0'; Pos++) { switch (State) { case GRUBENV_NEXT_LINE: if (Content[Pos] == '#') { State = GRUBENV_COMMENT; } else { KeyStart = Pos; State = GRUBENV_KEY; } break; case GRUBENV_COMMENT: if (Content[Pos] == '\n') { State = GRUBENV_NEXT_LINE; } break; case GRUBENV_KEY: if (Content[Pos] == '=') { Content[Pos] = '\0'; VarStart = Pos + 1; State = GRUBENV_VAR; } break; case GRUBENV_VAR: if (Content[Pos] == '\n') { Content[Pos] = '\0'; Status = InternalSetGrubVar (&Content[KeyStart], &Content[VarStart], VAR_ERR_NONE); if (EFI_ERROR (Status)) { return Status; } State = GRUBENV_NEXT_LINE; } break; default: ASSERT (FALSE); break; } } ASSERT (State == GRUBENV_COMMENT || State == GRUBENV_NEXT_LINE); return EFI_SUCCESS; }