diff --git a/external/njs_xml_module.c b/external/njs_xml_module.c
index 4736c3ac1..d3f18f98a 100644
--- a/external/njs_xml_module.c
+++ b/external/njs_xml_module.c
@@ -1693,7 +1693,7 @@ njs_xml_parse_ns_list(njs_vm_t *vm, njs_str_t *src)
while (*p != '\0') {
idx = out - buf;
- if (idx >= size) {
+ if (idx + 1 >= size) {
size *= 2;
n = njs_mp_alloc(njs_vm_memory_pool(vm), size * sizeof(char *));
diff --git a/external/qjs_xml_module.c b/external/qjs_xml_module.c
index ebb87657c..e526a3bfe 100644
--- a/external/qjs_xml_module.c
+++ b/external/qjs_xml_module.c
@@ -1740,7 +1740,7 @@ qjs_xml_parse_ns_list(JSContext *cx, u_char *src)
while (*p != '\0') {
idx = out - buf;
- if (idx >= size) {
+ if (idx + 1 >= size) {
size *= 2;
buf = js_realloc(cx, buf, size * sizeof(char *));
diff --git a/test/xml/xml.t.mjs b/test/xml/xml.t.mjs
index 8590bddc9..19f9c1740 100644
--- a/test/xml/xml.t.mjs
+++ b/test/xml/xml.t.mjs
@@ -127,6 +127,12 @@ let c14n_tsuite = {
expected: `foo` },
{ call: (doc) => xml.exclusiveC14n(doc.pdu.elem1, null, false, 'a b c d e f g h i j'),
expected: `foo` },
+ /* a prefix count that is a power of two exercises the namespace list
+ growth boundary, where the terminating NULL used to land one slot
+ past the buffer. */
+ { call: (doc) => xml.exclusiveC14n(doc.pdu.elem1, null, false,
+ Array(128).fill('n1').join(' ')),
+ expected: `foo` },
{ doc: `ToveJani`,
call: (doc) => xml.c14n(doc.note),
expected: `ToveJani` },