Skip to content

Commit c4c6b71

Browse files
dalexeevSpartan322
andcommitted
Core: Add allow_objects/full_objects parameter to text serialization
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]>
1 parent 9a49cab commit c4c6b71

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+507
-188
lines changed

core/config/project_settings.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -767,7 +767,7 @@ Error ProjectSettings::_load_settings_text(const String &p_path) {
767767
next_tag.fields.clear();
768768
next_tag.name = String();
769769

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

971971
String vstr;
972-
VariantWriter::write_to_string(value, vstr);
972+
VariantWriter::write_to_string(value, vstr, nullptr, nullptr, true, true);
973973
file->store_string(F.property_name_encode() + "=" + vstr + "\n");
974974
}
975975
}
@@ -1429,6 +1429,7 @@ ProjectSettings::ProjectSettings() {
14291429
GLOBAL_DEF_BASIC("application/config/version", "");
14301430
GLOBAL_DEF_INTERNAL(PropertyInfo(Variant::STRING, "application/config/tags"), PackedStringArray());
14311431
GLOBAL_DEF_BASIC(PropertyInfo(Variant::STRING, "application/run/main_scene", PROPERTY_HINT_FILE, "*.tscn,*.scn,*.res"), "");
1432+
GLOBAL_DEF_RST("application/run/disable_modified_security_assistance", false);
14321433
GLOBAL_DEF("application/run/disable_stdout", false);
14331434
GLOBAL_DEF("application/run/disable_stderr", false);
14341435
GLOBAL_DEF("application/run/print_header", true);

core/io/config_file.compat.inc

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/**************************************************************************/
2+
/* config_file.compat.inc */
3+
/**************************************************************************/
4+
/* This file is part of: */
5+
/* GODOT ENGINE */
6+
/* https://godotengine.org */
7+
/**************************************************************************/
8+
/* Copyright (c) 2024-present Redot Engine contributors */
9+
/* (see REDOT_AUTHORS.md) */
10+
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
11+
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
12+
/* */
13+
/* Permission is hereby granted, free of charge, to any person obtaining */
14+
/* a copy of this software and associated documentation files (the */
15+
/* "Software"), to deal in the Software without restriction, including */
16+
/* without limitation the rights to use, copy, modify, merge, publish, */
17+
/* distribute, sublicense, and/or sell copies of the Software, and to */
18+
/* permit persons to whom the Software is furnished to do so, subject to */
19+
/* the following conditions: */
20+
/* */
21+
/* The above copyright notice and this permission notice shall be */
22+
/* included in all copies or substantial portions of the Software. */
23+
/* */
24+
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
25+
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
26+
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
27+
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
28+
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
29+
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
30+
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
31+
/**************************************************************************/
32+
33+
#ifndef DISABLE_DEPRECATED
34+
35+
Error ConfigFile::_save_bind_compat_redot764(const String &p_path) {
36+
return save(p_path, false);
37+
}
38+
39+
Error ConfigFile::_load_bind_compat_redot764(const String &p_path) {
40+
return load(p_path, false);
41+
}
42+
43+
Error ConfigFile::_parse_bind_compat_redot764(const String &p_path) {
44+
return parse(p_path, false);
45+
}
46+
47+
String ConfigFile::_encode_to_text_bind_compat_redot764() const {
48+
return encode_to_text(false);
49+
}
50+
51+
Error ConfigFile::_load_encrypted_bind_compat_redot764(const String &p_path, const Vector<uint8_t> &p_key) {
52+
return load_encrypted(p_path, p_key, false);
53+
}
54+
55+
Error ConfigFile::_load_encrypted_pass_bind_compat_redot764(const String &p_path, const String &p_pass) {
56+
return load_encrypted_pass(p_path, p_pass, false);
57+
}
58+
59+
Error ConfigFile::_save_encrypted_bind_compat_redot764(const String &p_path, const Vector<uint8_t> &p_key) {
60+
return save_encrypted(p_path, p_key, false);
61+
}
62+
63+
Error ConfigFile::_save_encrypted_pass_bind_compat_redot764(const String &p_path, const String &p_pass) {
64+
return save_encrypted_pass(p_path, p_pass, false);
65+
}
66+
67+
void ConfigFile::_bind_compatibility_methods() {
68+
ClassDB::bind_compatibility_method(D_METHOD("save", "path"), &ConfigFile::_save_bind_compat_redot764);
69+
ClassDB::bind_compatibility_method(D_METHOD("load", "path"), &ConfigFile::_load_bind_compat_redot764);
70+
ClassDB::bind_compatibility_method(D_METHOD("parse", "data"), &ConfigFile::_parse_bind_compat_redot764);
71+
72+
ClassDB::bind_compatibility_method(D_METHOD("encode_to_text"), &ConfigFile::_encode_to_text_bind_compat_redot764);
73+
74+
ClassDB::bind_compatibility_method(D_METHOD("load_encrypted", "path", "key"), &ConfigFile::_load_encrypted_bind_compat_redot764);
75+
ClassDB::bind_compatibility_method(D_METHOD("load_encrypted_pass", "path", "password"), &ConfigFile::_load_encrypted_pass_bind_compat_redot764);
76+
77+
ClassDB::bind_compatibility_method(D_METHOD("save_encrypted", "path", "key"), &ConfigFile::_save_encrypted_bind_compat_redot764);
78+
ClassDB::bind_compatibility_method(D_METHOD("save_encrypted_pass", "path", "password"), &ConfigFile::_save_encrypted_pass_bind_compat_redot764);
79+
}
80+
81+
#endif

core/io/config_file.cpp

+33-31
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
/**************************************************************************/
3232

3333
#include "config_file.h"
34+
#include "config_file.compat.inc"
3435

3536
#include "core/io/file_access_encrypted.h"
3637
#include "core/os/keyboard.h"
@@ -133,7 +134,7 @@ void ConfigFile::erase_section_key(const String &p_section, const String &p_key)
133134
}
134135
}
135136

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

