diff --git a/libr/cons/grep.c b/libr/cons/grep.c index e294ce39c6..4c009a887a 100644 --- a/libr/cons/grep.c +++ b/libr/cons/grep.c @@ -591,10 +591,16 @@ R_API int r_cons_grepbuf(char *buf, int len) { char *str = r_str_ndup (tline, ret); char *newstr = r_str_newf (Color_INVERT"%s"Color_RESET, grep->str); if (str && newstr) { - str = r_str_replace (str, grep->str, newstr, 1); - ret = strlen (str); - memcpy (out, str, ret); - memcpy (out + ret, "\n", 2); + if (grep->icase) { + str = r_str_replace_icase (str, grep->str, newstr, 1, 1); + } else { + str = r_str_replace (str, grep->str, newstr, 1); + } + if (str) { + ret = strlen (str); + memcpy (out, str, ret); + memcpy (out + ret, "\n", 2); + } } free (str); free (newstr); diff --git a/libr/include/r_util/r_str.h b/libr/include/r_util/r_str.h index 413c3da32c..f2dbf7516d 100644 --- a/libr/include/r_util/r_str.h +++ b/libr/include/r_util/r_str.h @@ -53,6 +53,7 @@ R_API int r_str_split(char *str, char ch); R_API RList *r_str_split_list(char *str, const char *c); R_API int *r_str_split_lines(char *str, int *count); R_API char* r_str_replace(char *str, const char *key, const char *val, int g); +R_API char *r_str_replace_icase(char *str, const char *key, const char *val, int g, int keep_case); R_API char *r_str_replace_in(char *str, ut32 sz, const char *key, const char *val, int g); #define r_str_cpy(x,y) memmove(x,y,strlen(y)+1); R_API int r_str_bits(char *strout, const ut8 *buf, int len, const char *bitz); diff --git a/libr/util/str.c b/libr/util/str.c index 8973f251ec..7bbc462662 100644 --- a/libr/util/str.c +++ b/libr/util/str.c @@ -932,12 +932,10 @@ R_API char *r_str_appendch(char *x, char y) { } R_API char* r_str_replace(char *str, const char *key, const char *val, int g) { + r_return_val_if_fail (str && key && val, NULL); + int off, i, klen, vlen, slen; char *newstr, *scnd, *p = str; - - if (!str || !key || !val) { - return NULL; - } klen = strlen (key); vlen = strlen (val); if (klen == 1 && vlen < 2) { @@ -958,10 +956,9 @@ R_API char* r_str_replace(char *str, const char *key, const char *val, int g) { off = (int)(size_t)(p - str); scnd = strdup (p + klen); slen += vlen - klen; - // HACK: this 32 avoids overwrites wtf newstr = realloc (str, slen + klen + 1); - if (!newstr) { - eprintf ("realloc fail\n"); + if (!newstr || !scnd) { + eprintf ("alloc fail\n"); R_FREE (str); free (scnd); break; @@ -979,6 +976,67 @@ R_API char* r_str_replace(char *str, const char *key, const char *val, int g) { return str; } +R_API char *r_str_replace_icase(char *str, const char *key, const char *val, int g, int keep_case) { + r_return_val_if_fail (str && key && val, NULL); + + int off, i, klen, vlen, slen; + char *newstr, *scnd, *p = str, *tmp_val = NULL; + klen = strlen (key); + vlen = strlen (val); + + slen = strlen (str); + for (i = 0; i < slen;) { + p = (char *)r_str_casestr (str + i, key); + if (!p) { + break; + } + off = (int)(size_t) (p - str); + scnd = strdup (p + klen); + slen += vlen - klen; + newstr = realloc (str, slen + klen + 1); + tmp_val = strdup (val); + + if (!newstr || !tmp_val || !scnd) { + goto alloc_fail; + } + + str = newstr; + p = str + off; + + if (keep_case) { + char *str_case = r_str_ndup (p, klen); + if (!str_case) { + goto alloc_fail; + } + tmp_val = r_str_replace_icase (tmp_val, key, str_case, 0, 0); + free (str_case); + if (!tmp_val) { + goto alloc_fail; + } + } + + memcpy (p, tmp_val, vlen); + memcpy (p + vlen, scnd, strlen (scnd) + 1); + i = off + vlen; + free (tmp_val); + free (scnd); + if (!g) { + break; + } + } + return str; + +alloc_fail: + eprintf ("alloc fail\n"); + free (str); + if (str != newstr) { + free (newstr); + } + free (scnd); + free (tmp_val); + return NULL; +} + /* replace the key in str with val. * * str - input string