Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[4.2] Add support for reading text resource format 4 #91250

Merged
merged 1 commit into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 78 additions & 1 deletion core/variant/variant_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

#include "variant_parser.h"

#include "core/crypto/crypto_core.h"
#include "core/input/input_event.h"
#include "core/io/resource_loader.h"
#include "core/object/script_language.h"
Expand Down Expand Up @@ -595,6 +596,82 @@ Error VariantParser::_parse_construct(Stream *p_stream, Vector<T> &r_construct,
return OK;
}

Error VariantParser::_parse_byte_array(Stream *p_stream, Vector<uint8_t> &r_construct, int &line, String &r_err_str) {
Token token;
get_token(p_stream, token, line, r_err_str);
if (token.type != TK_PARENTHESIS_OPEN) {
r_err_str = "Expected '(' in constructor";
return ERR_PARSE_ERROR;
}

get_token(p_stream, token, line, r_err_str);
if (token.type == TK_STRING) {
// Base64 encoded array.
String base64_encoded_string = token.value;
int strlen = base64_encoded_string.length();
CharString cstr = base64_encoded_string.ascii();

size_t arr_len = 0;
r_construct.resize(strlen / 4 * 3 + 1);
uint8_t *w = r_construct.ptrw();
Error err = CryptoCore::b64_decode(&w[0], r_construct.size(), &arr_len, (unsigned char *)cstr.get_data(), strlen);
if (err) {
r_err_str = "Invalid base64-encoded string";
return ERR_PARSE_ERROR;
}
r_construct.resize(arr_len);

get_token(p_stream, token, line, r_err_str);
if (token.type != TK_PARENTHESIS_CLOSE) {
r_err_str = "Expected ')' in constructor";
return ERR_PARSE_ERROR;
}

} else if (token.type == TK_NUMBER || token.type == TK_IDENTIFIER) {
// Individual elements.
while (true) {
if (token.type != TK_NUMBER) {
bool valid = false;
if (token.type == TK_IDENTIFIER) {
double real = stor_fix(token.value);
if (real != -1) {
token.type = TK_NUMBER;
token.value = real;
valid = true;
}
}
if (!valid) {
r_err_str = "Expected number in constructor";
return ERR_PARSE_ERROR;
}
}

r_construct.push_back(token.value);

get_token(p_stream, token, line, r_err_str);

if (token.type == TK_COMMA) {
//do none
} else if (token.type == TK_PARENTHESIS_CLOSE) {
break;
} else {
r_err_str = "Expected ',' or ')' in constructor";
return ERR_PARSE_ERROR;
}

get_token(p_stream, token, line, r_err_str);
}
} else if (token.type == TK_PARENTHESIS_CLOSE) {
// Empty array.
return OK;
} else {
r_err_str = "Expected base64 string, or list of numbers in constructor";
return ERR_PARSE_ERROR;
}

return OK;
}

Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, int &line, String &r_err_str, ResourceParser *p_res_parser) {
if (token.type == TK_CURLY_BRACKET_OPEN) {
Dictionary d;
Expand Down Expand Up @@ -1148,7 +1225,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
value = array;
} else if (id == "PackedByteArray" || id == "PoolByteArray" || id == "ByteArray") {
Vector<uint8_t> args;
Error err = _parse_construct<uint8_t>(p_stream, args, line, r_err_str);
Error err = _parse_byte_array(p_stream, args, line, r_err_str);
if (err) {
return err;
}
Expand Down
1 change: 1 addition & 0 deletions core/variant/variant_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ class VariantParser {

template <class T>
static Error _parse_construct(Stream *p_stream, Vector<T> &r_construct, int &line, String &r_err_str);
static Error _parse_byte_array(Stream *p_stream, Vector<uint8_t> &r_construct, int &line, String &r_err_str);
static Error _parse_enginecfg(Stream *p_stream, Vector<String> &strings, int &line, String &r_err_str);
static Error _parse_dictionary(Dictionary &object, Stream *p_stream, int &line, String &r_err_str, ResourceParser *p_res_parser = nullptr);
static Error _parse_array(Array &array, Stream *p_stream, int &line, String &r_err_str, ResourceParser *p_res_parser = nullptr);
Expand Down
8 changes: 5 additions & 3 deletions scene/resources/resource_format_text.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@

// Version 2: changed names for Basis, AABB, Vectors, etc.
// Version 3: new string ID for ext/subresources, breaks forward compat.
// Version 4: PackedByteArray is now stored as base64 encoded.
#define FORMAT_VERSION 3
#define FORMAT_VERSION_READABLE 4

#define BINARY_FORMAT_VERSION 4

Expand Down Expand Up @@ -1050,7 +1052,7 @@ void ResourceLoaderText::open(Ref<FileAccess> p_f, bool p_skip_first_tag) {

if (tag.fields.has("format")) {
int fmt = tag.fields["format"];
if (fmt > FORMAT_VERSION) {
if (fmt > FORMAT_VERSION_READABLE) {
error_text = "Saved with newer format version";
_printerr();
error = ERR_PARSE_ERROR;
Expand Down Expand Up @@ -1541,7 +1543,7 @@ String ResourceLoaderText::recognize_script_class(Ref<FileAccess> p_f) {

if (tag.fields.has("format")) {
int fmt = tag.fields["format"];
if (fmt > FORMAT_VERSION) {
if (fmt > FORMAT_VERSION_READABLE) {
error_text = "Saved with newer format version";
_printerr();
return "";
Expand Down Expand Up @@ -1579,7 +1581,7 @@ String ResourceLoaderText::recognize(Ref<FileAccess> p_f) {

if (tag.fields.has("format")) {
int fmt = tag.fields["format"];
if (fmt > FORMAT_VERSION) {
if (fmt > FORMAT_VERSION_READABLE) {
error_text = "Saved with newer format version";
_printerr();
return "";
Expand Down
Loading