mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-24 05:40:10 +00:00
Fix #12667 - Fix heap overflow in RCons.grep ##cons
This commit is contained in:
parent
c4bff784e0
commit
c98136300d
@ -595,7 +595,7 @@ R_API int r_cons_get_buffer_len() {
|
||||
R_API void r_cons_filter() {
|
||||
/* grep */
|
||||
if (I.filter || I.context->grep.nstrings > 0 || I.context->grep.tokens_used || I.context->grep.less || I.context->grep.json) {
|
||||
r_cons_grepbuf (I.context->buffer, I.context->buffer_len);
|
||||
(void)r_cons_grepbuf ();
|
||||
I.filter = false;
|
||||
}
|
||||
/* html */
|
||||
|
@ -253,7 +253,7 @@ R_API int r_line_set_hist_callback(RLine *line, RLineHistoryUpCb up, RLineHistor
|
||||
line->cb_history_down = down;
|
||||
line->offset_hist_index = 0;
|
||||
line->file_hist_index = 0;
|
||||
line->sdbshell_hist_iter = line->sdbshell_hist? r_list_head (line->sdbshell_hist): NULL;
|
||||
line->sdbshell_hist_iter = r_list_head (line->sdbshell_hist);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
106
libr/cons/grep.c
106
libr/cons/grep.c
@ -438,23 +438,24 @@ static int cmp(const void *a, const void *b) {
|
||||
return strcmp (a, b);
|
||||
}
|
||||
|
||||
R_API int r_cons_grepbuf(char *buf, int len) {
|
||||
R_API void r_cons_grepbuf() {
|
||||
RCons *cons = r_cons_singleton ();
|
||||
const char *buf = cons->context->buffer;
|
||||
const int len = cons->context->buffer_len;
|
||||
RConsGrep *grep = &cons->context->grep;
|
||||
char *tline, *tbuf, *p, *out, *in = buf;
|
||||
const char *in = buf;
|
||||
int ret, total_lines = 0, buffer_len = 0, l = 0, tl = 0;
|
||||
bool show = false;
|
||||
if (cons->filter) {
|
||||
cons->context->buffer_len = 0;
|
||||
R_FREE (cons->context->buffer);
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((!len || !buf || buf[0] == '\0') &&
|
||||
(grep->json || grep->less)) {
|
||||
if ((!len || !buf || buf[0] == '\0') && (grep->json || grep->less)) {
|
||||
grep->json = 0;
|
||||
grep->less = 0;
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
if (grep->json) {
|
||||
if (grep->json_path) {
|
||||
@ -478,7 +479,7 @@ R_API int r_cons_grepbuf(char *buf, int len) {
|
||||
};
|
||||
char *out = r_print_json_indent (buf, I (color), " ", palette);
|
||||
if (!out) {
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
free (cons->context->buffer);
|
||||
cons->context->buffer = out;
|
||||
@ -490,44 +491,39 @@ R_API int r_cons_grepbuf(char *buf, int len) {
|
||||
r_cons_less_str (cons->context->buffer, NULL);
|
||||
}
|
||||
}
|
||||
return 3;
|
||||
return;
|
||||
// cons->lines = ?? return 3;
|
||||
}
|
||||
if (grep->less) {
|
||||
int less = grep->less;
|
||||
grep->less = 0;
|
||||
if (less == 2) {
|
||||
char *res = r_cons_hud_string (buf);
|
||||
r_cons_println (res);
|
||||
free (res);
|
||||
if (res) {
|
||||
r_cons_println (res);
|
||||
free (res);
|
||||
}
|
||||
} else {
|
||||
r_cons_less_str (buf, NULL);
|
||||
buf[0] = 0;
|
||||
cons->context->buffer_len = 0;
|
||||
if (cons->context->buffer) {
|
||||
cons->context->buffer[0] = 0;
|
||||
}
|
||||
R_FREE (cons->context->buffer);
|
||||
}
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
if (!cons->context->buffer) {
|
||||
cons->context->buffer_len = len + 20;
|
||||
cons->context->buffer = malloc (cons->context->buffer_len);
|
||||
cons->context->buffer[0] = 0;
|
||||
}
|
||||
out = tbuf = calloc (1, len + 1);
|
||||
if (!out) {
|
||||
return 0;
|
||||
}
|
||||
tline = malloc (len);
|
||||
if (!tline) {
|
||||
free (out);
|
||||
return 0;
|
||||
}
|
||||
RStrBuf *ob = r_strbuf_new ("");
|
||||
// if we modify cons->lines we should update I.context->buffer too
|
||||
cons->lines = 0;
|
||||
// used to count lines and change negative grep.line values
|
||||
while ((int) (size_t) (in - buf) < len) {
|
||||
p = strchr (in, '\n');
|
||||
char *p = strchr (in, '\n');
|
||||
if (!p) {
|
||||
break;
|
||||
}
|
||||
@ -552,15 +548,13 @@ R_API int r_cons_grepbuf(char *buf, int len) {
|
||||
}
|
||||
in = buf;
|
||||
while ((int) (size_t) (in - buf) < len) {
|
||||
p = strchr (in, '\n');
|
||||
char *p = strchr (in, '\n');
|
||||
if (!p) {
|
||||
free (tbuf);
|
||||
free (tline);
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
l = p - in;
|
||||
if (l > 0) {
|
||||
memcpy (tline, in, l);
|
||||
char *tline = r_str_ndup (in, l);
|
||||
if (cons->grep_color) {
|
||||
tl = l;
|
||||
} else {
|
||||
@ -587,8 +581,8 @@ R_API int r_cons_grepbuf(char *buf, int len) {
|
||||
}
|
||||
if (ret > 0) {
|
||||
if (show) {
|
||||
char *str = r_str_ndup (tline, ret);
|
||||
if (cons->grep_highlight && grep->str) {
|
||||
char *str = r_str_ndup (tline, ret);
|
||||
char *newstr = r_str_newf (Color_INVERT"%s"Color_RESET, grep->str);
|
||||
if (str && newstr) {
|
||||
if (grep->icase) {
|
||||
@ -597,38 +591,34 @@ R_API int r_cons_grepbuf(char *buf, int len) {
|
||||
str = r_str_replace (str, grep->str, newstr, 1);
|
||||
}
|
||||
if (str) {
|
||||
ret = strlen (str);
|
||||
memcpy (out, str, ret);
|
||||
memcpy (out + ret, "\n", 2);
|
||||
r_strbuf_append (ob, str);
|
||||
r_strbuf_append (ob, "\n");
|
||||
}
|
||||
}
|
||||
free (str);
|
||||
free (newstr);
|
||||
} else {
|
||||
memcpy (out, tline, ret);
|
||||
memcpy (out + ret, "\n", 2);
|
||||
r_strbuf_append (ob, str);
|
||||
r_strbuf_append (ob, "\n");
|
||||
}
|
||||
out += ret + 1;
|
||||
buffer_len += ret + 1;
|
||||
free (str);
|
||||
}
|
||||
if (!grep->range_line) {
|
||||
show = false;
|
||||
}
|
||||
cons->lines++;
|
||||
} else if (ret < 0) {
|
||||
free (tbuf);
|
||||
free (tline);
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
free (tline);
|
||||
in += l + 1;
|
||||
} else {
|
||||
in++;
|
||||
}
|
||||
}
|
||||
memcpy (buf, tbuf, len);
|
||||
cons->context->buffer_len = buffer_len;
|
||||
free (tbuf);
|
||||
free (tline);
|
||||
|
||||
cons->context->buffer_len = r_strbuf_length (ob);
|
||||
if (grep->counter) {
|
||||
int cnt = grep->charCounter? strlen (cons->context->buffer): cons->lines;
|
||||
if (cons->context->buffer_len < 10) {
|
||||
@ -637,19 +627,32 @@ R_API int r_cons_grepbuf(char *buf, int len) {
|
||||
snprintf (cons->context->buffer, cons->context->buffer_len, "%d\n", cnt);
|
||||
cons->context->buffer_len = strlen (cons->context->buffer);
|
||||
cons->num->value = cons->lines;
|
||||
return;
|
||||
}
|
||||
|
||||
const int ob_len = r_strbuf_length (ob);
|
||||
if (ob_len >= cons->context->buffer_sz) {
|
||||
cons->context->buffer_sz = ob_len + 1;
|
||||
cons->context->buffer = r_strbuf_drain (ob);
|
||||
} else {
|
||||
memcpy (cons->context->buffer, r_strbuf_getbin (ob, NULL), ob_len);
|
||||
cons->context->buffer[ob_len] = 0;
|
||||
r_strbuf_free (ob);
|
||||
}
|
||||
cons->context->buffer_len = ob_len;
|
||||
|
||||
if (grep->sort != -1) {
|
||||
#define INSERT_LINES(list)\
|
||||
do {\
|
||||
r_list_foreach (list, iter, str) {\
|
||||
int len = strlen (str);\
|
||||
memcpy (ptr, str, len);\
|
||||
memcpy (ptr + len, "\n", 2);\
|
||||
ptr += len + 1;\
|
||||
nl++;\
|
||||
do {\
|
||||
r_list_foreach (list, iter, str) {\
|
||||
int len = strlen (str);\
|
||||
memcpy (ptr, str, len);\
|
||||
memcpy (ptr + len, "\n", 2);\
|
||||
ptr += len + 1;\
|
||||
nl++;\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
while (false)
|
||||
while (false)
|
||||
|
||||
RListIter *iter;
|
||||
int nl = 0;
|
||||
@ -668,7 +671,6 @@ R_API int r_cons_grepbuf(char *buf, int len) {
|
||||
r_list_free (unsorted_lines);
|
||||
unsorted_lines = NULL;
|
||||
}
|
||||
return cons->lines;
|
||||
}
|
||||
|
||||
R_API int r_cons_grep_line(char *buf, int len) {
|
||||
@ -702,7 +704,7 @@ R_API int r_cons_grep_line(char *buf, int len) {
|
||||
if (grep->icase) {
|
||||
r_str_case (str, false);
|
||||
}
|
||||
char *p = strstr (in, grep->strings[i]);
|
||||
const char *p = strstr (in, grep->strings[i]);
|
||||
if (!p) {
|
||||
ampfail = 0;
|
||||
continue;
|
||||
|
@ -2390,7 +2390,6 @@ static void rop_kuery(void *data, const char *input) {
|
||||
char *dup = strdup (sdbkv_value (kv));
|
||||
bool flag = false; // to free tok when doing strdup
|
||||
char *size = strtok (dup, " ");
|
||||
char *outtok = strtok (NULL, "{}");
|
||||
char *tok = strtok (NULL, "{}");
|
||||
if (!tok) {
|
||||
tok = strdup ("NOP");
|
||||
|
@ -1346,10 +1346,8 @@ R_API int r_debug_continue_until_nonblock(RDebug *dbg, ut64 addr) {
|
||||
}
|
||||
|
||||
R_API bool r_debug_continue_back(RDebug *dbg) {
|
||||
RDebugSession *before;
|
||||
RBreakpointItem *prev = NULL;
|
||||
int has_bp;
|
||||
ut64 pc, end_addr;
|
||||
ut64 pc;
|
||||
if (!dbg) {
|
||||
return false;
|
||||
}
|
||||
@ -1363,14 +1361,16 @@ R_API bool r_debug_continue_back(RDebug *dbg) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Get previous state */
|
||||
RListIter *iter = r_list_head (dbg->sessions);
|
||||
before = iter? iter->data: NULL; //XXX: currently use first session.
|
||||
if (!iter || !before) {
|
||||
if (!dbg->sessions) {
|
||||
return false;
|
||||
}
|
||||
|
||||
end_addr = r_debug_reg_get (dbg, dbg->reg->name[R_REG_NAME_PC]);
|
||||
/* Get previous state */
|
||||
RListIter *iter = dbg->sessions->head;
|
||||
if (!iter || !iter->data) {
|
||||
return false;
|
||||
}
|
||||
RDebugSession *before = iter->data; //XXX: currently use first session.
|
||||
ut64 end_addr = r_debug_reg_get (dbg, dbg->reg->name[R_REG_NAME_PC]);
|
||||
//eprintf ("before session (%d) 0x%08"PFMT64x"=> to 0x%08"PFMT64x"\n", before->key.id, before->key.addr, end_addr);
|
||||
|
||||
/* Rollback to previous state */
|
||||
@ -1378,7 +1378,7 @@ R_API bool r_debug_continue_back(RDebug *dbg) {
|
||||
|
||||
/* ### Get previous breakpoint ### */
|
||||
// Firstly set the breakpoint at end address
|
||||
has_bp = r_bp_get_in (dbg->bp, end_addr, R_BP_PROT_EXEC) != NULL;
|
||||
bool has_bp = r_bp_get_in (dbg->bp, end_addr, R_BP_PROT_EXEC) != NULL;
|
||||
if (!has_bp) {
|
||||
r_bp_add_sw (dbg->bp, end_addr, dbg->bpsize, R_BP_PROT_EXEC);
|
||||
}
|
||||
@ -1420,6 +1420,7 @@ R_API bool r_debug_continue_back(RDebug *dbg) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static int show_syscall(RDebug *dbg, const char *sysreg) {
|
||||
const char *sysname;
|
||||
char regname[32];
|
||||
|
@ -803,7 +803,7 @@ R_API void r_cons_grep_parsecmd(char *cmd, const char *quotestr);
|
||||
R_API char * r_cons_grep_strip(char *cmd, const char *quotestr);
|
||||
R_API void r_cons_grep_process(char * grep);
|
||||
R_API int r_cons_grep_line(char *buf, int len); // must be static
|
||||
R_API int r_cons_grepbuf(char *buf, int len);
|
||||
R_API void r_cons_grepbuf();
|
||||
|
||||
R_API void r_cons_rgb(ut8 r, ut8 g, ut8 b, ut8 a);
|
||||
R_API void r_cons_rgb_fgbg(ut8 r, ut8 g, ut8 b, ut8 R, ut8 G, ut8 B);
|
||||
|
@ -63,7 +63,7 @@ typedef struct r_oflist_t {
|
||||
// #define r_list_empty(x) (!x || (!(x->head) && !(x->tail)))
|
||||
#define r_list_empty(x) (!(x) || !(x)->length)
|
||||
#define r_list_head(x) ((x)? (x)->head: NULL)
|
||||
#define r_list_tail(x) x->tail
|
||||
#define r_list_tail(x) ((x)? (x)->tail: NULL)
|
||||
|
||||
#define r_list_iter_get(x)\
|
||||
x->data;\
|
||||
@ -83,6 +83,7 @@ R_API RListIter *r_list_prepend(RList *list, void *data);
|
||||
R_API RListIter *r_list_insert(RList *list, int n, void *data);
|
||||
R_API int r_list_length(const RList *list);
|
||||
R_API void *r_list_first(const RList *list);
|
||||
R_API void *r_list_last(const RList *list);
|
||||
R_API RListIter *r_list_add_sorted(RList *list, void *data, RListComparator cmp);
|
||||
R_API void r_list_sort(RList *list, RListComparator cmp);
|
||||
R_API RList *r_list_uniq(const RList *list, RListComparator cmp);
|
||||
|
@ -31,6 +31,7 @@ static inline void r_str_rmch(char *s, char ch) {
|
||||
#define r_str_array(x,y) ((y>=0 && y<(sizeof(x)/sizeof(*x)))?x[y]:"")
|
||||
R_API const char *r_str_pad(const char ch, int len);
|
||||
R_API const char *r_str_rstr(const char *base, const char *p);
|
||||
R_API const char *r_strstr_ansi (const char *a, const char *b);
|
||||
R_API const char *r_str_rchr(const char *base, const char *p, int ch);
|
||||
R_API const char *r_str_closer_chr(const char *b, const char *s);
|
||||
R_API int r_str_bounds(const char *str, int *h);
|
||||
|
@ -38,11 +38,17 @@ R_API RListIter *r_list_get_next(RListIter *list) {
|
||||
return list->n;
|
||||
}
|
||||
|
||||
// rename to head/last
|
||||
R_API void *r_list_first(const RList *list) {
|
||||
r_return_val_if_fail (list, NULL);
|
||||
return list->head ? list->head->data : NULL;
|
||||
}
|
||||
|
||||
R_API void *r_list_last(const RList *list) {
|
||||
r_return_val_if_fail (list, NULL);
|
||||
return list->tail ? list->tail->data : NULL;
|
||||
}
|
||||
|
||||
R_API void r_list_init(RList *list) {
|
||||
list->head = NULL;
|
||||
list->tail = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user