wmem: Make strbuf_utf8_validate() accept embedded NUL bytes
This commit is contained in:
parent
338e6b50e2
commit
6aa33f0fc9
|
@ -18,6 +18,7 @@
|
|||
#include <glib.h>
|
||||
#include <ws_symbol_export.h>
|
||||
#include <ws_attributes.h>
|
||||
#include <ws_posix_compat.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
@ -415,10 +415,35 @@ wmem_strbuf_destroy(wmem_strbuf_t *strbuf)
|
|||
wmem_free(strbuf->allocator, strbuf);
|
||||
}
|
||||
|
||||
bool
|
||||
wmem_strbuf_utf8_validate(wmem_strbuf_t *strbuf, const char **endptr)
|
||||
static bool
|
||||
string_utf8_validate(const char *str, ssize_t max_len, const char **endpptr)
|
||||
{
|
||||
return g_utf8_validate(strbuf->str, strbuf->len, endptr);
|
||||
bool valid;
|
||||
|
||||
if (max_len <= 0)
|
||||
return true;
|
||||
|
||||
valid = g_utf8_validate(str, max_len, endpptr);
|
||||
if (valid || **endpptr != '\0')
|
||||
return valid;
|
||||
|
||||
/* Invalid because of a nul byte. Skip nuls and continue. */
|
||||
max_len -= *endpptr - str;
|
||||
str = *endpptr;
|
||||
while (max_len > 0 && *str == '\0') {
|
||||
str++;
|
||||
max_len--;
|
||||
}
|
||||
return string_utf8_validate(str, max_len, endpptr);
|
||||
}
|
||||
|
||||
/* g_utf8_validate() returns FALSE in the string contains embedded NUL
|
||||
* bytes. We accept \x00 as valid and work around that to validate the
|
||||
* entire len bytes. */
|
||||
bool
|
||||
wmem_strbuf_utf8_validate(wmem_strbuf_t *strbuf, const char **endpptr)
|
||||
{
|
||||
return string_utf8_validate(strbuf->str, strbuf->len, endpptr);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1175,6 +1175,34 @@ wmem_test_strbuf(void)
|
|||
wmem_destroy_allocator(allocator);
|
||||
}
|
||||
|
||||
static void
|
||||
wmem_test_strbuf_validate(void)
|
||||
{
|
||||
wmem_strbuf_t *strbuf;
|
||||
const char *endptr;
|
||||
|
||||
strbuf = wmem_strbuf_new(NULL, "TEST\xEF ABC");
|
||||
g_assert_false(wmem_strbuf_utf8_validate(strbuf, &endptr));
|
||||
g_assert(endptr == &strbuf->str[4]);
|
||||
wmem_strbuf_destroy(strbuf);
|
||||
|
||||
strbuf = wmem_strbuf_new(NULL, NULL);
|
||||
wmem_strbuf_append_len(strbuf, "TEST\x00\x00 ABC", 10);
|
||||
g_assert_true(wmem_strbuf_utf8_validate(strbuf, &endptr));
|
||||
wmem_strbuf_destroy(strbuf);
|
||||
|
||||
strbuf = wmem_strbuf_new(NULL, NULL);
|
||||
wmem_strbuf_append_len(strbuf, "TEST\x00\xEF ABC", 10);
|
||||
g_assert_false(wmem_strbuf_utf8_validate(strbuf, &endptr));
|
||||
g_assert(endptr == &strbuf->str[5]);
|
||||
wmem_strbuf_destroy(strbuf);
|
||||
|
||||
strbuf = wmem_strbuf_new(NULL, NULL);
|
||||
wmem_strbuf_append_len(strbuf, "TEST\x00 ABC \x00 DEF \x00", 17);
|
||||
g_assert_true(wmem_strbuf_utf8_validate(strbuf, &endptr));
|
||||
wmem_strbuf_destroy(strbuf);
|
||||
}
|
||||
|
||||
static void
|
||||
wmem_test_tree(void)
|
||||
{
|
||||
|
@ -1466,6 +1494,7 @@ main(int argc, char **argv)
|
|||
g_test_add_func("/wmem/datastruct/queue", wmem_test_queue);
|
||||
g_test_add_func("/wmem/datastruct/stack", wmem_test_stack);
|
||||
g_test_add_func("/wmem/datastruct/strbuf", wmem_test_strbuf);
|
||||
g_test_add_func("/wmem/datastruct/strbuf/validate", wmem_test_strbuf_validate);
|
||||
g_test_add_func("/wmem/datastruct/tree", wmem_test_tree);
|
||||
g_test_add_func("/wmem/datastruct/itree", wmem_test_itree);
|
||||
|
||||
|
|
Loading…
Reference in New Issue