Skip to content

Commit b1ce289

Browse files
committed
Fixed memory leak with String objects
The member _godot_string should never be straight out overwritten ever without first destroying the underlying string object's memory. This change solves the problem through the introduction of a new private constructor to create String objects with a pre-existing godot_string handle.
1 parent c2f765e commit b1ce289

File tree

2 files changed

+40
-137
lines changed

2 files changed

+40
-137
lines changed

include/core/String.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ class CharString {
2929
class String {
3030
godot_string _godot_string;
3131

32+
String(godot_string contents) :
33+
_godot_string(contents) {}
34+
3235
public:
3336
String();
3437
String(const char *contents);

src/core/String.cpp

Lines changed: 37 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -25,52 +25,31 @@ const char *godot::CharString::get_data() const {
2525
}
2626

2727
String String::num(double p_num, int p_decimals) {
28-
String new_string;
29-
new_string._godot_string = godot::api->godot_string_num_with_decimals(p_num, p_decimals);
30-
31-
return new_string;
28+
return String(godot::api->godot_string_num_with_decimals(p_num, p_decimals));
3229
}
3330

3431
String String::num_scientific(double p_num) {
35-
String new_string;
36-
new_string._godot_string = godot::api->godot_string_num_scientific(p_num);
37-
38-
return new_string;
32+
return String(godot::api->godot_string_num_scientific(p_num));
3933
}
4034

4135
String String::num_real(double p_num) {
42-
String new_string;
43-
new_string._godot_string = godot::api->godot_string_num_real(p_num);
44-
45-
return new_string;
36+
return String(godot::api->godot_string_num_real(p_num));
4637
}
4738

4839
String String::num_int64(int64_t p_num, int base, bool capitalize_hex) {
49-
String new_string;
50-
new_string._godot_string = godot::api->godot_string_num_int64_capitalized(p_num, base, capitalize_hex);
51-
52-
return new_string;
40+
return String(godot::api->godot_string_num_int64_capitalized(p_num, base, capitalize_hex));
5341
}
5442

5543
String String::chr(godot_char_type p_char) {
56-
String new_string;
57-
new_string._godot_string = godot::api->godot_string_chr(p_char);
58-
59-
return new_string;
44+
return String(godot::api->godot_string_chr(p_char));
6045
}
6146

6247
String String::md5(const uint8_t *p_md5) {
63-
String new_string;
64-
new_string._godot_string = godot::api->godot_string_md5(p_md5);
65-
66-
return new_string;
48+
return String(godot::api->godot_string_md5(p_md5));
6749
}
6850

6951
String String::hex_encode_buffer(const uint8_t *p_buffer, int p_len) {
70-
String new_string;
71-
new_string._godot_string = godot::api->godot_string_hex_encode_buffer(p_buffer, p_len);
72-
73-
return new_string;
52+
return String(godot::api->godot_string_hex_encode_buffer(p_buffer, p_len));
7453
}
7554

7655
godot::String::String() {
@@ -124,14 +103,11 @@ bool String::operator!=(const String &s) const {
124103
}
125104

126105
String String::operator+(const String &s) const {
127-
String new_string;
128-
new_string._godot_string = godot::api->godot_string_operator_plus(&_godot_string, &s._godot_string);
129-
130-
return new_string;
106+
return godot::api->godot_string_operator_plus(&_godot_string, &s._godot_string);
131107
}
132108

133109
void String::operator+=(const String &s) {
134-
_godot_string = godot::api->godot_string_operator_plus(&_godot_string, &s._godot_string);
110+
*this = String(godot::api->godot_string_operator_plus(&_godot_string, &s._godot_string));
135111
}
136112

137113
void String::operator+=(const wchar_t c) {
@@ -223,24 +199,15 @@ PoolStringArray String::bigrams() const {
223199
}
224200

225201
String String::c_escape() const {
226-
String new_string;
227-
new_string._godot_string = godot::api->godot_string_c_escape(&_godot_string);
228-
229-
return new_string;
202+
return String(godot::api->godot_string_c_escape(&_godot_string));
230203
}
231204

232205
String String::c_unescape() const {
233-
String new_string;
234-
new_string._godot_string = godot::api->godot_string_c_unescape(&_godot_string);
235-
236-
return new_string;
206+
return String(godot::api->godot_string_c_unescape(&_godot_string));
237207
}
238208

239209
String String::capitalize() const {
240-
String new_string;
241-
new_string._godot_string = godot::api->godot_string_capitalize(&_godot_string);
242-
243-
return new_string;
210+
return String(godot::api->godot_string_capitalize(&_godot_string));
244211
}
245212

246213
bool String::empty() const {
@@ -268,41 +235,31 @@ int String::findn(String p_what, int p_from) const {
268235
}
269236

270237
String String::format(Variant values) const {
271-
String new_string;
272-
new_string._godot_string = godot::api->godot_string_format(&_godot_string, (godot_variant *)&values);
273-
274-
return new_string;
238+
return String(godot::api->godot_string_format(&_godot_string, (godot_variant *)&values));
275239
}
276240

277241
String String::format(Variant values, String placeholder) const {
278-
String new_string;
279242
godot_char_string contents = godot::api->godot_string_utf8(&placeholder._godot_string);
280-
new_string._godot_string = godot::api->godot_string_format_with_custom_placeholder(&_godot_string, (godot_variant *)&values, godot::api->godot_char_string_get_data(&contents));
243+
String new_string(godot::api->godot_string_format_with_custom_placeholder(&_godot_string, (godot_variant *)&values, godot::api->godot_char_string_get_data(&contents)));
281244
godot::api->godot_char_string_destroy(&contents);
282245

283246
return new_string;
284247
}
285248

286249
String String::get_base_dir() const {
287-
String new_string;
288-
new_string._godot_string = godot::api->godot_string_get_base_dir(&_godot_string);
289-
290-
return new_string;
250+
return String(godot::api->godot_string_get_base_dir(&_godot_string));
291251
}
292252

293253
String String::get_basename() const {
294-
godot_string new_string = godot::api->godot_string_get_basename(&_godot_string);
295-
return *(String *)&new_string;
254+
return String(godot::api->godot_string_get_basename(&_godot_string));
296255
}
297256

298257
String String::get_extension() const {
299-
godot_string new_string = godot::api->godot_string_get_extension(&_godot_string);
300-
return *(String *)&new_string;
258+
return String(godot::api->godot_string_get_extension(&_godot_string));
301259
}
302260

303261
String String::get_file() const {
304-
godot_string new_string = godot::api->godot_string_get_file(&_godot_string);
305-
return *(String *)&new_string;
262+
return String(godot::api->godot_string_get_file(&_godot_string));
306263
}
307264

308265
int String::hash() const {
@@ -314,10 +271,7 @@ int String::hex_to_int() const {
314271
}
315272

316273
String String::insert(int position, String what) const {
317-
String new_string;
318-
new_string._godot_string = godot::api->godot_string_insert(&_godot_string, position, what._godot_string);
319-
320-
return new_string;
274+
return String(godot::api->godot_string_insert(&_godot_string, position, what._godot_string));
321275
}
322276

323277
bool String::is_abs_path() const {
@@ -357,17 +311,11 @@ bool String::is_valid_ip_address() const {
357311
}
358312

359313
String String::json_escape() const {
360-
String new_string;
361-
new_string._godot_string = godot::api->godot_string_json_escape(&_godot_string);
362-
363-
return new_string;
314+
return String(godot::api->godot_string_json_escape(&_godot_string));
364315
}
365316

366317
String String::left(int position) const {
367-
String new_string;
368-
new_string._godot_string = godot::api->godot_string_left(&_godot_string, position);
369-
370-
return new_string;
318+
return String(godot::api->godot_string_left(&_godot_string, position));
371319
}
372320

373321
bool String::match(String expr) const {
@@ -384,63 +332,39 @@ PoolByteArray String::md5_buffer() const {
384332
}
385333

386334
String String::md5_text() const {
387-
String new_string;
388-
new_string._godot_string = godot::api->godot_string_md5_text(&_godot_string);
389-
390-
return new_string;
335+
return String(godot::api->godot_string_md5_text(&_godot_string));
391336
}
392337

393338
int String::ord_at(int at) const {
394339
return godot::api->godot_string_ord_at(&_godot_string, at);
395340
}
396341

397342
String String::pad_decimals(int digits) const {
398-
String new_string;
399-
new_string._godot_string = godot::api->godot_string_pad_decimals(&_godot_string, digits);
400-
401-
return new_string;
343+
return String(godot::api->godot_string_pad_decimals(&_godot_string, digits));
402344
}
403345

404346
String String::pad_zeros(int digits) const {
405-
String new_string;
406-
new_string._godot_string = godot::api->godot_string_pad_zeros(&_godot_string, digits);
407-
408-
return new_string;
347+
return String(godot::api->godot_string_pad_zeros(&_godot_string, digits));
409348
}
410349

411350
String String::percent_decode() const {
412-
String new_string;
413-
new_string._godot_string = godot::api->godot_string_percent_decode(&_godot_string);
414-
415-
return new_string;
351+
return String(godot::api->godot_string_percent_decode(&_godot_string));
416352
}
417353

418354
String String::percent_encode() const {
419-
String new_string;
420-
new_string._godot_string = godot::api->godot_string_percent_encode(&_godot_string);
421-
422-
return new_string;
355+
return String(godot::api->godot_string_percent_encode(&_godot_string));
423356
}
424357

425358
String String::plus_file(String file) const {
426-
String new_string;
427-
new_string._godot_string = godot::api->godot_string_plus_file(&_godot_string, &file._godot_string);
428-
429-
return new_string;
359+
return String(godot::api->godot_string_plus_file(&_godot_string, &file._godot_string));
430360
}
431361

432362
String String::replace(String p_key, String p_with) const {
433-
String new_string;
434-
new_string._godot_string = godot::api->godot_string_replace(&_godot_string, p_key._godot_string, p_with._godot_string);
435-
436-
return new_string;
363+
return String(godot::api->godot_string_replace(&_godot_string, p_key._godot_string, p_with._godot_string));
437364
}
438365

439366
String String::replacen(String what, String forwhat) const {
440-
String new_string;
441-
new_string._godot_string = godot::api->godot_string_replacen(&_godot_string, what._godot_string, forwhat._godot_string);
442-
443-
return new_string;
367+
return String(godot::api->godot_string_replacen(&_godot_string, what._godot_string, forwhat._godot_string));
444368
}
445369

446370
int String::rfind(String p_what, int p_from) const {
@@ -452,10 +376,7 @@ int String::rfindn(String p_what, int p_from) const {
452376
}
453377

454378
String String::right(int position) const {
455-
String new_string;
456-
new_string._godot_string = godot::api->godot_string_right(&_godot_string, position);
457-
458-
return new_string;
379+
return String(godot::api->godot_string_right(&_godot_string, position));
459380
}
460381

461382
PoolByteArray String::sha256_buffer() const {
@@ -465,10 +386,7 @@ PoolByteArray String::sha256_buffer() const {
465386
}
466387

467388
String String::sha256_text() const {
468-
String new_string;
469-
new_string._godot_string = godot::api->godot_string_sha256_text(&_godot_string);
470-
471-
return new_string;
389+
return String(godot::api->godot_string_sha256_text(&_godot_string));
472390
}
473391

474392
float String::similarity(String text) const {
@@ -494,17 +412,11 @@ PoolRealArray String::split_floats(String divisor, bool allow_empty) const {
494412
}
495413

496414
String String::strip_edges(bool left, bool right) const {
497-
String new_string;
498-
new_string._godot_string = godot::api->godot_string_strip_edges(&_godot_string, left, right);
499-
500-
return new_string;
415+
return String(godot::api->godot_string_strip_edges(&_godot_string, left, right));
501416
}
502417

503418
String String::substr(int from, int len) const {
504-
String new_string;
505-
new_string._godot_string = godot::api->godot_string_substr(&_godot_string, from, len);
506-
507-
return new_string;
419+
return String(godot::api->godot_string_substr(&_godot_string, from, len));
508420
}
509421

510422
float String::to_float() const {
@@ -516,31 +428,19 @@ int64_t String::to_int() const {
516428
}
517429

518430
String String::to_lower() const {
519-
String new_string;
520-
new_string._godot_string = godot::api->godot_string_to_lower(&_godot_string);
521-
522-
return new_string;
431+
return String(godot::api->godot_string_to_lower(&_godot_string));
523432
}
524433

525434
String String::to_upper() const {
526-
String new_string;
527-
new_string._godot_string = godot::api->godot_string_to_upper(&_godot_string);
528-
529-
return new_string;
435+
return String(godot::api->godot_string_to_upper(&_godot_string));
530436
}
531437

532438
String String::xml_escape() const {
533-
String new_string;
534-
new_string._godot_string = godot::api->godot_string_xml_escape(&_godot_string);
535-
536-
return new_string;
439+
return String(godot::api->godot_string_xml_escape(&_godot_string));
537440
}
538441

539442
String String::xml_unescape() const {
540-
String new_string;
541-
new_string._godot_string = godot::api->godot_string_xml_unescape(&_godot_string);
542-
543-
return new_string;
443+
return String(godot::api->godot_string_xml_unescape(&_godot_string));
544444
}
545445

546446
signed char String::casecmp_to(String p_str) const {

0 commit comments

Comments
 (0)