mirror of
https://github.com/acidanthera/OpenCorePkg.git
synced 2025-12-08 19:25:01 +00:00
Add export to OcXmlLib
This commit is contained in:
parent
c43916be47
commit
9ce5f7b29d
4
.gitignore
vendored
4
.gitignore
vendored
@ -2,8 +2,10 @@
|
||||
UDK
|
||||
Binaries
|
||||
*.dSYM
|
||||
TestsUser/Serialized/Serialized
|
||||
TestsUser/Macho/Macho
|
||||
TestsUser/Prelinked/Prelinked
|
||||
TestsUser/Prelinked/Result.xml
|
||||
TestsUser/Serialized/Serialized
|
||||
TestsUser/Smbios/Smbios
|
||||
DICT
|
||||
fuzz-*.log
|
||||
|
||||
@ -116,11 +116,25 @@ typedef struct XML_NODE_ XML_NODE;
|
||||
// @return The parsed xml fragment iff parsing was successful, 0 otherwise
|
||||
//
|
||||
XML_DOCUMENT *
|
||||
XmlParseDocument (
|
||||
XmlDocumentParse (
|
||||
CHAR8 *Buffer,
|
||||
UINT32 Length
|
||||
);
|
||||
|
||||
//
|
||||
// Exports parsed document into the buffer.
|
||||
//
|
||||
// @param Document XML_DOCUMENT to export
|
||||
// @param Length Resulting length of the buffer without trailing \0 (optional)
|
||||
//
|
||||
// @return Exported buffer allocated from pool or NULL.
|
||||
//
|
||||
CHAR8 *
|
||||
XmlDocumentExport (
|
||||
XML_DOCUMENT *Document,
|
||||
UINT32 *Length
|
||||
);
|
||||
|
||||
//
|
||||
// Frees all resources associated with the document. All XML_NODE
|
||||
// references obtained through the document will be invalidated.
|
||||
|
||||
@ -84,7 +84,7 @@ GetAppleRecoveryNameFromPlist (
|
||||
CHAR16 *RecoveryName;
|
||||
UINTN RecoveryNameSize;
|
||||
|
||||
Document = XmlParseDocument (SystemVersionData, (UINT32) SystemVersionDataSize);
|
||||
Document = XmlDocumentParse (SystemVersionData, (UINT32) SystemVersionDataSize);
|
||||
|
||||
if (Document == NULL) {
|
||||
return NULL;
|
||||
|
||||
@ -311,7 +311,7 @@ ParseSerialized (
|
||||
XML_DOCUMENT *Document;
|
||||
XML_NODE *RootDict;
|
||||
|
||||
Document = XmlParseDocument (PlistBuffer, PlistSize);
|
||||
Document = XmlDocumentParse (PlistBuffer, PlistSize);
|
||||
|
||||
if (Document == NULL) {
|
||||
DEBUG ((DEBUG_INFO, "Couldn't parse serialized file!\n"));
|
||||
|
||||
@ -47,6 +47,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#include <Library/OcMiscLib.h>
|
||||
#include <Library/OcStringLib.h>
|
||||
|
||||
//
|
||||
// Minimal extra allocation size during export.
|
||||
//
|
||||
#define XML_EXPORT_MIN_ALLOCATION_SIZE 4096
|
||||
|
||||
struct XML_NODE_LIST_;
|
||||
struct XML_PARSER_;
|
||||
|
||||
@ -54,8 +59,8 @@ typedef struct XML_NODE_LIST_ XML_NODE_LIST;
|
||||
typedef struct XML_PARSER_ XML_PARSER;
|
||||
|
||||
//
|
||||
// An XML_NODE will always contain a tag name and a 0-terminated list of
|
||||
// children. Moreover it may contain text content.
|
||||
// An XML_NODE will always contain a tag name and possibly a list of
|
||||
// children or text content.
|
||||
//
|
||||
struct XML_NODE_ {
|
||||
CONST CHAR8 *Name;
|
||||
@ -295,7 +300,7 @@ XmlParserError (
|
||||
#define XML_PARSER_ERROR(Parser, Offset, Message) \
|
||||
XmlParserError (Parser, Offset, Message)
|
||||
#define XML_USAGE_ERROR(Message) \
|
||||
DEBUG ((DEBUG_VERBOSE, "XML_PARSER_TAG %a\n", Message));
|
||||
DEBUG ((DEBUG_VERBOSE, "%a\n", Message));
|
||||
#else
|
||||
#define XML_PARSER_ERROR(Parser, Offset, Message) do {} while (0)
|
||||
#define XML_USAGE_ERROR(X) do {} while (0)
|
||||
@ -655,6 +660,86 @@ XmlParseContent (
|
||||
return &Parser->Buffer[Start];
|
||||
}
|
||||
|
||||
//
|
||||
// Prints to growing buffer always preserving one byte extra.
|
||||
//
|
||||
STATIC
|
||||
VOID
|
||||
XmlBufferAppend (
|
||||
CHAR8 **Buffer,
|
||||
UINT32 *AllocSize,
|
||||
UINT32 *CurrentSize,
|
||||
CONST CHAR8 *Data,
|
||||
UINT32 DataLength
|
||||
)
|
||||
{
|
||||
CHAR8 *NewBuffer;
|
||||
UINT32 NewSize;
|
||||
|
||||
NewSize = *AllocSize;
|
||||
|
||||
if (NewSize - *CurrentSize <= DataLength) {
|
||||
if (DataLength + 1 <= XML_EXPORT_MIN_ALLOCATION_SIZE) {
|
||||
NewSize += XML_EXPORT_MIN_ALLOCATION_SIZE;
|
||||
} else {
|
||||
NewSize += DataLength + 1;
|
||||
}
|
||||
|
||||
NewBuffer = AllocatePool (NewSize);
|
||||
if (NewBuffer == NULL) {
|
||||
XML_USAGE_ERROR("XmlBufferAppend::failed to allocate");
|
||||
return;
|
||||
}
|
||||
|
||||
CopyMem (NewBuffer, *Buffer, *CurrentSize);
|
||||
FreePool (*Buffer);
|
||||
*Buffer = NewBuffer;
|
||||
*AllocSize = NewSize;
|
||||
}
|
||||
|
||||
CopyMem (&(*Buffer)[*CurrentSize], Data, DataLength);
|
||||
*CurrentSize += DataLength;
|
||||
}
|
||||
|
||||
//
|
||||
// Prints node to growing buffer always preserving one byte extra.
|
||||
//
|
||||
STATIC
|
||||
VOID
|
||||
XmlNodeExportRecursive (
|
||||
XML_NODE *Node,
|
||||
CHAR8 **Buffer,
|
||||
UINT32 *AllocSize,
|
||||
UINT32 *CurrentSize
|
||||
)
|
||||
{
|
||||
UINT32 Index;
|
||||
UINT32 NameLength;
|
||||
|
||||
NameLength = AsciiStrLen (Node->Name);
|
||||
|
||||
XmlBufferAppend (Buffer, AllocSize, CurrentSize, "<", L_STR_LEN ("<"));
|
||||
XmlBufferAppend (Buffer, AllocSize, CurrentSize, Node->Name, NameLength);
|
||||
|
||||
if (Node->Children != NULL || Node->Content != NULL) {
|
||||
XmlBufferAppend (Buffer, AllocSize, CurrentSize, ">", L_STR_LEN (">"));
|
||||
|
||||
if (Node->Children != NULL) {
|
||||
for (Index = 0; Index < Node->Children->NodeCount; ++Index) {
|
||||
XmlNodeExportRecursive (Node->Children->NodeList[Index], Buffer, AllocSize, CurrentSize);
|
||||
}
|
||||
} else {
|
||||
XmlBufferAppend (Buffer, AllocSize, CurrentSize, Node->Content, AsciiStrLen (Node->Content));
|
||||
}
|
||||
|
||||
XmlBufferAppend (Buffer, AllocSize, CurrentSize, "</", L_STR_LEN ("</"));
|
||||
XmlBufferAppend (Buffer, AllocSize, CurrentSize, Node->Name, NameLength);
|
||||
XmlBufferAppend (Buffer, AllocSize, CurrentSize, ">", L_STR_LEN (">"));
|
||||
} else {
|
||||
XmlBufferAppend (Buffer, AllocSize, CurrentSize, "/>", L_STR_LEN ("/>"));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Parses an XML fragment node.
|
||||
//
|
||||
@ -789,7 +874,7 @@ XmlParseNode (
|
||||
}
|
||||
|
||||
XML_DOCUMENT *
|
||||
XmlParseDocument (
|
||||
XmlDocumentParse (
|
||||
CHAR8 *Buffer,
|
||||
UINT32 Length
|
||||
)
|
||||
@ -809,7 +894,7 @@ XmlParseDocument (
|
||||
// An empty buffer can never contain a valid document.
|
||||
//
|
||||
if (Length == 0 || Length > XML_PARSER_MAX_SIZE) {
|
||||
XML_PARSER_ERROR (&Parser, NO_CHARACTER, "XmlParseDocument::length is too small or too large");
|
||||
XML_PARSER_ERROR (&Parser, NO_CHARACTER, "XmlDocumentParse::length is too small or too large");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -818,7 +903,7 @@ XmlParseDocument (
|
||||
//
|
||||
Root = XmlParseNode (&Parser);
|
||||
if (Root == NULL) {
|
||||
XML_PARSER_ERROR (&Parser, NO_CHARACTER, "XmlParseDocument::parsing document failed");
|
||||
XML_PARSER_ERROR (&Parser, NO_CHARACTER, "XmlDocumentParse::parsing document failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -828,7 +913,7 @@ XmlParseDocument (
|
||||
Document = AllocatePool (sizeof(XML_DOCUMENT));
|
||||
|
||||
if (Document == NULL) {
|
||||
XML_PARSER_ERROR (&Parser, NO_CHARACTER, "XmlParseDocument::document allocation failed");
|
||||
XML_PARSER_ERROR (&Parser, NO_CHARACTER, "XmlDocumentParse::document allocation failed");
|
||||
XmlNodeFree (Root);
|
||||
return NULL;
|
||||
}
|
||||
@ -840,6 +925,38 @@ XmlParseDocument (
|
||||
return Document;
|
||||
}
|
||||
|
||||
CHAR8 *
|
||||
XmlDocumentExport (
|
||||
XML_DOCUMENT *Document,
|
||||
UINT32 *Length
|
||||
)
|
||||
{
|
||||
CHAR8 *Buffer;
|
||||
UINT32 AllocSize;
|
||||
UINT32 CurrentSize;
|
||||
|
||||
AllocSize = Document->Buffer.Length + 1;
|
||||
Buffer = AllocatePool (AllocSize);
|
||||
if (Buffer == NULL) {
|
||||
XML_USAGE_ERROR ("XmlDocumentExport::failed to allocate");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CurrentSize = 0;
|
||||
XmlNodeExportRecursive (Document->Root, &Buffer, &AllocSize, &CurrentSize);
|
||||
|
||||
if (Length != NULL) {
|
||||
*Length = CurrentSize;
|
||||
}
|
||||
|
||||
//
|
||||
// XmlBufferAppend guarantees one more byte.
|
||||
//
|
||||
Buffer[CurrentSize] = '\0';
|
||||
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
VOID
|
||||
XmlDocumentFree (
|
||||
XML_DOCUMENT *Document
|
||||
|
||||
108
TestsUser/Prelinked/Prelinked.c
Normal file
108
TestsUser/Prelinked/Prelinked.c
Normal file
@ -0,0 +1,108 @@
|
||||
/** @file
|
||||
Copyright (C) 2018, vit9696. All rights reserved.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
**/
|
||||
|
||||
#include <Library/OcTemplateLib.h>
|
||||
#include <Library/OcSerializeLib.h>
|
||||
#include <Library/OcMiscLib.h>
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
/*
|
||||
clang -g -fsanitize=undefined,address -I../Include -I../../Include -I../../../MdePkg/Include/ -include ../Include/Base.h Prelinked.c ../../Library/OcXmlLib/OcXmlLib.c ../../Library/OcTemplateLib/OcTemplateLib.c ../../Library/OcSerializeLib/OcSerializeLib.c ../../Library/OcMiscLib/Base64Decode.c ../../Library/OcStringLib/OcAsciiLib.c -o Prelinked
|
||||
|
||||
for fuzzing:
|
||||
clang-mp-7.0 -Dmain=__main -g -fsanitize=undefined,address,fuzzer -I../Include -I../../Include -I../../../MdePkg/Include/ -include ../Include/Base.h Prelinked.c ../../Library/OcXmlLib/OcXmlLib.c ../../Library/OcTemplateLib/OcTemplateLib.c ../../Library/OcSerializeLib/OcSerializeLib.c ../../Library/OcMiscLib/Base64Decode.c ../../Library/OcStringLib/OcAsciiLib.c -o Prelinked
|
||||
rm -rf DICT fuzz*.log ; mkdir DICT ; cp Prelinked.plist DICT ; ./Prelinked -jobs=4 DICT
|
||||
|
||||
rm -rf Prelinked.dSYM DICT fuzz*.log Prelinked
|
||||
*/
|
||||
|
||||
long long current_timestamp() {
|
||||
struct timeval te;
|
||||
gettimeofday(&te, NULL); // get current time
|
||||
long long milliseconds = te.tv_sec*1000LL + te.tv_usec/1000; // calculate milliseconds
|
||||
// printf("milliseconds: %lld\n", milliseconds);
|
||||
return milliseconds;
|
||||
}
|
||||
|
||||
uint8_t *readFile(const char *str, uint32_t *size) {
|
||||
FILE *f = fopen(str, "rb");
|
||||
|
||||
if (!f) return NULL;
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
long fsize = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
uint8_t *string = malloc(fsize + 1);
|
||||
fread(string, fsize, 1, f);
|
||||
fclose(f);
|
||||
|
||||
string[fsize] = 0;
|
||||
*size = fsize;
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
uint32_t f;
|
||||
uint8_t *b;
|
||||
if ((b = readFile(argc > 1 ? argv[1] : "Prelinked.xml", &f)) == NULL) {
|
||||
printf("Read fail\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
XML_DOCUMENT *doc = XmlDocumentParse((char *)b, f);
|
||||
|
||||
if (doc == NULL) {
|
||||
printf("Parse fail\n");
|
||||
return -2;
|
||||
}
|
||||
|
||||
UINT32 s;
|
||||
CHAR8 *buf = XmlDocumentExport(doc, &s);
|
||||
|
||||
if (buf != NULL) {
|
||||
printf("Exported into %u bytes:\n\n\n", s);
|
||||
printf("%s\n", buf);
|
||||
FreePool (buf);
|
||||
} else {
|
||||
printf("Exporting gave NULL\n");
|
||||
}
|
||||
|
||||
XmlDocumentFree (doc);
|
||||
|
||||
free(b);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT32 LLVMFuzzerTestOneInput(CONST UINT8 *Data, UINTN Size) {
|
||||
VOID *NewData = AllocatePool (Size);
|
||||
if (NewData) {
|
||||
CopyMem (NewData, Data, Size);
|
||||
XML_DOCUMENT *doc = XmlDocumentParse((char *)NewData, Size);
|
||||
if (doc != NULL) {
|
||||
UINT32 s;
|
||||
CHAR8 *buf = XmlDocumentExport(doc, &s);
|
||||
if (buf != NULL) {
|
||||
FreePool (buf);
|
||||
}
|
||||
XmlDocumentFree (doc);
|
||||
}
|
||||
FreePool (NewData);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
4
TestsUser/Prelinked/Prelinked.xml
Normal file
4
TestsUser/Prelinked/Prelinked.xml
Normal file
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user