GitHub

@@ -12,7 +12,6 @@

1212

#include <time.h>

1313

#include <string.h>

141415-

#define INITIAL_BUFFER_SIZE 64

1615

#define MAX_BUFFER_SIZE 4096

17161817

/*

@@ -60,12 +59,12 @@ mrb_time_strftime(mrb_state *mrb, mrb_value self)

6059

/* Process this segment (up to NUL or end of string) */

6160

if (segment_len > 0) {

6261

char *segment;

63-

size_t buf_size;

6462

char *buf;

6563

size_t n;

66646765

/* Create null-terminated copy of this segment */

68-

segment = (char *)mrb_malloc(mrb, (size_t)segment_len + 1);

66+

/* Use mrb_temp_alloc for exception safety - GC will clean up on exception */

67+

segment = (char *)mrb_temp_alloc(mrb, (size_t)segment_len + 1);

6968

memcpy(segment, fmt_ptr, (size_t)segment_len);

7069

segment[segment_len] = '\0';

7170

@@ -74,41 +73,21 @@ mrb_time_strftime(mrb_state *mrb, mrb_value self)

7473

/* Scan for %- patterns in the format string */

7574

for (const char *p = segment; *p != '\0'; p++) {

7675

if (p[0] == '%' && p[1] == '-') {

77-

mrb_free(mrb, segment);

7876

mrb_raisef(mrb, E_ARGUMENT_ERROR,

7977

"strftime format flag '%-' not supported on this platform (use '%%#' on Windows)");

8078

}

8179

}

8280

#endif

83818482

/* Allocate buffer for formatted output */

85-

buf_size = INITIAL_BUFFER_SIZE;

86-

buf = (char *)mrb_malloc(mrb, buf_size);

87-88-

/* Try formatting; grow buffer if needed */

89-

while (1) {

90-

n = strftime(buf, buf_size, segment, tm);

91-92-

/*

93-

* strftime returns 0 if:

94-

* 1. Buffer is too small (retry with larger buffer)

95-

* 2. Format produces empty result (stop retrying)

96-

* We distinguish by checking buffer size limit.

97-

*/

98-

if (n > 0 || buf_size >= MAX_BUFFER_SIZE) {

99-

break;

100-

}

83+

/* Use mrb_temp_alloc with max size for exception safety */

84+

buf = (char *)mrb_temp_alloc(mrb, MAX_BUFFER_SIZE);

10185102-

/* Double buffer size and retry */

103-

buf_size *= 2;

104-

buf = (char *)mrb_realloc(mrb, buf, buf_size);

105-

}

86+

/* Try formatting with max buffer size */

87+

n = strftime(buf, MAX_BUFFER_SIZE, segment, tm);

1068810789

/* Append formatted output to result */

10890

mrb_str_cat(mrb, result, buf, n);

109-110-

mrb_free(mrb, buf);

111-

mrb_free(mrb, segment);

11291

}

1139211493

/* If there was a NUL, append it to result and advance past it */

Read the original on github.com ↗