]> git.kaiwu.me - njs.git/commitdiff
Modules: fix shared dict state JSON separators
authorDmitry Volyntsev <xeioex@nginx.com>
Sat, 10 Oct 2026 01:40:28 +0000 (18:40 -0700)
committerDmitry Volyntsev <xeioexception@gmail.com>
Thu, 15 Oct 2026 01:49:05 +0000 (18:49 -0700)
When saving a shared dict zone with timeout=, expired entries are
skipped.  A comma is appended whenever another tree node follows a live
entry, even if all remaining nodes are expired.  This can leave a
trailing comma in the state file, making it invalid JSON.

Insert commas before live entries only when a previous entry has been
rendered, so skipped entries do not affect the separators.

nginx/ngx_js_shared_dict.c

index 22526f5b79b7fa7c98c4d2cc67fd74c1c2d3eb9f..5c14d67c2b8ac8ac7515eb0eec9dd42fb39c282c 100644 (file)
@@ -1999,6 +1999,7 @@ ngx_js_dict_render_json(ngx_js_dict_t *dict, njs_chb_t *chain)
 {
     u_char              *p, *dst;
     size_t               len;
+    ngx_uint_t           first;
     ngx_msec_t           now;
     ngx_time_t          *tp;
     ngx_rbtree_t        *rbtree;
@@ -2017,6 +2018,8 @@ ngx_js_dict_render_json(ngx_js_dict_t *dict, njs_chb_t *chain)
         return NGX_OK;
     }
 
+    first = 1;
+
     for (rn = ngx_rbtree_min(rbtree->root, rbtree->sentinel);
          rn != NULL;
          rn = next)
@@ -2029,6 +2032,12 @@ ngx_js_dict_render_json(ngx_js_dict_t *dict, njs_chb_t *chain)
             continue;
         }
 
+        if (!first) {
+            njs_chb_append_literal(chain, ",");
+        }
+
+        first = 0;
+
         if (ngx_js_render_string(chain, &node->sn.str) != NGX_OK) {
             return NGX_ERROR;
         }
@@ -2067,10 +2076,6 @@ ngx_js_dict_render_json(ngx_js_dict_t *dict, njs_chb_t *chain)
         }
 
         njs_chb_append_literal(chain, "}");
-
-        if (next != NULL) {
-            njs_chb_append_literal(chain, ",");
-        }
     }
 
     njs_chb_append_literal(chain, "}");