From: Dmitry Volyntsev Date: Sat, 15 Nov 2025 02:22:56 +0000 (-0800) Subject: Ensuring string values are zero-terminated. X-Git-Tag: 0.9.5~26 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=e7caa46d;p=njs.git Ensuring string values are zero-terminated. This helps when some code requires a string value to be zero-terminated to avoid copying and adding \0 byte. It adds small overhead (less than 3% in worst case of an empty string value) to existing sizeof(njs_value_t) + sizeof(njs_string_t) = 32. --- diff --git a/src/njs_scope.c b/src/njs_scope.c index cd1176a2..9d7b5776 100644 --- a/src/njs_scope.c +++ b/src/njs_scope.c @@ -199,7 +199,7 @@ njs_scope_value_index(njs_vm_t *vm, const njs_value_t *src, njs_uint_t runtime, + njs_string_map_size(length); } - value_size += sizeof(njs_string_t) + size; + value_size += sizeof(njs_string_t) + size + 1; } value_size += sizeof(njs_index_t); @@ -221,6 +221,8 @@ njs_scope_value_index(njs_vm_t *vm, const njs_value_t *src, njs_uint_t runtime, string->length = src->string.data->length; string->size = src->string.data->size; + string->start[size] = '\0'; + memcpy(string->start, start, size); } diff --git a/src/njs_string.c b/src/njs_string.c index 1a2b2333..ae680889 100644 --- a/src/njs_string.c +++ b/src/njs_string.c @@ -147,6 +147,7 @@ njs_string_new(njs_vm_t *vm, njs_value_t *value, const u_char *start, } +/* Underlying string data is zero-terminated. */ u_char * njs_string_alloc(njs_vm_t *vm, njs_value_t *value, uint64_t size, uint64_t length) @@ -164,12 +165,12 @@ njs_string_alloc(njs_vm_t *vm, njs_value_t *value, uint64_t size, value->atom_id = NJS_ATOM_STRING_unknown; if (size != length && length > NJS_STRING_MAP_STRIDE) { - map_offset = njs_string_map_offset(size); + map_offset = njs_string_map_offset(size + njs_length("\0")); total = map_offset + njs_string_map_size(length); } else { map_offset = 0; - total = size; + total = size + njs_length("\0"); } string = njs_mp_alloc(vm->mem_pool, sizeof(njs_string_t) + total); @@ -181,6 +182,8 @@ njs_string_alloc(njs_vm_t *vm, njs_value_t *value, uint64_t size, string->size = size; string->length = length; + string->start[size] = '\0'; + if (map_offset != 0) { map = (uint32_t *) (string->start + map_offset); map[0] = 0; diff --git a/src/njs_string.h b/src/njs_string.h index 225721ed..2a676ee0 100644 --- a/src/njs_string.h +++ b/src/njs_string.h @@ -37,7 +37,7 @@ #define njs_string_map_offset(size) njs_align_size((size), sizeof(uint32_t)) #define njs_string_map_start(p) \ - ((uint32_t *) njs_align_ptr((p), sizeof(uint32_t))) + ((uint32_t *) njs_align_ptr((u_char *) (p) + 1, sizeof(uint32_t))) #define njs_string_map_size(length) \ (((length - 1) / NJS_STRING_MAP_STRIDE) * sizeof(uint32_t)) diff --git a/src/njs_value.h b/src/njs_value.h index 61a46c0a..1422f02c 100644 --- a/src/njs_value.h +++ b/src/njs_value.h @@ -517,6 +517,7 @@ typedef struct { njs_assert((value)->string.data != NULL); \ (str)->length = (value)->string.data->size; \ (str)->start = (u_char *) (value)->string.data->start; \ + njs_assert((str)->start[(str)->length] == '\0'); \ } while (0) diff --git a/src/njs_vm.c b/src/njs_vm.c index fe4e3a31..348316a1 100644 --- a/src/njs_vm.c +++ b/src/njs_vm.c @@ -1520,31 +1520,12 @@ njs_vm_value_to_string(njs_vm_t *vm, njs_str_t *dst, njs_value_t *src) } -/* - * If string value is null-terminated the corresponding C string - * is returned as is, otherwise the new copy is allocated with - * the terminating zero byte. - */ const char * njs_vm_value_to_c_string(njs_vm_t *vm, njs_value_t *value) { - u_char *p, *data; - size_t size; - njs_assert(njs_is_string(value)); - size = value->string.data->size; - - data = njs_mp_alloc(vm->mem_pool, size + njs_length("\0")); - if (njs_slow_path(data == NULL)) { - njs_memory_error(vm); - return NULL; - } - - p = njs_cpymem(data, value->string.data->start, size); - *p++ = '\0'; - - return (const char *) data; + return (const char *) value->string.data->start; } diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index 0c5e55cc..5b6d556b 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -7825,6 +7825,9 @@ static njs_unit_test_t njs_test[] = { njs_str("'\\ud83d\\udc4d'.length"), njs_str("1") }, + { njs_str("'\\u00A0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'.length"), + njs_str("35") }, + { njs_str("'\\ud83d abc \\udc4d'"), njs_str("� abc �") },