lib/buffer: add support for "safe" encoding

Signed-off-by: Karel Zak <kzak@redhat.com>
pull/1407/head
Karel Zak 1 year ago
parent f55be40188
commit 9ea47344ca
  1. 9
      include/buffer.h
  2. 2
      lib/Makemodule.am
  3. 67
      lib/buffer.c
  4. 14
      libmount/src/optstr.c
  5. 4
      misc-utils/lsblk.c

@ -10,6 +10,9 @@ struct ul_buffer {
size_t sz; /* allocated space for data */
size_t chunksize;
char *encoded; /* encoded data (from mbs_safe_encode_to_buffer)) */
size_t encoded_sz; /* space allocated for encoded data */
char **ptrs; /* saved pointers */
size_t nptrs; /* number of saved poiters */
};
@ -26,12 +29,16 @@ int ul_buffer_append_data(struct ul_buffer *buf, const char *data, size_t sz);
int ul_buffer_append_string(struct ul_buffer *buf, const char *str);
int ul_buffer_append_ntimes(struct ul_buffer *buf, size_t n, const char *str);
int ul_buffer_set_data(struct ul_buffer *buf, const char *data, size_t sz);
char *ul_buffer_get_data(struct ul_buffer *buf, size_t *sz);
char *ul_buffer_get_data(struct ul_buffer *buf, size_t *sz, size_t *width);
char *ul_buffer_get_safe_data(struct ul_buffer *buf, size_t *sz, size_t *width, const char *safechars);
size_t ul_buffer_get_bufsiz(struct ul_buffer *buf);
int ul_buffer_save_pointer(struct ul_buffer *buf, unsigned short ptr_idx);
char *ul_buffer_get_pointer(struct ul_buffer *buf, unsigned short ptr_idx);
size_t ul_buffer_get_pointer_length(struct ul_buffer *buf, unsigned short ptr_idx);
size_t ul_buffer_get_safe_pointer_width(struct ul_buffer *buf, unsigned short ptr_idx);
#endif /* UTIL_LINUX_BUFFER */

@ -203,7 +203,7 @@ test_pwdutils_CFLAGS = $(AM_CFLAGS) -DTEST_PROGRAM
test_remove_env_SOURCES = lib/env.c
test_remove_env_CFLAGS = $(AM_CFLAGS) -DTEST_PROGRAM
test_buffer_SOURCES = lib/buffer.c
test_buffer_SOURCES = lib/buffer.c lib/mbsalign.c
test_buffer_CFLAGS = $(AM_CFLAGS) -DTEST_PROGRAM_BUFFER
if LINUX

@ -5,6 +5,7 @@
* Written by Karel Zak <kzak@redhat.com>
*/
#include "buffer.h"
#include "mbsalign.h"
void ul_buffer_reset_data(struct ul_buffer *buf)
{
@ -26,6 +27,10 @@ void ul_buffer_free_data(struct ul_buffer *buf)
free(buf->ptrs);
buf->ptrs = NULL;
buf->nptrs = 0;
free(buf->encoded);
buf->encoded = NULL;
buf->encoded_sz = 0;
}
void ul_buffer_set_chunksize(struct ul_buffer *buf, size_t sz)
@ -61,15 +66,26 @@ char *ul_buffer_get_pointer(struct ul_buffer *buf, unsigned short ptr_idx)
return NULL;
}
/* returns length from begin to the pointer */
size_t ul_buffer_get_pointer_length(struct ul_buffer *buf, unsigned short ptr_idx)
{
char *ptr = ul_buffer_get_pointer(buf, ptr_idx);
if (ptr)
if (ptr && ptr > buf->begin)
return ptr - buf->begin;
return 0;
}
/* returns width of data in safe encoding (from the begin to the pointer) */
size_t ul_buffer_get_safe_pointer_width(struct ul_buffer *buf, unsigned short ptr_idx)
{
size_t len = ul_buffer_get_pointer_length(buf, ptr_idx);
if (!len)
return 0;
return mbs_safe_nwidth(buf->begin, len, NULL);
}
void ul_buffer_refer_string(struct ul_buffer *buf, char *str)
{
@ -157,10 +173,12 @@ int ul_buffer_set_data(struct ul_buffer *buf, const char *data, size_t sz)
return ul_buffer_append_data(buf, data, sz);
}
char *ul_buffer_get_data(struct ul_buffer *buf, size_t *sz)
char *ul_buffer_get_data(struct ul_buffer *buf, size_t *sz, size_t *width)
{
if (sz)
*sz = buf->end - buf->begin;
if (width)
*width = buf->begin && *buf->begin ? mbs_width(buf->begin) : 0;
return buf->begin;
}
@ -170,6 +188,42 @@ size_t ul_buffer_get_bufsiz(struct ul_buffer *buf)
return buf->sz;
}
/* encode data by mbs_safe_encode() to avoid control and non-printable chars */
char *ul_buffer_get_safe_data(struct ul_buffer *buf, size_t *sz, size_t *width, const char *safechars)
{
char *data = ul_buffer_get_data(buf, NULL, NULL);
size_t encsz, wsz = 0;
char *res = NULL;
if (!data)
goto nothing;
encsz = mbs_safe_encode_size(buf->sz) + 1;
if (encsz > buf->encoded_sz) {
char *tmp = realloc(buf->encoded, encsz);
if (!tmp)
goto nothing;
buf->encoded = tmp;
buf->encoded_sz = encsz;
}
res = mbs_safe_encode_to_buffer(data, &wsz, buf->encoded, safechars);
if (!res || !wsz || wsz == (size_t) -1)
goto nothing;
if (width)
*width = wsz;
if (sz)
*sz = strlen(res);
return res;
nothing:
if (width)
*width = 0;
if (sz)
*sz = 0;
return NULL;
}
#ifdef TEST_PROGRAM_BUFFER
@ -197,18 +251,21 @@ int main(void)
ul_buffer_append_string(&buf, "bbb");
ul_buffer_save_pointer(&buf, PTR_BBB);
str = ul_buffer_get_data(&buf, &sz);
str = ul_buffer_get_data(&buf, &sz, NULL);
printf("data [%zu] '%s'\n", sz, str);
printf(" pointer data len: AAA=%zu, BBB=%zu\n",
ul_buffer_get_pointer_length(&buf, PTR_AAA),
ul_buffer_get_pointer_length(&buf, PTR_BBB));
printf(" pointer data width: AAA=%zu, BBB=%zu\n",
ul_buffer_get_safe_pointer_width(&buf, PTR_AAA),
ul_buffer_get_safe_pointer_width(&buf, PTR_BBB));
ul_buffer_reset_data(&buf);
ul_buffer_append_string(&buf, "This is really long string to test the buffer function.");
ul_buffer_save_pointer(&buf, PTR_AAA);
ul_buffer_append_string(&buf, " YES!");
str = ul_buffer_get_data(&buf, &sz);
str = ul_buffer_get_data(&buf, &sz, NULL);
printf("data [%zu] '%s'\n", sz, str);
printf(" pointer data len: AAA=%zu\n", ul_buffer_get_pointer_length(&buf, PTR_AAA));
@ -217,7 +274,7 @@ int main(void)
ul_buffer_refer_string(&buf, str);
ul_buffer_append_data(&buf, ",", 1);
ul_buffer_append_string(&buf, "bar");
str = ul_buffer_get_data(&buf, &sz);
str = ul_buffer_get_data(&buf, &sz, NULL);
printf("data [%zu] '%s'\n", sz, str);
ul_buffer_free_data(&buf);