149150
for (const KeyValue<String, Variant> &F : E.value) {
150151
String vstr;
151-
VariantWriter::write_to_string(F.value, vstr);
152+
VariantWriter::write_to_string(F.value, vstr, nullptr, nullptr, true, p_full_objects);
152153
sb.append(F.key.property_name_encode() + "=" + vstr + "\n");
153154
}
154155
}
155156
return sb.as_string();
156157
}
157158

158-
Error ConfigFile::save(const String &p_path) {
159+
Error ConfigFile::save(const String &p_path, bool p_full_objects) {
159160
Error err;
160161
Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::WRITE, &err);
161162

162163
if (err) {
163164
return err;
164165
}
165166

166-
return _internal_save(file);
167+
return _internal_save(file, p_full_objects);
167168
}
168169

169-
Error ConfigFile::save_encrypted(const String &p_path, const Vector<uint8_t> &p_key) {
170+
Error ConfigFile::save_encrypted(const String &p_path, const Vector<uint8_t> &p_key, bool p_full_objects) {
170171
Error err;
171172
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::WRITE, &err);
172173

@@ -180,10 +181,10 @@ Error ConfigFile::save_encrypted(const String &p_path, const Vector<uint8_t> &p_
180181
if (err) {
181182
return err;
182183
}
183-
return _internal_save(fae);
184+
return _internal_save(fae, p_full_objects);
184185
}
185186

186-
Error ConfigFile::save_encrypted_pass(const String &p_path, const String &p_pass) {
187+
Error ConfigFile::save_encrypted_pass(const String &p_path, const String &p_pass, bool p_full_objects) {
187188
Error err;
188189
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::WRITE, &err);
189190

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

201-
return _internal_save(fae);
202+
return _internal_save(fae, p_full_objects);
202203
}
203204

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

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

223224
return OK;
224225
}
225226

226-
Error ConfigFile::load(const String &p_path) {
227+
Error ConfigFile::load(const String &p_path, bool p_allow_objects) {
227228
Error err;
228229
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ, &err);
229230

230231
if (f.is_null()) {
231232
return err;
232233
}
233234

234-
return _internal_load(p_path, f);
235+
return _internal_load(p_path, f, p_allow_objects);
235236
}
236237

