On 19/02/2026 18:45, William Lallemand wrote:
> Well it's just changing iterating on 1 octet and you don't have to
handle > 10
> items so that's only inelegant more than inefficient. But I agree,
the API is
> not great. I stripped down our mjson code since the latest CVE, but
we could
> reintroduce mjson_next if needed.
Actually I started work on acme profiles spec too and introducing mjson_next
kind of thing would be required.
It is because profiles are listed like this:
"profiles": {
"profile1": "https://example.com/acme/docs/profiles#profile1",
"profile2": "https://example.com/acme/docs/profiles#profile2",
}
When user provides an invalid profile it would be useful to give a list
of supported profiles, but that requires iterating over keys...
And also doing stuff like
snprintf(profile, sizeof(profile), "$.meta.profiles.%s",
ctx->cfg->profile)
is not good as %s arg would require sanitization, and that seems hard to do.
I'm now thinking about an user-facing API like this:
struct buffer *record_values = NULL;
struct mjson_iter it;
record_values = get_trash_chunk();
if (mjson_iter_init(tokptr, toklen, "$.issuer-domain-names", &it)
!= MJSON_TOK_ARRAY) {
memprintf(errmsg, "couldn't get issuer-domain-names");
goto error;
}
while ((it.offset = mjson_iter_next(&it)) != 0) {
int ret;
if (it.array_index >= 10) {
memprintf(errmsg, "more then 10 entries in acme
issuer-domain-names");
goto error;
}
ret = mjson_get_string(it.val_ptr, it.val_len, "$", trash.area,
trash.size);
if (ret == -1) {
memprintf(errmsg, "issuer-domain-names contains values
other than strings");
goto error;
}
trash.data = ret;
...
}
if (it.array_index == 0) {
memprintf(errmsg, "0 entries in acme issuer-domain-names");
goto error;
}
So there is a struct that encapsulates all of the data required for
iteration.
Not entirely sure what the final API would be yet, needs refining.
I think I will submit both dns-persist and profiles patches first, and then
that mjson iterator thing later that rewrites the code to use iterator.
Ok with this? Or should I introduce that iter first?