From nobody Tue Dec 16 08:32:44 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1754664990; cv=none; d=zohomail.com; s=zohoarc; b=aeh5RglAPRi0q3f/4y99YwlBYfIk+Q/DkdTtBH9HEGzjO0bOhgRXRtLLXkU02Q0jjgW5/5N7JBxMEazOjAeqB/P3WOtXItgu7JOAk6xBUb2/txBcAmPt2A9Q9hLQ2I9xG+6sGGuvMK23qI8gYozdx1iNIO5kwJU7jy280lJ0mX0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1754664990; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=vRMIu2sOc8ho9gldf/0/Ow6xK9iiXJMrSVqeHIXyoNY=; b=h/7iTxEx8CADY0Gi8wFscjAuV5cJZjefdjZyKVt6acrelcD2H8Juqpj2VR7QPtTnxtTQkks2PQ8yu3+bf43UB9L9u0nDhdL5D96WJx3oIQ3KCiEd11xPwiBkDQaqp14zfQEd5HzmZg+99XUeIDLC+UvO4J5N2QzK/uy4pjIUYaQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1754664990200851.4748630750078; Fri, 8 Aug 2025 07:56:30 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1074667.1437193 (Exim 4.92) (envelope-from ) id 1ukOVw-0000zb-1G; Fri, 08 Aug 2025 14:56:12 +0000 Received: by outflank-mailman (output) from mailman id 1074667.1437193; Fri, 08 Aug 2025 14:56:11 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1ukOVv-0000zO-RX; Fri, 08 Aug 2025 14:56:11 +0000 Received: by outflank-mailman (input) for mailman id 1074667; Fri, 08 Aug 2025 14:56:10 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1ukOVu-0000Vw-2P for xen-devel@lists.xenproject.org; Fri, 08 Aug 2025 14:56:10 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1ukOVt-007zrZ-2w; Fri, 08 Aug 2025 14:56:09 +0000 Received: from [2a01:e0a:1da:8420:b77:bd5:6e45:7633] (helo=l14..) by xenbits.xenproject.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1ukOVt-009BYT-27; Fri, 08 Aug 2025 14:56:09 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xenproject.org; s=20200302mail; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=vRMIu2sOc8ho9gldf/0/Ow6xK9iiXJMrSVqeHIXyoNY=; b=t4yE+O72N18PnGBjxjBJtEwsPG AJwQ4blV8QeBEnXfj/CRBe6ulEqOU7avsptKBYrpUqqwDxWoeUG2aRL52pVYjQbqZus/ABQHfha1B le4fknbkC8BPUG/OLy3CpFM2LykUbYxJM2CRzn1jVSOHCIrOhsSDXYZ2EhvRypjnSSqI=; From: Anthony PERARD To: xen-devel@lists.xenproject.org Cc: Anthony PERARD , Juergen Gross Subject: [XEN PATCH 05/11] libxl: Convert libxl__json_parse() to use json-c Date: Fri, 8 Aug 2025 16:55:56 +0200 Message-Id: <20250808145602.41716-6-anthony@xenproject.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250808145602.41716-1-anthony@xenproject.org> References: <20250808145602.41716-1-anthony@xenproject.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xenproject.org) X-ZM-MESSAGEID: 1754664990783116600 Content-Type: text/plain; charset="utf-8" From: Anthony PERARD This reuse the "json_callback_*" implemented for the yajl parser as they don't really need to be changed. It's just awkward to have to cast between `unsigned char` and `char.` Replace few strncpy() by memcpy() to let the compiler know we want to copy the string without the terminating nul, as we are adding it just after. Also, it should be possible to keep using YAJL parser when json-c library isn't available. Signed-off-by: Anthony PERARD Reviewed-by: Jason Andryuk --- tools/include/libxl_json.h | 4 ++ tools/libs/light/libxl_json.c | 120 ++++++++++++++++++++++++++++++++-- 2 files changed, 120 insertions(+), 4 deletions(-) diff --git a/tools/include/libxl_json.h b/tools/include/libxl_json.h index 3f97267eae..f0b4871e0e 100644 --- a/tools/include/libxl_json.h +++ b/tools/include/libxl_json.h @@ -42,6 +42,7 @@ yajl_gen_status libxl_ms_vm_genid_gen_json(yajl_gen hand,= libxl_ms_vm_genid *p); # define HAVE_YAJL_V2 1 #endif =20 +#ifdef HAVE_LIBYAJL #ifdef HAVE_YAJL_V2 =20 typedef size_t libxl_yajl_length; @@ -89,5 +90,8 @@ static inline yajl_gen libxl_yajl_gen_alloc(const yajl_al= loc_funcs *allocFuncs) } =20 #endif /* !HAVE_YAJL_V2 */ +#else +typedef size_t libxl_yajl_length; +#endif /* !HAVE_LIBYAJL */ =20 #endif /* LIBXL_JSON_H */ diff --git a/tools/libs/light/libxl_json.c b/tools/libs/light/libxl_json.c index 9b8ef2cab9..44ee6e213f 100644 --- a/tools/libs/light/libxl_json.c +++ b/tools/libs/light/libxl_json.c @@ -16,7 +16,25 @@ =20 #include =20 +#ifdef HAVE_LIBJSONC +#include +#define USE_LIBJSONC_PARSER +#endif + +#ifdef HAVE_LIBYAJL +# ifndef USE_LIBJSONC_PARSER +# define USE_LIBYAJL_PARSER +# endif +#endif + + +#ifdef USE_LIBJSONC_PARSER +#include +#endif + +#ifdef USE_LIBYAJL_PARSER #include +#endif #include =20 #include "libxl_internal.h" @@ -25,7 +43,9 @@ =20 typedef struct libxl__yajl_ctx { libxl__gc *gc; +#ifdef USE_LIBYAJL_PARSER yajl_handle hand; +#endif libxl__json_object *head; libxl__json_object *current; #ifdef DEBUG_ANSWER @@ -33,7 +53,7 @@ typedef struct libxl__yajl_ctx { #endif } libxl__yajl_ctx; =20 -#ifdef DEBUG_ANSWER +#if defined(DEBUG_ANSWER) && defined(USE_LIBYAJL_PARSER) #if YAJL_VERSION < 20000 # define DEBUG_GEN_ALLOC(ctx) \ if ((ctx)->g =3D=3D NULL) { \ @@ -759,7 +779,7 @@ static int json_callback_number(void *opaque, const cha= r *s, libxl_yajl_length l obj =3D libxl__json_object_alloc(ctx->gc, JSON_NUMBER); =20 t =3D libxl__zalloc(ctx->gc, len + 1); - strncpy(t, s, len); + memcpy(t, s, len); t[len] =3D 0; =20 obj->u.string =3D t; @@ -806,7 +826,7 @@ static int json_callback_map_key(void *opaque, const un= signed char *str, =20 DEBUG_GEN_STRING(ctx, str, len); =20 - strncpy(t, (const char *) str, len); + memcpy(t, (const char *) str, len); t[len] =3D 0; =20 if (libxl__json_object_is_map(obj)) { @@ -890,6 +910,7 @@ static int json_callback_end_array(void *opaque) return 1; } =20 +#ifdef USE_LIBYAJL_PARSER static yajl_callbacks callbacks =3D { json_callback_null, json_callback_boolean, @@ -903,28 +924,111 @@ static yajl_callbacks callbacks =3D { json_callback_start_array, json_callback_end_array }; +#endif =20 static void yajl_ctx_free(libxl__yajl_ctx *yajl_ctx) { +#ifdef USE_LIBYAJL_PARSER if (yajl_ctx->hand) { yajl_free(yajl_ctx->hand); yajl_ctx->hand =3D NULL; } +#endif DEBUG_GEN_FREE(yajl_ctx); } =20 +#ifdef USE_LIBJSONC_PARSER +static int jso_visiter(json_object *jso, + int flags, + json_object *parent_jso, + const char *jso_key, + size_t *jso_index, + void *userarg) +{ + enum json_type type; + int r; + + if (jso_key && flags !=3D JSON_C_VISIT_SECOND) { + json_callback_map_key(userarg, (const unsigned char*)jso_key, strl= en(jso_key)); + } + type =3D json_object_get_type(jso); + switch (type) { + case json_type_null: + r =3D json_callback_null(userarg); + break; + case json_type_boolean: + r =3D json_callback_boolean(userarg, json_object_get_boolean(jso)); + break; + case json_type_int: + case json_type_double: { + // it might be better to use on of + // json_object_get_{int,int64,uint64,double} instead. + // but would need to replace json_callback_number(). + const char *s =3D json_object_get_string(jso); + r =3D json_callback_number(userarg, s, strlen(s)); + break; + } + case json_type_object: + if (flags !=3D JSON_C_VISIT_SECOND) { + r =3D json_callback_start_map(userarg); + } else { + r =3D json_callback_end_map(userarg); + } + break; + case json_type_array: + if (flags !=3D JSON_C_VISIT_SECOND) { + r =3D json_callback_start_array(userarg); + } else { + r =3D json_callback_end_array(userarg); + } + break; + case json_type_string: { + const char *s =3D json_object_get_string(jso); + const int len =3D json_object_get_string_len(jso); + r =3D json_callback_string(userarg, (const unsigned char*)s, len); + break; + } + default: + /* error */ + r =3D 0; + } + if (r =3D=3D 0) + return JSON_C_VISIT_RETURN_ERROR; + return JSON_C_VISIT_RETURN_CONTINUE; +} +#endif + libxl__json_object *libxl__json_parse(libxl__gc *gc, const char *s) { +#ifdef USE_LIBYAJL_PARSER yajl_status status; + unsigned char *str =3D NULL; +#endif libxl__yajl_ctx yajl_ctx; libxl__json_object *o =3D NULL; - unsigned char *str =3D NULL; +#ifdef USE_LIBJSONC_PARSER + json_object *jso; + enum json_tokener_error error; + + jso =3D json_tokener_parse_verbose(s, &error); + if (!jso) { + LOG(ERROR, "json-c parse error: %s", json_tokener_error_desc(error= )); + goto out; + } +#endif =20 memset(&yajl_ctx, 0, sizeof (yajl_ctx)); yajl_ctx.gc =3D gc; =20 DEBUG_GEN_ALLOC(&yajl_ctx); =20 +#ifdef USE_LIBJSONC_PARSER + int r =3D json_c_visit(jso, 0, jso_visiter, &yajl_ctx); + if (r < 0) { + LOG(ERROR, "json_c_visit failed"); + goto out; + } +#elif defined(USE_LIBYAJL_PARSER) if (yajl_ctx.hand =3D=3D NULL) { yajl_ctx.hand =3D libxl__yajl_alloc(&callbacks, NULL, &yajl_ctx); } @@ -935,6 +1039,7 @@ libxl__json_object *libxl__json_parse(libxl__gc *gc, c= onst char *s) status =3D yajl_complete_parse(yajl_ctx.hand); if (status !=3D yajl_status_ok) goto out; +#endif =20 o =3D yajl_ctx.head; =20 @@ -943,13 +1048,20 @@ libxl__json_object *libxl__json_parse(libxl__gc *gc,= const char *s) yajl_ctx.head =3D NULL; =20 yajl_ctx_free(&yajl_ctx); +#ifdef USE_LIBJSONC_PARSER + json_object_put(jso); +#endif return o; =20 out: +#ifdef USE_LIBJSONC_PARSER + json_object_put(jso); +#elif defined(USE_LIBYAJL_PARSER) str =3D yajl_get_error(yajl_ctx.hand, 1, (const unsigned char*)s, strl= en(s)); =20 LIBXL__LOG(libxl__gc_owner(gc), LIBXL__LOG_ERROR, "yajl error: %s", st= r); yajl_free_error(yajl_ctx.hand, str); +#endif yajl_ctx_free(&yajl_ctx); return NULL; } --=20 Anthony PERARD