Skip to content

Commit fce9493

Browse files
committed
Fix #12007: RLog heap buffer
Work in progress for #12007. - Avoid stack-fixed buffer in r_log_vmessage by allocating the formatted message on the heap (r_str_newvf), preventing truncation. - Add a unit test to ensure long log messages are not truncated.
1 parent 25e9e07 commit fce9493

File tree

2 files changed

+49
-2
lines changed

2 files changed

+49
-2
lines changed

libr/util/log.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,16 +173,20 @@ R_API bool r_log_match(int level, const char *origin) {
173173
}
174174

175175
R_API void r_log_vmessage(RLogLevel level, const char *origin, const char *func, int line, const char *fmt, va_list ap) {
176-
char out[512];
176+
char *out;
177177
if (!r_log_init ()) {
178178
return;
179179
}
180-
vsnprintf (out, sizeof (out), fmt, ap);
180+
out = r_str_newvf (fmt, ap);
181+
if (!out) {
182+
return;
183+
}
181184
if (rlog->cbs) {
182185
RListIter *iter;
183186
RLogCallbackUser *cbu;
184187
r_list_foreach (rlog->cbs, iter, cbu) {
185188
if (cbu->cb (cbu->user, level, origin, out)) {
189+
free (out);
186190
return;
187191
}
188192
}
@@ -221,6 +225,7 @@ R_API void r_log_vmessage(RLogLevel level, const char *origin, const char *func,
221225
}
222226
}
223227
r_strbuf_appendf (sb, "%s %s\n", ts, out);
228+
free (out);
224229
char *s = r_strbuf_drain (sb);
225230
sb = NULL;
226231
if (!rlog->quiet) {

test/unit/test_util.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,14 +229,56 @@ bool test_references(void) {
229229
mu_end;
230230
}
231231

232+
typedef struct {
233+
const char *expected;
234+
size_t expected_len;
235+
size_t got_len;
236+
bool got_msg;
237+
bool match;
238+
} LogTestCtx;
239+
240+
static bool cb_log_test(void *user, int type, const char *origin, const char *msg) {
241+
(void)type;
242+
(void)origin;
243+
LogTestCtx *ctx = (LogTestCtx *)user;
244+
if (!msg) {
245+
return true;
246+
}
247+
ctx->got_len = strlen (msg);
248+
ctx->got_msg = true;
249+
ctx->match = !strcmp (msg, ctx->expected);
250+
return ctx->match;
251+
}
252+
232253
bool test_log(void) {
233254
// Stand up a semi-realistic log environment with an RCore
234255
RCore *core = r_core_new ();
256+
mu_assert_notnull (core, "r_core_new should not return NULL");
235257
r_log_set_quiet (true);
236258

237259
// https://github.com/radareorg/radare2/issues/22468
238260
R_LOG_INFO ("%s", "");
239261

262+
const size_t slen = 600;
263+
char *s = malloc (slen + 1);
264+
mu_assert_notnull (s, "malloc should not return NULL");
265+
memset (s, 'A', slen);
266+
s[slen] = 0;
267+
LogTestCtx ctx = {
268+
.expected = s,
269+
.expected_len = slen,
270+
.got_len = 0,
271+
.got_msg = false,
272+
.match = false,
273+
};
274+
r_log_add_callback (cb_log_test, &ctx);
275+
R_LOG_INFO ("%s", s);
276+
r_log_del_callback (cb_log_test);
277+
free (s);
278+
mu_assert_true (ctx.got_msg, "log callback should receive message");
279+
mu_assert_true (ctx.match, "log callback message should match expected string");
280+
mu_assert_eq ((int)ctx.got_len, (int)ctx.expected_len, "log message should not be truncated");
281+
240282
r_core_free (core);
241283
mu_end;
242284
}

0 commit comments

Comments
 (0)