Skip to content

Commit

Permalink
Core: Add allow_objects/full_objects parameter to text serialization
Browse files Browse the repository at this point in the history
Adapted from commit dalexeev/godot@377ff79

Add "disable_modified_security_assistance" project setting
	Warns about application performing unsafe behavior by default when enabled

Rename compat functions to redot764
Fix uninitialized array warning

Co-authored-by: Spartan322 <[email protected]>
  • Loading branch information
dalexeev and Spartan322 committed Oct 27, 2024
1 parent 77eaec7 commit 4dd96ef
Show file tree
Hide file tree
Showing 41 changed files with 505 additions and 186 deletions.
5 changes: 3 additions & 2 deletions core/config/project_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,7 @@ Error ProjectSettings::_load_settings_text(const String &p_path) {
next_tag.fields.clear();
next_tag.name = String();

err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, nullptr, true);
err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, nullptr, true, true);
if (err == ERR_FILE_EOF) {
// If we're loading a project.godot from source code, we can operate some
// ProjectSettings conversions if need be.
Expand Down Expand Up @@ -986,7 +986,7 @@ Error ProjectSettings::_save_settings_text(const String &p_file, const RBMap<Str
}

String vstr;
VariantWriter::write_to_string(value, vstr);
VariantWriter::write_to_string(value, vstr, nullptr, nullptr, true, true);
file->store_string(F.property_name_encode() + "=" + vstr + "\n");
}
}
Expand Down Expand Up @@ -1446,6 +1446,7 @@ ProjectSettings::ProjectSettings() {
GLOBAL_DEF_BASIC("application/config/version", "");
GLOBAL_DEF_INTERNAL(PropertyInfo(Variant::STRING, "application/config/tags"), PackedStringArray());
GLOBAL_DEF_BASIC(PropertyInfo(Variant::STRING, "application/run/main_scene", PROPERTY_HINT_FILE, "*.tscn,*.scn,*.res"), "");
GLOBAL_DEF_RST("application/run/disable_modified_security_assistance", false);
GLOBAL_DEF("application/run/disable_stdout", false);
GLOBAL_DEF("application/run/disable_stderr", false);
GLOBAL_DEF("application/run/print_header", true);
Expand Down
81 changes: 81 additions & 0 deletions core/io/config_file.compat.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/**************************************************************************/
/* config_file.compat.inc */
/**************************************************************************/
/* This file is part of: */
/* REDOT ENGINE */
/* https://redotengine.org */
/**************************************************************************/
/* Copyright (c) 2024-present Redot Engine contributors */
/* (see REDOT_AUTHORS.md) */
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/

#ifndef DISABLE_DEPRECATED

Error ConfigFile::_save_bind_compat_redot764(const String &p_path) {
return save(p_path, false);
}

Error ConfigFile::_load_bind_compat_redot764(const String &p_path) {
return load(p_path, false);
}

Error ConfigFile::_parse_bind_compat_redot764(const String &p_path) {
return parse(p_path, false);
}

String ConfigFile::_encode_to_text_bind_compat_redot764() const {
return encode_to_text(false);
}

Error ConfigFile::_load_encrypted_bind_compat_redot764(const String &p_path, const Vector<uint8_t> &p_key) {
return load_encrypted(p_path, p_key, false);
}

Error ConfigFile::_load_encrypted_pass_bind_compat_redot764(const String &p_path, const String &p_pass) {
return load_encrypted_pass(p_path, p_pass, false);
}

Error ConfigFile::_save_encrypted_bind_compat_redot764(const String &p_path, const Vector<uint8_t> &p_key) {
return save_encrypted(p_path, p_key, false);
}

Error ConfigFile::_save_encrypted_pass_bind_compat_redot764(const String &p_path, const String &p_pass) {
return save_encrypted_pass(p_path, p_pass, false);
}

void ConfigFile::_bind_compatibility_methods() {
ClassDB::bind_compatibility_method(D_METHOD("save", "path"), &ConfigFile::_save_bind_compat_redot764);
ClassDB::bind_compatibility_method(D_METHOD("load", "path"), &ConfigFile::_load_bind_compat_redot764);
ClassDB::bind_compatibility_method(D_METHOD("parse", "data"), &ConfigFile::_parse_bind_compat_redot764);

ClassDB::bind_compatibility_method(D_METHOD("encode_to_text"), &ConfigFile::_encode_to_text_bind_compat_redot764);

ClassDB::bind_compatibility_method(D_METHOD("load_encrypted", "path", "key"), &ConfigFile::_load_encrypted_bind_compat_redot764);
ClassDB::bind_compatibility_method(D_METHOD("load_encrypted_pass", "path", "password"), &ConfigFile::_load_encrypted_pass_bind_compat_redot764);

ClassDB::bind_compatibility_method(D_METHOD("save_encrypted", "path", "key"), &ConfigFile::_save_encrypted_bind_compat_redot764);
ClassDB::bind_compatibility_method(D_METHOD("save_encrypted_pass", "path", "password"), &ConfigFile::_save_encrypted_pass_bind_compat_redot764);
}

#endif
64 changes: 33 additions & 31 deletions core/io/config_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
/**************************************************************************/

#include "config_file.h"
#include "config_file.compat.inc"

#include "core/io/file_access_encrypted.h"
#include "core/os/keyboard.h"
Expand Down Expand Up @@ -133,7 +134,7 @@ void ConfigFile::erase_section_key(const String &p_section, const String &p_key)
}
}