237-
Error ConfigFile::load_encrypted(const String &p_path, const Vector<uint8_t> &p_key) {
238+
Error ConfigFile::load_encrypted(const String &p_path, const Vector<uint8_t> &p_key, bool p_allow_objects) {
238239
Error err;
239240
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ, &err);
240241

@@ -248,10 +249,10 @@ Error ConfigFile::load_encrypted(const String &p_path, const Vector<uint8_t> &p_
248249
if (err) {
249250
return err;
250251
}
251-
return _internal_load(p_path, fae);
252+
return _internal_load(p_path, fae, p_allow_objects);
252253
}
253254

254-
Error ConfigFile::load_encrypted_pass(const String &p_path, const String &p_pass) {
255+
Error ConfigFile::load_encrypted_pass(const String &p_path, const String &p_pass, bool p_allow_objects) {
255256
Error err;
256257
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ, &err);
257258

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

269-
return _internal_load(p_path, fae);
270+
return _internal_load(p_path, fae, p_allow_objects);
270271
}
271272

272-
Error ConfigFile::_internal_load(const String &p_path, Ref<FileAccess> f) {
273+
Error ConfigFile::_internal_load(const String &p_path, Ref<FileAccess> f, bool p_allow_objects) {
273274
VariantParser::StreamFile stream;
274275
stream.f = f;
275276

276-
Error err = _parse(p_path, &stream);
277+
Error err = _parse(p_path, &stream, p_allow_objects);
277278

278279
return err;
279280
}
280281

281-
Error ConfigFile::parse(const String &p_data) {
282+
Error ConfigFile::parse(const String &p_data, bool p_allow_objects) {
282283
VariantParser::StreamString stream;
283284
stream.s = p_data;
284-
return _parse("<string>", &stream);
285+
return _parse("<string>", &stream, p_allow_objects);
285286
}
286287

287-
Error ConfigFile::_parse(const String &p_path, VariantParser::Stream *p_stream) {
288+
Error ConfigFile::_parse(const String &p_path, VariantParser::Stream *p_stream, bool p_allow_objects) {
288289
String assign;
289290
Variant value;
290291
VariantParser::Tag next_tag;
@@ -295,11 +296,12 @@ Error ConfigFile::_parse(const String &p_path, VariantParser::Stream *p_stream)
295296
String section;
296297

297298
while (true) {
298-
assign = Variant();
299+
assign = String();
300+
value = Variant();
299301
next_tag.fields.clear();
300302
next_tag.name = String();
301303

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

337-
ClassDB::bind_method(D_METHOD("load", "path"), &ConfigFile::load);
338-
ClassDB::bind_method(D_METHOD("parse", "data"), &ConfigFile::parse);
339-
ClassDB::bind_method(D_METHOD("save", "path"), &ConfigFile::save);
339+
ClassDB::bind_method(D_METHOD("load", "path", "allow_objects"), &ConfigFile::load, DEFVAL(false));
340+
ClassDB::bind_method(D_METHOD("parse", "data", "allow_objects"), &ConfigFile::parse, DEFVAL(false));
341+
ClassDB::bind_method(D_METHOD("save", "path", "full_objects"), &ConfigFile::save, DEFVAL(false));
340342

341-
ClassDB::bind_method(D_METHOD("encode_to_text"), &ConfigFile::encode_to_text);
343+
ClassDB::bind_method(D_METHOD("encode_to_text", "full_objects"), &ConfigFile::encode_to_text, DEFVAL(false));
342344

343345
BIND_METHOD_ERR_RETURN_DOC("load", ERR_FILE_CANT_OPEN);
344346

345-
ClassDB::bind_method(D_METHOD("load_encrypted", "path", "key"), &ConfigFile::load_encrypted);
346-
ClassDB::bind_method(D_METHOD("load_encrypted_pass", "path", "password"), &ConfigFile::load_encrypted_pass);
347+
ClassDB::bind_method(D_METHOD("load_encrypted", "path", "key", "allow_objects"), &ConfigFile::load_encrypted, DEFVAL(false));
348+
ClassDB::bind_method(D_METHOD("load_encrypted_pass", "path", "password", "allow_objects"), &ConfigFile::load_encrypted_pass, DEFVAL(false));
347349

348-
ClassDB::bind_method(D_METHOD("save_encrypted", "path", "key"), &ConfigFile::save_encrypted);
349-
ClassDB::bind_method(D_METHOD("save_encrypted_pass", "path", "password"), &ConfigFile::save_encrypted_pass);
350+
ClassDB::bind_method(D_METHOD("save_encrypted", "path", "key", "full_objects"), &ConfigFile::save_encrypted, DEFVAL(false));
351+
ClassDB::bind_method(D_METHOD("save_encrypted_pass", "path", "password", "full_objects"), &ConfigFile::save_encrypted_pass, DEFVAL(false));
350352

351353
ClassDB::bind_method(D_METHOD("clear"), &ConfigFile::clear);
352354
}

core/io/config_file.h

+27-11
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,30 @@ class ConfigFile : public RefCounted {
4545

4646
PackedStringArray _get_sections() const;
4747
PackedStringArray _get_section_keys(const String &p_section) const;
48-
Error _internal_load(const String &p_path, Ref<FileAccess> f);
49-
Error _internal_save(Ref<FileAccess> file);
48+
Error _internal_load(const String &p_path, Ref<FileAccess> f, bool p_allow_objects);
49+
Error _internal_save(Ref<FileAccess> file, bool p_full_objects);
5050

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

5353
protected:
5454
static void _bind_methods();
5555

56+
#ifndef DISABLE_DEPRECATED
57+
Error _save_bind_compat_redot764(const String &p_path);
58+
Error _load_bind_compat_redot764(const String &p_path);
59+
Error _parse_bind_compat_redot764(const String &p_path);
60+
61+
String _encode_to_text_bind_compat_redot764() const;
62+
63+
Error _load_encrypted_bind_compat_redot764(const String &p_path, const Vector<uint8_t> &p_key);
64+
Error _load_encrypted_pass_bind_compat_redot764(const String &p_path, const String &p_pass);
65+
66+
Error _save_encrypted_bind_compat_redot764(const String &p_path, const Vector<uint8_t> &p_key);
67+
Error _save_encrypted_pass_bind_compat_redot764(const String &p_path, const String &p_pass);
68+
69+
static void _bind_compatibility_methods();
70+
#endif
71+
5672
public:
5773
void set_value(const String &p_section, const String &p_key, const Variant &p_value);
5874
Variant get_value(const String &p_section, const String &p_key, const Variant &p_default = Variant()) const;
@@ -66,19 +82,19 @@ class ConfigFile : public RefCounted {
6682
void erase_section(const String &p_section);
6783
void erase_section_key(const String &p_section, const String &p_key);
6884

69-
Error save(const String &p_path);
70-
Error load(const String &p_path);
71-
Error parse(const String &p_data);
85+
Error save(const String &p_path, bool p_full_objects = false);
86+
Error load(const String &p_path, bool p_allow_objects = false);
87+
Error parse(const String &p_data, bool p_allow_objects = false);
7288

73-
String encode_to_text() const; // used by exporter
89+
String encode_to_text(bool p_full_objects = false) const;
7490

7591
void clear();
7692

77-
Error load_encrypted(const String &p_path, const Vector<uint8_t> &p_key);
78-
Error load_encrypted_pass(const String &p_path, const String &p_pass);
93+
Error load_encrypted(const String &p_path, const Vector<uint8_t> &p_key, bool p_allow_objects = false);
94+
Error load_encrypted_pass(const String &p_path, const String &p_pass, bool p_allow_objects = false);
7995

80-
Error save_encrypted(const String &p_path, const Vector<uint8_t> &p_key);
81-
Error save_encrypted_pass(const String &p_path, const String &p_pass);
96+
Error save_encrypted(const String &p_path, const Vector<uint8_t> &p_key, bool p_full_objects = false);
97+
Error save_encrypted_pass(const String &p_path, const String &p_pass, bool p_full_objects = false);
8298
};
8399

84100
#endif // CONFIG_FILE_H

core/io/resource_importer.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy
7373
next_tag.fields.clear();
7474
next_tag.name = String();
7575

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

336-
err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, nullptr, true);
336+
err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, nullptr, true, true);
337337
if (err == ERR_FILE_EOF) {
338338
return;
339339
} else if (err != OK) {
@@ -548,12 +548,12 @@ void ResourceImporter::_bind_methods() {
548548
Error ResourceFormatImporterSaver::set_uid(const String &p_path, ResourceUID::ID p_uid) {
549549
Ref<ConfigFile> cf;
550550
cf.instantiate();
551-
Error err = cf->load(p_path + ".import");
551+
Error err = cf->load(p_path + ".import", true);
552552
if (err != OK) {
553553
return err;
554554
}
555555
cf->set_value("remap", "uid", ResourceUID::get_singleton()->id_to_text(p_uid));
556-
cf->save(p_path + ".import");
556+
cf->save(p_path + ".import", true);
557557

558558
return OK;
559559
}

0 commit comments

Comments
 (0)