Skip to content

Commit e7caa46

Browse files
committed
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.
1 parent fc526af commit e7caa46

File tree

6 files changed

+14
-24
lines changed

6 files changed

+14
-24
lines changed

src/njs_scope.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ njs_scope_value_index(njs_vm_t *vm, const njs_value_t *src, njs_uint_t runtime,
199199
+ njs_string_map_size(length);
200200
}
201201

202-
value_size += sizeof(njs_string_t) + size;
202+
value_size += sizeof(njs_string_t) + size + 1;
203203
}
204204

205205
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,
221221
string->length = src->string.data->length;
222222
string->size = src->string.data->size;
223223

224+
string->start[size] = '\0';
225+
224226
memcpy(string->start, start, size);
225227
}
226228

src/njs_string.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ njs_string_new(njs_vm_t *vm, njs_value_t *value, const u_char *start,
147147
}
148148

149149

150+
/* Underlying string data is zero-terminated. */
150151
u_char *
151152
njs_string_alloc(njs_vm_t *vm, njs_value_t *value, uint64_t size,
152153
uint64_t length)
@@ -164,12 +165,12 @@ njs_string_alloc(njs_vm_t *vm, njs_value_t *value, uint64_t size,
164165
value->atom_id = NJS_ATOM_STRING_unknown;
165166

166167
if (size != length && length > NJS_STRING_MAP_STRIDE) {
167-
map_offset = njs_string_map_offset(size);
168+
map_offset = njs_string_map_offset(size + njs_length("\0"));
168169
total = map_offset + njs_string_map_size(length);
169170

170171
} else {
171172
map_offset = 0;
172-
total = size;
173+
total = size + njs_length("\0");
173174
}
174175

175176
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,
181182
string->size = size;
182183
string->length = length;
183184

185+
string->start[size] = '\0';
186+
184187
if (map_offset != 0) {
185188
map = (uint32_t *) (string->start + map_offset);
186189
map[0] = 0;

src/njs_string.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
#define njs_string_map_offset(size) njs_align_size((size), sizeof(uint32_t))
3838

3939
#define njs_string_map_start(p) \
40-
((uint32_t *) njs_align_ptr((p), sizeof(uint32_t)))
40+
((uint32_t *) njs_align_ptr((u_char *) (p) + 1, sizeof(uint32_t)))
4141

4242
#define njs_string_map_size(length) \
4343
(((length - 1) / NJS_STRING_MAP_STRIDE) * sizeof(uint32_t))

src/njs_value.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,7 @@ typedef struct {
517517
njs_assert((value)->string.data != NULL); \
518518
(str)->length = (value)->string.data->size; \
519519
(str)->start = (u_char *) (value)->string.data->start; \
520+
njs_assert((str)->start[(str)->length] == '\0'); \
520521
} while (0)
521522

522523

src/njs_vm.c

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1520,31 +1520,12 @@ njs_vm_value_to_string(njs_vm_t *vm, njs_str_t *dst, njs_value_t *src)
15201520
}
15211521

15221522

1523-
/*
1524-
* If string value is null-terminated the corresponding C string
1525-
* is returned as is, otherwise the new copy is allocated with
1526-
* the terminating zero byte.
1527-
*/
15281523
const char *
15291524
njs_vm_value_to_c_string(njs_vm_t *vm, njs_value_t *value)
15301525
{
1531-
u_char *p, *data;
1532-
size_t size;
1533-
15341526
njs_assert(njs_is_string(value));
15351527

1536-
size = value->string.data->size;
1537-
1538-
data = njs_mp_alloc(vm->mem_pool, size + njs_length("\0"));
1539-
if (njs_slow_path(data == NULL)) {
1540-
njs_memory_error(vm);
1541-
return NULL;
1542-
}
1543-
1544-
p = njs_cpymem(data, value->string.data->start, size);
1545-
*p++ = '\0';
1546-
1547-
return (const char *) data;
1528+
return (const char *) value->string.data->start;
15481529
}
15491530

15501531

src/test/njs_unit_test.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7825,6 +7825,9 @@ static njs_unit_test_t njs_test[] =
78257825
{ njs_str("'\\ud83d\\udc4d'.length"),
78267826
njs_str("1") },
78277827

7828+
{ njs_str("'\\u00A0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'.length"),
7829+
njs_str("35") },
7830+
78287831
{ njs_str("'\\ud83d abc \\udc4d'"),
78297832
njs_str("� abc �") },
78307833

0 commit comments

Comments
 (0)