@ -224,7 +224,7 @@ int mnt_optstr_append_option(char **optstr, const char *name, const char *value)
rc = __buffer_append_option(&buf, name, nsz, value, vsz);
*optstr = ul_buffer_get_data(&buf, NULL);
*optstr = ul_buffer_get_data(&buf, NULL, NULL);
return rc;
}
/**
@ -261,7 +261,7 @@ int mnt_optstr_prepend_option(char **optstr, const char *name, const char *value
free(*optstr);
}
*optstr = ul_buffer_get_data(&buf, NULL);
*optstr = ul_buffer_get_data(&buf, NULL, NULL);
return rc;
}
@ -558,11 +558,11 @@ int mnt_split_optstr(const char *optstr, char **user, char **vfs,
}
if (vfs)
*vfs = rc ? NULL : ul_buffer_get_data(&xvfs, NULL);
*vfs = rc ? NULL : ul_buffer_get_data(&xvfs, NULL, NULL);
if (fs)
*fs = rc ? NULL : ul_buffer_get_data(&xfs, NULL);
*fs = rc ? NULL : ul_buffer_get_data(&xfs, NULL, NULL);
if (user)
*user = rc ? NULL : ul_buffer_get_data(&xuser, NULL);
*user = rc ? NULL : ul_buffer_get_data(&xuser, NULL, NULL);
if (rc) {
ul_buffer_free_data(&xvfs);
ul_buffer_free_data(&xfs);
@ -626,7 +626,7 @@ int mnt_optstr_get_options(const char *optstr, char **subset,
break;
}
*subset = rc ? NULL : ul_buffer_get_data(&buf, NULL);
*subset = rc ? NULL : ul_buffer_get_data(&buf, NULL, NULL);
if (rc)
ul_buffer_free_data(&buf);
return rc;
@ -834,7 +834,7 @@ int mnt_optstr_apply_flags(char **optstr, unsigned long flags,
goto err;
}
*optstr = ul_buffer_get_data(&buf, NULL);
*optstr = ul_buffer_get_data(&buf, NULL, NULL);
}
DBG(CXT, ul_debug("new optstr '%s'", *optstr));

@ -820,7 +820,7 @@ static char *device_get_data(
if (i + 1 < n)
ul_buffer_append_data(&buf, "\n", 1);
}
str = ul_buffer_get_data(&buf, NULL);
str = ul_buffer_get_data(&buf, NULL, NULL);
break;
}
case COL_FSROOTS:
@ -838,7 +838,7 @@ static char *device_get_data(
if (i + 1 < n)
ul_buffer_append_data(&buf, "\n", 1);
}
str = ul_buffer_get_data(&buf, NULL);
str = ul_buffer_get_data(&buf, NULL, NULL);
break;
}
case COL_LABEL:

Loading…
Cancel
Save