diff options
| author | Karel Zak <kzak@redhat.com> | 2021-08-06 12:02:39 +0200 |
|---|---|---|
| committer | Karel Zak <kzak@redhat.com> | 2021-08-06 12:02:39 +0200 |
| commit | 9ea47344ca59f1fb9fc5dfb11f223a309c0644e3 (patch) | |
| tree | c82ffd4e7eecfdb1f4a3d469576aca89783e3d3c | |
| parent | f55be401884d651350f15881cb5a9b8a8f120b24 (diff) | |
| download | util-linux-9ea47344ca59f1fb9fc5dfb11f223a309c0644e3.tar.gz | |
lib/buffer: add support for "safe" encoding
Signed-off-by: Karel Zak <kzak@redhat.com>
| -rw-r--r-- | include/buffer.h | 9 | ||||
| -rw-r--r-- | lib/Makemodule.am | 2 | ||||
| -rw-r--r-- | lib/buffer.c | 67 | ||||
| -rw-r--r-- | libmount/src/optstr.c | 14 | ||||
| -rw-r--r-- | misc-utils/lsblk.c | 4 |
5 files changed, 80 insertions, 16 deletions
diff --git a/include/buffer.h b/include/buffer.h index 5c081fb81f..724bcbe90a 100644 --- a/include/buffer.h +++ b/include/buffer.h @@ -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 */ diff --git a/lib/Makemodule.am b/lib/Makemodule.am index 1cdd1b146c..d32a20a2c4 100644 --- a/lib/Makemodule.am +++ b/lib/Makemodule.am @@ -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 diff --git a/lib/buffer.c b/lib/buffer.c index 3c112dd9de..b63b3684a9 100644 --- a/lib/buffer.c +++ b/lib/buffer.c @@ -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); diff --git a/libmount/src/optstr.c b/libmount/src/optstr.c index d37c7bcd42..21707d1ed3 100644 --- a/libmount/src/optstr.c +++ b/libmount/src/optstr.c @@ -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)); diff --git a/misc-utils/lsblk.c b/misc-utils/lsblk.c index 4a501eda09..100eba0779 100644 --- a/misc-utils/lsblk.c +++ b/misc-utils/lsblk.c @@ -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: |