String ConfigFile::encode_to_text() const {
String ConfigFile::encode_to_text(bool p_full_objects) const {
StringBuilder sb;
bool first = true;
for (const KeyValue<String, HashMap<String, Variant>> &E : values) {
Expand All @@ -148,25 +149,25 @@ String ConfigFile::encode_to_text() const {

for (const KeyValue<String, Variant> &F : E.value) {
String vstr;
VariantWriter::write_to_string(F.value, vstr);
VariantWriter::write_to_string(F.value, vstr, nullptr, nullptr, true, p_full_objects);
sb.append(F.key.property_name_encode() + "=" + vstr + "\n");
}
}
return sb.as_string();
}

Error ConfigFile::save(const String &p_path) {
Error ConfigFile::save(const String &p_path, bool p_full_objects) {
Error err;
Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::WRITE, &err);

if (err) {
return err;
}

return _internal_save(file);
return _internal_save(file, p_full_objects);
}

Error ConfigFile::save_encrypted(const String &p_path, const Vector<uint8_t> &p_key) {
Error ConfigFile::save_encrypted(const String &p_path, const Vector<uint8_t> &p_key, bool p_full_objects) {
Error err;
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::WRITE, &err);

Expand All @@ -180,10 +181,10 @@ Error ConfigFile::save_encrypted(const String &p_path, const Vector<uint8_t> &p_
if (err) {
return err;
}
return _internal_save(fae);
return _internal_save(fae, p_full_objects);
}

Error ConfigFile::save_encrypted_pass(const String &p_path, const String &p_pass) {
Error ConfigFile::save_encrypted_pass(const String &p_path, const String &p_pass, bool p_full_objects) {
Error err;
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::WRITE, &err);

Expand All @@ -198,10 +199,10 @@ Error ConfigFile::save_encrypted_pass(const String &p_path, const String &p_pass
return err;
}

return _internal_save(fae);
return _internal_save(fae, p_full_objects);
}

Error ConfigFile::_internal_save(Ref<FileAccess> file) {
Error ConfigFile::_internal_save(Ref<FileAccess> file, bool p_full_objects) {
bool first = true;
for (const KeyValue<String, HashMap<String, Variant>> &E : values) {
if (first) {
Expand All @@ -215,26 +216,26 @@ Error ConfigFile::_internal_save(Ref<FileAccess> file) {

for (const KeyValue<String, Variant> &F : E.value) {
String vstr;
VariantWriter::write_to_string(F.value, vstr);
VariantWriter::write_to_string(F.value, vstr, nullptr, nullptr, true, p_full_objects);
file->store_string(F.key.property_name_encode() + "=" + vstr + "\n");
}
}

return OK;
}

Error ConfigFile::load(const String &p_path) {
Error ConfigFile::load(const String &p_path, bool p_allow_objects) {
Error err;
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ, &err);

if (f.is_null()) {
return err;
}

return _internal_load(p_path, f);
return _internal_load(p_path, f, p_allow_objects);
}

Error ConfigFile::load_encrypted(const String &p_path, const Vector<uint8_t> &p_key) {
Error ConfigFile::load_encrypted(const String &p_path, const Vector<uint8_t> &p_key, bool p_allow_objects) {
Error err;
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ, &err);

Expand All @@ -248,10 +249,10 @@ Error ConfigFile::load_encrypted(const String &p_path, const Vector<uint8_t> &p_
if (err) {
return err;
}
return _internal_load(p_path, fae);
return _internal_load(p_path, fae, p_allow_objects);
}

Error ConfigFile::load_encrypted_pass(const String &p_path, const String &p_pass) {
Error ConfigFile::load_encrypted_pass(const String &p_path, const String &p_pass, bool p_allow_objects) {
Error err;
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ, &err);

Expand All @@ -266,25 +267,25 @@ Error ConfigFile::load_encrypted_pass(const String &p_path, const String &p_pass
return err;
}

return _internal_load(p_path, fae);
return _internal_load(p_path, fae, p_allow_objects);
}

Error ConfigFile::_internal_load(const String &p_path, Ref<FileAccess> f) {
Error ConfigFile::_internal_load(const String &p_path, Ref<FileAccess> f, bool p_allow_objects) {
VariantParser::StreamFile stream;
stream.f = f;

Error err = _parse(p_path, &stream);
Error err = _parse(p_path, &stream, p_allow_objects);

return err;
}

Error ConfigFile::parse(const String &p_data) {
Error ConfigFile::parse(const String &p_data, bool p_allow_objects) {
VariantParser::StreamString stream;
stream.s = p_data;
return _parse("<string>", &stream);
return _parse("<string>", &stream, p_allow_objects);
}

Error ConfigFile::_parse(const String &p_path, VariantParser::Stream *p_stream) {
Error ConfigFile::_parse(const String &p_path, VariantParser::Stream *p_stream, bool p_allow_objects) {
String assign;
Variant value;
VariantParser::Tag next_tag;
Expand All @@ -295,11 +296,12 @@ Error ConfigFile::_parse(const String &p_path, VariantParser::Stream *p_stream)
String section;

while (true) {
assign = Variant();
assign = String();
value = Variant();
next_tag.fields.clear();
next_tag.name = String();

Error err = VariantParser::parse_tag_assign_eof(p_stream, lines, error_text, next_tag, assign, value, nullptr, true);
Error err = VariantParser::parse_tag_assign_eof(p_stream, lines, error_text, next_tag, assign, value, nullptr, true, p_allow_objects);
if (err == ERR_FILE_EOF) {
return OK;
} else if (err != OK) {
Expand Down Expand Up @@ -334,19 +336,19 @@ void ConfigFile::_bind_methods() {
ClassDB::bind_method(D_METHOD("erase_section", "section"), &ConfigFile::erase_section);
ClassDB::bind_method(D_METHOD("erase_section_key", "section", "key"), &ConfigFile::erase_section_key);

ClassDB::bind_method(D_METHOD("load", "path"), &ConfigFile::load);
ClassDB::bind_method(D_METHOD("parse", "data"), &ConfigFile::parse);
ClassDB::bind_method(D_METHOD("save", "path"), &ConfigFile::save);
ClassDB::bind_method(D_METHOD("load", "path", "allow_objects"), &ConfigFile::load, DEFVAL(false));
ClassDB::bind_method(D_METHOD("parse", "data", "allow_objects"), &ConfigFile::parse, DEFVAL(false));
ClassDB::bind_method(D_METHOD("save", "path", "full_objects"), &ConfigFile::save, DEFVAL(false));

ClassDB::bind_method(D_METHOD("encode_to_text"), &ConfigFile::encode_to_text);
ClassDB::bind_method(D_METHOD("encode_to_text", "full_objects"), &ConfigFile::encode_to_text, DEFVAL(false));

BIND_METHOD_ERR_RETURN_DOC("load", ERR_FILE_CANT_OPEN);

ClassDB::bind_method(D_METHOD("load_encrypted", "path", "key"), &ConfigFile::load_encrypted);
ClassDB::bind_method(D_METHOD("load_encrypted_pass", "path", "password"), &ConfigFile::load_encrypted_pass);
ClassDB::bind_method(D_METHOD("load_encrypted", "path", "key", "allow_objects"), &ConfigFile::load_encrypted, DEFVAL(false));
ClassDB::bind_method(D_METHOD("load_encrypted_pass", "path", "password", "allow_objects"), &ConfigFile::load_encrypted_pass, DEFVAL(false));

ClassDB::bind_method(D_METHOD("save_encrypted", "path", "key"), &ConfigFile::save_encrypted);
ClassDB::bind_method(D_METHOD("save_encrypted_pass", "path", "password"), &ConfigFile::save_encrypted_pass);
ClassDB::bind_method(D_METHOD("save_encrypted", "path", "key", "full_objects"), &ConfigFile::save_encrypted, DEFVAL(false));
ClassDB::bind_method(D_METHOD("save_encrypted_pass", "path", "password", "full_objects"), &ConfigFile::save_encrypted_pass, DEFVAL(false));

ClassDB::bind_method(D_METHOD("clear"), &ConfigFile::clear);
}
38 changes: 27 additions & 11 deletions core/io/config_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,30 @@ class ConfigFile : public RefCounted {

PackedStringArray _get_sections() const;
PackedStringArray _get_section_keys(const String &p_section) const;
Error _internal_load(const String &p_path, Ref<FileAccess> f);
Error _internal_save(Ref<FileAccess> file);
Error _internal_load(const String &p_path, Ref<FileAccess> f, bool p_allow_objects);
Error _internal_save(Ref<FileAccess> file, bool p_full_objects);

Error _parse(const String &p_path, VariantParser::Stream *p_stream);
Error _parse(const String &p_path, VariantParser::Stream *p_stream, bool p_allow_objects);

protected:
static void _bind_methods();

#ifndef DISABLE_DEPRECATED
Error _save_bind_compat_redot764(const String &p_path);
Error _load_bind_compat_redot764(const String &p_path);
Error _parse_bind_compat_redot764(const String &p_path);

String _encode_to_text_bind_compat_redot764() const;

Error _load_encrypted_bind_compat_redot764(const String &p_path, const Vector<uint8_t> &p_key);
Error _load_encrypted_pass_bind_compat_redot764(const String &p_path, const String &p_pass);

Error _save_encrypted_bind_compat_redot764(const String &p_path, const Vector<uint8_t> &p_key);
Error _save_encrypted_pass_bind_compat_redot764(const String &p_path, const String &p_pass);

static void _bind_compatibility_methods();
#endif

public:
void set_value(const String &p_section, const String &p_key, const Variant &p_value);
Variant get_value(const String &p_section, const String &p_key, const Variant &p_default = Variant()) const;
Expand All @@ -66,19 +82,19 @@ class ConfigFile : public RefCounted {
void erase_section(const String &p_section);
void erase_section_key(const String &p_section, const String &p_key);

Error save(const String &p_path);
Error load(const String &p_path);
Error parse(const String &p_data);
Error save(const String &p_path, bool p_full_objects = false);
Error load(const String &p_path, bool p_allow_objects = false);
Error parse(const String &p_data, bool p_allow_objects = false);

String encode_to_text() const; // used by exporter
String encode_to_text(bool p_full_objects = false) const;

void clear();

Error load_encrypted(const String &p_path, const Vector<uint8_t> &p_key);
Error load_encrypted_pass(const String &p_path, const String &p_pass);
Error load_encrypted(const String &p_path, const Vector<uint8_t> &p_key, bool p_allow_objects = false);
Error load_encrypted_pass(const String &p_path, const String &p_pass, bool p_allow_objects = false);

Error save_encrypted(const String &p_path, const Vector<uint8_t> &p_key);
Error save_encrypted_pass(const String &p_path, const String &p_pass);
Error save_encrypted(const String &p_path, const Vector<uint8_t> &p_key, bool p_full_objects = false);
Error save_encrypted_pass(const String &p_path, const String &p_pass, bool p_full_objects = false);
};

#endif // CONFIG_FILE_H
8 changes: 4 additions & 4 deletions core/io/resource_importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy
next_tag.fields.clear();
next_tag.name = String();

err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, nullptr, true);
err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, nullptr, true, true);
if (err == ERR_FILE_EOF) {
return OK;
} else if (err != OK) {
Expand Down Expand Up @@ -333,7 +333,7 @@ void ResourceFormatImporter::get_internal_resource_path_list(const String &p_pat
next_tag.fields.clear();
next_tag.name = String();

err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, nullptr, true);
err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, nullptr, true, true);
if (err == ERR_FILE_EOF) {
return;
} else if (err != OK) {
Expand Down Expand Up @@ -548,12 +548,12 @@ void ResourceImporter::_bind_methods() {
Error ResourceFormatImporterSaver::set_uid(const String &p_path, ResourceUID::ID p_uid) {
Ref<ConfigFile> cf;
cf.instantiate();
Error err = cf->load(p_path + ".import");
Error err = cf->load(p_path + ".import", true);
if (err != OK) {
return err;
}
cf->set_value("remap", "uid", ResourceUID::get_singleton()->id_to_text(p_uid));
cf->save(p_path + ".import");
cf->save(p_path + ".import", true);

return OK;
}
Loading

0 comments on commit 4dd96ef

Please sign in to comment.