mirror of
https://github.com/rizinorg/rizin
synced 2026-08-22 20:26:16 -04:00
Make rz_strbuf_slice() truncate on excessive len (#2115)
It is often useful to get a slice of some maximum len, also accepting smaller results if the source is not large enough. This also makes the function always operate on byte indices. Before, it was inconsistently skipping ansi codes sometimes. This also fixes potential oob writes in panels.c
This commit is contained in:
parent
bd7854d297
commit
17ef95aed8
3 changed files with 29 additions and 26 deletions
|
|
@ -16,7 +16,7 @@ typedef struct {
|
|||
#define RZ_STRBUF_SAFEGET(sb) (rz_strbuf_get(sb) ? rz_strbuf_get(sb) : "")
|
||||
RZ_API RzStrBuf *rz_strbuf_new(const char *s);
|
||||
RZ_API const char *rz_strbuf_set(RzStrBuf *sb, const char *s); // return = the string or NULL on fail
|
||||
RZ_API bool rz_strbuf_slice(RzStrBuf *sb, int from, int len);
|
||||
RZ_API bool rz_strbuf_slice(RzStrBuf *sb, size_t from, size_t len);
|
||||
RZ_API bool rz_strbuf_setbin(RzStrBuf *sb, const ut8 *s, size_t len);
|
||||
RZ_API ut8 *rz_strbuf_getbin(RzStrBuf *sb, int *len);
|
||||
RZ_API const char *rz_strbuf_setf(RzStrBuf *sb, const char *fmt, ...) RZ_PRINTF_CHECK(2, 3); // return = the string or NULL on fail
|
||||
|
|
|
|||
|
|
@ -110,36 +110,29 @@ RZ_API bool rz_strbuf_setbin(RzStrBuf *sb, const ut8 *s, size_t l) {
|
|||
/**
|
||||
* \brief Cuts the current string into a substring
|
||||
*
|
||||
* Only to be used on strings, not binary buffers.
|
||||
* If `len > sb->len - from`, then the resulting size will be truncated appropriately.
|
||||
*
|
||||
* \param sb RzStrBuf to use
|
||||
* \param from Begin index from where to cut
|
||||
* \param len Length of the substring to cut
|
||||
*
|
||||
* \return false when fails to to cut the current buffer into a substring
|
||||
*/
|
||||
RZ_API bool rz_strbuf_slice(RZ_NONNULL RzStrBuf *sb, int from, int len) {
|
||||
RZ_API bool rz_strbuf_slice(RZ_NONNULL RzStrBuf *sb, size_t from, size_t len) {
|
||||
rz_return_val_if_fail(sb && from >= 0 && len >= 0, false);
|
||||
if (from < 0 && len >= sb->len) {
|
||||
return false;
|
||||
if (from >= sb->len) {
|
||||
// trying to cut outside the buf
|
||||
return !sb->len && !from; // but it's fine if both are 0
|
||||
}
|
||||
char *s = rz_strbuf_get(sb);
|
||||
if (!from) {
|
||||
sb->len = len;
|
||||
sb->ptrlen = len + 1;
|
||||
s[len] = 0;
|
||||
return true;
|
||||
len = RZ_MIN(sb->len - from, len);
|
||||
if (from) {
|
||||
memmove(s, s + from, len);
|
||||
}
|
||||
const char *fr = rz_str_ansi_chrn(s, from + 1);
|
||||
const char *to = rz_str_ansi_chrn(s, from + len + 1);
|
||||
char *r = rz_str_newlen(fr, to - fr);
|
||||
rz_strbuf_fini(sb);
|
||||
rz_strbuf_init(sb);
|
||||
if (from >= len) {
|
||||
rz_strbuf_set(sb, "");
|
||||
free(r);
|
||||
return false;
|
||||
}
|
||||
rz_strbuf_set(sb, r);
|
||||
free(r);
|
||||
sb->len = len;
|
||||
sb->ptrlen = len + 1;
|
||||
s[len] = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,10 +6,20 @@
|
|||
|
||||
bool test_rz_strbuf_slice(void) {
|
||||
RzStrBuf *sa = rz_strbuf_new("foo,bar,cow");
|
||||
rz_strbuf_slice(sa, 2, 4); // should be from/to instead of from/len ?
|
||||
char *a = rz_strbuf_drain(sa);
|
||||
mu_assert_streq(a, "o,ba", "slicing fails");
|
||||
free(a);
|
||||
rz_strbuf_slice(sa, 2, 4);
|
||||
mu_assert_streq_free(rz_strbuf_drain(sa), "o,ba", "from + len");
|
||||
|
||||
sa = rz_strbuf_new("Restore our vision of natural progression");
|
||||
rz_strbuf_slice(sa, 0, 18);
|
||||
mu_assert_streq_free(rz_strbuf_drain(sa), "Restore our vision", "len");
|
||||
|
||||
sa = rz_strbuf_new("Drift with the ebb and flow");
|
||||
rz_strbuf_slice(sa, 15, 9001);
|
||||
mu_assert_streq_free(rz_strbuf_drain(sa), "ebb and flow", "from + escessive len");
|
||||
|
||||
sa = rz_strbuf_new("Intuition speak to me");
|
||||
rz_strbuf_slice(sa, 0, 9001);
|
||||
mu_assert_streq_free(rz_strbuf_drain(sa), "Intuition speak to me", "escessive len");
|
||||
|
||||
mu_end;
|
||||
}
|
||||
|
|
@ -233,4 +243,4 @@ bool all_tests() {
|
|||
return tests_passed != tests_run;
|
||||
}
|
||||
|
||||
mu_main(all_tests)
|
||||
mu_main(all_tests)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue