From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mx0a-002e3701.pphosted.com (mx0a-002e3701.pphosted.com [148.163.147.86]) by mx.groups.io with SMTP id smtpd.web08.2474.1608251319751543252 for ; Thu, 17 Dec 2020 16:28:40 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@hpe.com header.s=pps0720 header.b=Megc4e/W; spf=pass (domain: hpe.com, ip: 148.163.147.86, mailfrom: prvs=0621f7b516=abner.chang@hpe.com) Received: from pps.filterd (m0134420.ppops.net [127.0.0.1]) by mx0b-002e3701.pphosted.com (8.16.0.43/8.16.0.43) with SMTP id 0BI0Mu2j009453; Fri, 18 Dec 2020 00:28:39 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hpe.com; h=from : to : cc : subject : date : message-id : references : in-reply-to : content-type : content-transfer-encoding : mime-version; s=pps0720; bh=ZQiYY3Ai7+pbl0sztFl/TI+LhxHGYN8JxpmxYemwzgw=; b=Megc4e/WhZnclgn/kcJGnNgYG9LGJ94x1bAztklW7z+sIT1RMTjBG0Xmh3CEnMTVSSBb vpU4duJmG8ndCu2W/GRA1m098iwvLntQrKXix3NhX+otW5w0t16bosOVfYhJgF9eMqPl OxlrKKOwhkmU0N1037c8sGNjzsPd2e0r93W+F25ajiJ6Azzd4i8zKyqQONC7aHJvbpSY Ai8pNPB8ce84zkPhA5F+y5AqcidFwLfVv30HzdUGcK7GNJ3JFf9nokcPSrRUIS9+7mxH 2Ip6YTHTMGltkUKf3A0iS/ZcbfT1x5mY4Z3BDg7eMNpXo4GZaLTUXQa9DkhMvANdfS68 1Q== Received: from g4t3426.houston.hpe.com (g4t3426.houston.hpe.com [15.241.140.75]) by mx0b-002e3701.pphosted.com with ESMTP id 35ex94fppd-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 18 Dec 2020 00:28:38 +0000 Received: from G2W6311.americas.hpqcorp.net (g2w6311.austin.hp.com [16.197.64.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by g4t3426.houston.hpe.com (Postfix) with ESMTPS id 611866C; Fri, 18 Dec 2020 00:28:37 +0000 (UTC) Received: from G4W9335.americas.hpqcorp.net (16.208.33.85) by G2W6311.americas.hpqcorp.net (16.197.64.53) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 18 Dec 2020 00:27:31 +0000 Received: from G9W9209.americas.hpqcorp.net (2002:10dc:429c::10dc:429c) by G4W9335.americas.hpqcorp.net (2002:10d0:2155::10d0:2155) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 18 Dec 2020 00:27:31 +0000 Received: from NAM11-BN8-obe.outbound.protection.outlook.com (15.241.52.13) by G9W9209.americas.hpqcorp.net (16.220.66.156) with Microsoft SMTP Server (TLS) id 15.0.1497.2 via Frontend Transport; Fri, 18 Dec 2020 00:27:30 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=cqYz9ZGFuiDv9GqXGMSZjPBunnB7H8EV0/OOQvibSf0MBpuco9TAJo4/GOCCoD06ks/4ieyfPw5+nO1erEFqZymArT7CDa1D5i6Mu0oAary1jtfMZT+6RyaEhxWgtgs5mVSgJ0y+B1p4ZFedDdKrcJBO+/G4kSjqIH+mMplRdUA1ErnQkQU0m1NDnYbChrP61PQdRbui0D5LJ9SmrTULvgMmKAJJpA6vvU4QDuQL0PGFzxTqBy0kjVB4ikeSp4SfPmV1eIDk8R9jD/M6U6hrmEEQUxXkYbdLJe+bFrocXCSI6c/ZjKsPLCIPL/wycFgc+8J9fIG0RwyQwBBpLQRF+g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=oYFvHQkblWUntlrcsbZwDiNMF7mFWv070uZP8aXfU2o=; b=hxwG21MdQ3C5TwILO8kLZrvDOsmMZzSkHn/GD7ED84IsSHu1GM2hsnQCAHt06W1diZuI+J3evb048JwxVEIpV6GtsPBx72NpDg+XpJ9WwXRTZL01IXB+Z2MNOA0R7G47tbHUKNoajebTgA9cRtjfGSw7xqwliGJ7gVZgNo/t7ZZ5ao+UwBfxCAX/LXiCqr1M+/WYX4/sG1NCDtN64YN5yqh2OHhLKBxFsf4RmOTHeXwowvwsv7oD8c2C4YMhQZLyS7jPwHMufQfinpzRfFuYq8GdI2b4HtM+fQyhXEZyGhaUFEDhxgLuU3Y6i5ePq5EvXi2PWV9o/V036kZWjmXagA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=hpe.com; dmarc=pass action=none header.from=hpe.com; dkim=pass header.d=hpe.com; arc=none Received: from CS1PR8401MB1144.NAMPRD84.PROD.OUTLOOK.COM (2a01:111:e400:7508::16) by CS1PR8401MB0342.NAMPRD84.PROD.OUTLOOK.COM (2a01:111:e400:750a::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3676.25; Fri, 18 Dec 2020 00:27:29 +0000 Received: from CS1PR8401MB1144.NAMPRD84.PROD.OUTLOOK.COM ([fe80::a094:ed67:fb40:340e]) by CS1PR8401MB1144.NAMPRD84.PROD.OUTLOOK.COM ([fe80::a094:ed67:fb40:340e%10]) with mapi id 15.20.3654.025; Fri, 18 Dec 2020 00:27:28 +0000 From: "Abner Chang" To: "devel@edk2.groups.io" , "leif@nuviainc.com" CC: "Wang, Nickle (HPS SW)" , "O'Hanley, Peter (EXL)" Subject: Re: [edk2-devel] [PATCH v7 4/6] RedfishPkg/library: EDK2 port of jansson library Thread-Topic: [edk2-devel] [PATCH v7 4/6] RedfishPkg/library: EDK2 port of jansson library Thread-Index: AQHW1HGrIH03oj1/zUiJ89t5Siiwt6n7WtMQgAA3DACAAG2WgA== Date: Fri, 18 Dec 2020 00:27:28 +0000 Message-ID: References: <20201216031406.7136-1-abner.chang@hpe.com> <20201216031406.7136-5-abner.chang@hpe.com> <20201217123933.GM1664@vanye> <20201217175226.GQ1664@vanye> In-Reply-To: <20201217175226.GQ1664@vanye> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: edk2.groups.io; dkim=none (message not signed) header.d=none;edk2.groups.io; dmarc=none action=none header.from=hpe.com; x-originating-ip: [165.225.116.142] x-ms-publictraffictype: Email x-ms-office365-filtering-ht: Tenant x-ms-office365-filtering-correlation-id: 7c613e51-27c0-4168-fb44-08d8a2ebb3a6 x-ms-traffictypediagnostic: CS1PR8401MB0342: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:2803; x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: AJJd+7IJVwIbG5zYgd6hjqFTqKUDVK7sLze7wMulEIL3ws07YAQ1itm9l5yZ2Gf8S4xitC9v9ye+OqfEJ9+xlDVgjYwFskcwEootxlDY/1RfQowyFLEAb9UwKR6zGLvmnvEsC4Znvz39uxWn6yG34TjJDkCe4vMduDFEmsoXClrGz5Sv5Q49T0KnA41knWApKUZk3PU0rFx+FUvuKahC6UI1BSkMQIv4qYmoPA+9MWzr0Z3RbeBRApNAZTW+ddT3GQK757npDuPSTIPmnE17745OiAkmD9NDZiTuI6L/8A8Psz214WP0kpx8CCgKJQNEKpEn1CQHuy/uzw9zO44Uk3NZuyayr2G3D9prnkeJz/Blr0F+fA7b6207zml0p+DwjJlv0bKVDxSchaj/elBLEBxw76X9CLFb5AU0LCZ+D7cak3tJzy8ysCaYltf8wIW+Ka6d5ALh/q2MsvR1fmWHxPPtjM6knNovQBJGHqAmB1Q42z/xh+Tbtt1QLx0DNgHPxjGh/jf246cMcat0vMQepA== x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CS1PR8401MB1144.NAMPRD84.PROD.OUTLOOK.COM;PTR:;CAT:NONE;SFS:(136003)(346002)(366004)(396003)(39860400002)(376002)(4326008)(66556008)(45080400002)(83380400001)(8676002)(71200400001)(33656002)(52536014)(7696005)(186003)(6506007)(8936002)(86362001)(966005)(55236004)(9686003)(316002)(110136005)(5660300002)(64756008)(76116006)(55016002)(66946007)(2906002)(478600001)(53546011)(30864003)(26005)(54906003)(66476007)(66446008)(19627235002)(2004002)(579004)(559001);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata: =?us-ascii?Q?CvSdADZQIi/mJPFI1L+aTNvoD6wtyzsoEILqwbcyewX3HIOtvRNXS14qHxLj?= =?us-ascii?Q?QdAiaDsDf/E8XA3M7XejP+KaEL6RFxp6UpNCj4Pfq5/Ej/byrY7SlSEakqEl?= =?us-ascii?Q?9Yx6BzDKoxcMqxjP9cNGMNNnBfXQ+z2xpJb9XTA7g9cuUC6QYFgHsv6zcS3t?= =?us-ascii?Q?cgqo0XdxwgnyCldyGkBzDmjIGfTyYqFQX6YNVvn/IEeqEWW0TvaUug8autVv?= =?us-ascii?Q?SHsEnfuZmnBvKoKgD9/8NlRHgNRftNHzN0yCMrfCFZjejShcbdaYwacXJtNz?= =?us-ascii?Q?wv3DfBHhfDkKHuBeNZ/COq8LBz69FH9GHN9M5oDupbwBGWxS80FtC4CUvlqo?= =?us-ascii?Q?dT4bR3n25vL05XQqoEKczem2QxZcaKPD8RgaQah+sz1a/g2IEplKXJ/KmdRI?= =?us-ascii?Q?avqNN2nKMvsH0po2ICi1nRKfK5LGeZWvVnyv4zXSQ/jA+v0U3mvnjUuWSGOt?= =?us-ascii?Q?YZ5K6RpuDmt8mGzoUmWAE8ZLHUrki/TWSZwjrw80LefsPfEsDUr1y+wwc40l?= =?us-ascii?Q?uXgNW5UGaoSFxrNDgMVSwebhw0OSm8bUfwiwF5TK8Y2b2awd7P4pZpfNpyGu?= =?us-ascii?Q?fV9VUpd4eXFU/Dw+6DT1fzExSW3EwogpkSWnGx/g8t+9VBP+itCW6QY54P9x?= =?us-ascii?Q?owEP3vrAVcuMq+V+cHaHXdN7GGMQZ5xBy1YemOpgcVAg6sCy+60SggNOSeYC?= =?us-ascii?Q?zaFBa0ZDvm4Xkmq1ktVBRaUQF4I1pnHSY04dQIBlLHS+qhT1lwKPevLucSZN?= =?us-ascii?Q?FaJ7RMq9EV6ZoAQLLEzpcO0VVwallfGOUFzy8fkZHYmgxuX7mh+dLBG0tUnR?= =?us-ascii?Q?0QF/MZuMJvsJwNR221VuN1BzqaJJIx7iP89HNdhrECABupXTMzIPfw5w8Qvh?= =?us-ascii?Q?HWtKtcH8AtXGxJZb9qrBNi1doGrHHtrCxycLhr4BYgIoBTaZ7Itco9cj/7ez?= =?us-ascii?Q?u3VkjnfCu1RmJFWlUz1/4CDlFSuQAm2djDmiZPsAxcQ=3D?= X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: CS1PR8401MB1144.NAMPRD84.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-Network-Message-Id: 7c613e51-27c0-4168-fb44-08d8a2ebb3a6 X-MS-Exchange-CrossTenant-originalarrivaltime: 18 Dec 2020 00:27:28.6435 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 105b2061-b669-4b31-92ac-24d304d195dc X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: rPHGwK2DGsfGTBx9B8Xwb7KA9wBeFHCCOfMRHH7NYXonUBzORGVtPS3N7o46gPNLHuI7R+FqE8p3CcZ7ZdgbZw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CS1PR8401MB0342 X-OriginatorOrg: hpe.com X-Proofpoint-UnRewURL: 0 URL was un-rewritten MIME-Version: 1.0 X-HPE-SCL: -1 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.343,18.0.737 definitions=2020-12-17_17:2020-12-17,2020-12-17 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxscore=0 lowpriorityscore=0 adultscore=0 spamscore=0 bulkscore=0 impostorscore=0 suspectscore=0 mlxlogscore=999 clxscore=1015 priorityscore=1501 malwarescore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2009150000 definitions=main-2012180001 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable > -----Original Message----- > From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of > Leif Lindholm > Sent: Friday, December 18, 2020 1:52 AM > To: Chang, Abner (HPS SW/FW Technologist) > Cc: devel@edk2.groups.io; Wang, Nickle (HPS SW) ; > O'Hanley, Peter (EXL) > Subject: Re: [edk2-devel] [PATCH v7 4/6] RedfishPkg/library: EDK2 port o= f > jansson library >=20 > On Thu, Dec 17, 2020 at 14:40:20 +0000, Chang, Abner (HPS SW/FW > Technologist) wrote: > > > > > > > -----Original Message----- > > > From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf > > > Of Leif Lindholm > > > Sent: Thursday, December 17, 2020 8:40 PM > > > To: Chang, Abner (HPS SW/FW Technologist) > > > Cc: devel@edk2.groups.io; Wang, Nickle (HPS SW) > > > ; O'Hanley, Peter (EXL) > > > > Subject: Re: [edk2-devel] [PATCH v7 4/6] RedfishPkg/library: EDK2 > > > port of jansson library > > > > > > On Wed, Dec 16, 2020 at 11:14:04 +0800, Abner Chang wrote: > > > > edk2 JsonLib which is the edk2 port of open source jansson library= . > > > > (https://github.com/akheron/jansson) > > > > jansson library is the open source project to manipulate JSON data > > > > structure. > > > > > > > > Signed-off-by: Abner Chang > > > > > > > > Cc: Leif Lindholm > > > > Cc: Nickle Wang > > > > Cc: Peter O'Hanley > > > > --- > > > > RedfishPkg/Include/Library/JsonLib.h | 763 +++++++++++ > > > > RedfishPkg/Library/JsonLib/JsonLib.c | 964 ++++++++++++= ++ > > > > RedfishPkg/Library/JsonLib/JsonLib.inf | 89 ++ > > > > RedfishPkg/Library/JsonLib/Readme.rst | 40 + > > > > RedfishPkg/Library/JsonLib/jansson_config.h | 41 + > > > > .../Library/JsonLib/jansson_private_config.h | 19 + > > > > RedfishPkg/Library/JsonLib/load.c | 1111 ++++++++++++= +++++ > > > > RedfishPkg/RedfishPkg.ci.yaml | 8 +- > > > > RedfishPkg/RedfishPkg.dec | 11 + > > > > 9 files changed, 3045 insertions(+), 1 deletion(-) > > > > > > Please configure your git to use an orderfile for diffs. > > > This can be done by running BaseTools/Scripts/SetupGit.py in your > > > repository or manually by following > > > https://github.com/tianocore/tianocore.github.io/wiki/Laszlo%27s- > > > unkempt-git-guide-for-edk2-contributors-and-maintainers > > Will check it, I thought I have that configured. >=20 > If you, for example, copied the orderfile from the source tree somewhere > else instead of writing your own _or_ using the in-tree copy, then you c= ould > suffer from that file having been garbled in the tree for a while earlie= r this(?) > year. I found that I forget to assign order file to git format-patch. It's good = now. >=20 > > > > create mode 100644 RedfishPkg/Include/Library/JsonLib.h > > > > create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.c > > > > create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.inf > > > > create mode 100644 RedfishPkg/Library/JsonLib/Readme.rst > > > > create mode 100644 RedfishPkg/Library/JsonLib/jansson_config.h > > > > create mode 100644 > > > > RedfishPkg/Library/JsonLib/jansson_private_config.h > > > > create mode 100644 RedfishPkg/Library/JsonLib/load.c > > > > > > > > > > > diff --git a/RedfishPkg/Library/JsonLib/load.c > > > > b/RedfishPkg/Library/JsonLib/load.c > > > > new file mode 100644 > > > > index 0000000000..92063e63cb > > > > --- /dev/null > > > > +++ b/RedfishPkg/Library/JsonLib/load.c > > > > @@ -0,0 +1,1111 @@ > > > > +/* > > > > + * Copyright (c) 2009-2016 Petri Lehtinen > > > > + * > > > > + * Jansson is free software; you can redistribute it and/or > > > > +modify > > > > + * it under the terms of the MIT license. See LICENSE for details= . > > > > + > > > > + (C) Copyright 2020 Hewlett Packard Enterprise Development LP
> > > > + > > > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > > > > > This is not accurate. > > > You are adding the BSD-2-Clause-Patent license on top of the MIT > > > license for this contribution. The statement should be > > > > > > SPDX-License-Identifier: BSD-2-Clause-Patent AND MIT > > > > > > The way you're keeping the original header, then adding HPE > > > copyright, and then adding the SPDX tag is ideal though. Makes it > > > clear who did the license addition and when. > > Leif, not quite sure which way is accurate, looks like below? Or could > > please you give me the right one? :) Thanks > > > > Copyright (c) 2009-2016 Petri Lehtinen > > (C) Copyright 2020 Hewlett Packard Enterprise Development LP
> > > > SPDX-License-Identifier: BSD-2-Clause-Patent AND MIT >=20 > Just like what you submitted but with the SPDX-License-Identifier line > reading like above. I was complimenting you on doing it well, not asking= you > to change it further than the " AND MIT" bit. Ok, got you. Thanks though :) >=20 > / > Leif >=20 > > > > > > / > > > Leif > > > > > > > + */ > > > > + > > > > +#ifndef _GNU_SOURCE > > > > +#define _GNU_SOURCE > > > > +#endif > > > > + > > > > +#include "jansson_private.h" > > > > + > > > > +#include > > > > +#include > > > > +#include > > > > +#include > > > > +#include > > > > +#include > > > > +#ifdef HAVE_UNISTD_H > > > > +#include > > > > +#endif > > > > + > > > > +#include "jansson.h" > > > > +#include "strbuffer.h" > > > > +#include "utf.h" > > > > + > > > > +#define STREAM_STATE_OK 0 > > > > +#define STREAM_STATE_EOF -1 > > > > +#define STREAM_STATE_ERROR -2 > > > > + > > > > +#define TOKEN_INVALID -1 > > > > +#define TOKEN_EOF 0 > > > > +#define TOKEN_STRING 256 > > > > +#define TOKEN_INTEGER 257 > > > > +#define TOKEN_REAL 258 > > > > +#define TOKEN_TRUE 259 > > > > +#define TOKEN_FALSE 260 > > > > +#define TOKEN_NULL 261 > > > > + > > > > +/* Locale independent versions of isxxx() functions */ #define > > > > +l_isupper(c) ('A' <=3D (c) && (c) <=3D 'Z') #define l_islower(c) = ('a' > > > > +<=3D > > > > +(c) && (c) <=3D 'z') #define l_isalpha(c) (l_isupper(c) || > > > > +l_islower(c)) #define l_isdigit(c) ('0' <=3D (c) && (c) <=3D '9') > > > > +#define l_isxdigit(c) = \ > > > > + (l_isdigit(c) || ('A' <=3D (c) && (c) <=3D 'F') || ('a' <=3D = (c) && > > > > +(c) <=3D 'f')) > > > > + > > > > +/* Read one byte from stream, convert to unsigned char, then int,= and > > > > + return. return EOF on end of file. This corresponds to the > > > > + behaviour of fgetc(). */ > > > > +typedef int (*get_func)(void *data); > > > > + > > > > +typedef struct { > > > > + get_func get; > > > > + void *data; > > > > + char buffer[5]; > > > > + size_t buffer_pos; > > > > + int state; > > > > + int line; > > > > + int column, last_column; > > > > + size_t position; > > > > +} stream_t; > > > > + > > > > +typedef struct { > > > > + stream_t stream; > > > > + strbuffer_t saved_text; > > > > + size_t flags; > > > > + size_t depth; > > > > + int token; > > > > + union { > > > > + struct { > > > > + char *val; > > > > + size_t len; > > > > + } string; > > > > + json_int_t integer; > > > > + double real; > > > > + } value; > > > > +} lex_t; > > > > + > > > > +#define stream_to_lex(stream) container_of(stream, lex_t, stream) > > > > + > > > > +/*** error reporting ***/ > > > > + > > > > +static void error_set(json_error_t *error, const lex_t *lex, enum > > > json_error_code code, > > > > + const char *msg, ...) { > > > > + va_list ap; > > > > + char msg_text[JSON_ERROR_TEXT_LENGTH]; > > > > + char msg_with_context[JSON_ERROR_TEXT_LENGTH]; > > > > + > > > > + int line =3D -1, col =3D -1; > > > > + size_t pos =3D 0; > > > > + const char *result =3D msg_text; > > > > + > > > > + if (!error) > > > > + return; > > > > + > > > > + va_start(ap, msg); > > > > + vsnprintf(msg_text, JSON_ERROR_TEXT_LENGTH, msg, ap); > > > > + msg_text[JSON_ERROR_TEXT_LENGTH - 1] =3D '\0'; > > > > + va_end(ap); > > > > + > > > > + if (lex) { > > > > + const char *saved_text =3D > > > > + strbuffer_value(&lex->saved_text); > > > > + > > > > + line =3D lex->stream.line; > > > > + col =3D lex->stream.column; > > > > + pos =3D lex->stream.position; > > > > + > > > > + if (saved_text && saved_text[0]) { > > > > + if (lex->saved_text.length <=3D 20) { > > > > + snprintf(msg_with_context, > > > > + JSON_ERROR_TEXT_LENGTH, "%s > > > near '%s'", > > > > + msg_text, saved_text); > > > > + msg_with_context[JSON_ERROR_TEXT_LENGTH - 1] =3D = '\0'; > > > > + result =3D msg_with_context; > > > > + } > > > > + } else { > > > > + if (code =3D=3D json_error_invalid_syntax) { > > > > + /* More specific error code for premature end of = file. */ > > > > + code =3D json_error_premature_end_of_input; > > > > + } > > > > + if (lex->stream.state =3D=3D STREAM_STATE_ERROR) { > > > > + /* No context for UTF-8 decoding errors */ > > > > + result =3D msg_text; > > > > + } else { > > > > + snprintf(msg_with_context, > > > > + JSON_ERROR_TEXT_LENGTH, "%s > > > near end of file", > > > > + msg_text); > > > > + msg_with_context[JSON_ERROR_TEXT_LENGTH - 1] =3D = '\0'; > > > > + result =3D msg_with_context; > > > > + } > > > > + } > > > > + } > > > > + > > > > + jsonp_error_set(error, line, col, pos, code, "%s", result); } > > > > + > > > > +/*** lexical analyzer ***/ > > > > + > > > > +static void stream_init(stream_t *stream, get_func get, void *dat= a) { > > > > + stream->get =3D get; > > > > + stream->data =3D data; > > > > + stream->buffer[0] =3D '\0'; > > > > + stream->buffer_pos =3D 0; > > > > + > > > > + stream->state =3D STREAM_STATE_OK; > > > > + stream->line =3D 1; > > > > + stream->column =3D 0; > > > > + stream->position =3D 0; > > > > +} > > > > + > > > > +static int stream_get(stream_t *stream, json_error_t *error) { > > > > + int c; > > > > + > > > > + if (stream->state !=3D STREAM_STATE_OK) > > > > + return stream->state; > > > > + > > > > + if (!stream->buffer[stream->buffer_pos]) { > > > > + c =3D stream->get(stream->data); > > > > + if (c =3D=3D EOF) { > > > > + stream->state =3D STREAM_STATE_EOF; > > > > + return STREAM_STATE_EOF; > > > > + } > > > > + > > > > + stream->buffer[0] =3D c; > > > > + stream->buffer_pos =3D 0; > > > > + > > > > + if (0x80 <=3D c && c <=3D 0xFF) { > > > > + /* multi-byte UTF-8 sequence */ > > > > + size_t i, count; > > > > + > > > > + count =3D utf8_check_first(c); > > > > + if (!count) > > > > + goto out; > > > > + > > > > + assert(count >=3D 2); > > > > + > > > > + for (i =3D 1; i < count; i++) > > > > + stream->buffer[i] =3D stream->get(stream->data); > > > > + > > > > + if (!utf8_check_full(stream->buffer, count, NULL)) > > > > + goto out; > > > > + > > > > + stream->buffer[count] =3D '\0'; > > > > + } else > > > > + stream->buffer[1] =3D '\0'; > > > > + } > > > > + > > > > + c =3D stream->buffer[stream->buffer_pos++]; > > > > + > > > > + stream->position++; > > > > + if (c =3D=3D '\n') { > > > > + stream->line++; > > > > + stream->last_column =3D stream->column; > > > > + stream->column =3D 0; > > > > + } else if (utf8_check_first(c)) { > > > > + /* track the Unicode character column, so increment only = if > > > > + this is the first character of a UTF-8 sequence */ > > > > + stream->column++; > > > > + } > > > > + > > > > + return c; > > > > + > > > > +out: > > > > + stream->state =3D STREAM_STATE_ERROR; > > > > + error_set(error, stream_to_lex(stream), json_error_invalid_ut= f8, > > > > + "unable to decode byte 0x%x", c); > > > > + return STREAM_STATE_ERROR; > > > > +} > > > > + > > > > +static void stream_unget(stream_t *stream, int c) { > > > > + if (c =3D=3D STREAM_STATE_EOF || c =3D=3D STREAM_STATE_ERROR) > > > > + return; > > > > + > > > > + stream->position--; > > > > + if (c =3D=3D '\n') { > > > > + stream->line--; > > > > + stream->column =3D stream->last_column; > > > > + } else if (utf8_check_first(c)) > > > > + stream->column--; > > > > + > > > > + assert(stream->buffer_pos > 0); > > > > + stream->buffer_pos--; > > > > + assert(stream->buffer[stream->buffer_pos] =3D=3D c); } > > > > + > > > > +static int lex_get(lex_t *lex, json_error_t *error) { > > > > + return stream_get(&lex->stream, error); } > > > > + > > > > +static void lex_save(lex_t *lex, int c) { > > > > +strbuffer_append_byte(&lex->saved_text, c); } > > > > + > > > > +static int lex_get_save(lex_t *lex, json_error_t *error) { > > > > + int c =3D stream_get(&lex->stream, error); > > > > + if (c !=3D STREAM_STATE_EOF && c !=3D STREAM_STATE_ERROR) > > > > + lex_save(lex, c); > > > > + return c; > > > > +} > > > > + > > > > +static void lex_unget(lex_t *lex, int c) { > > > > +stream_unget(&lex->stream, c); } > > > > + > > > > +static void lex_unget_unsave(lex_t *lex, int c) { > > > > + if (c !=3D STREAM_STATE_EOF && c !=3D STREAM_STATE_ERROR) { > > > > +/* Since we treat warnings as errors, when assertions are turned > > > > + * off the "d" variable would be set but never used. Which is > > > > + * treated as an error by GCC. > > > > + */ > > > > +#ifndef NDEBUG > > > > + char d; > > > > +#endif > > > > + stream_unget(&lex->stream, c); #ifndef NDEBUG > > > > + d =3D > > > > +#endif > > > > + strbuffer_pop(&lex->saved_text); > > > > + assert(c =3D=3D d); > > > > + } > > > > +} > > > > + > > > > +static void lex_save_cached(lex_t *lex) { > > > > + while (lex->stream.buffer[lex->stream.buffer_pos] !=3D '\0') = { > > > > + lex_save(lex, lex->stream.buffer[lex->stream.buffer_pos])= ; > > > > + lex->stream.buffer_pos++; > > > > + lex->stream.position++; > > > > + } > > > > +} > > > > + > > > > +static void lex_free_string(lex_t *lex) { > > > > + jsonp_free(lex->value.string.val); > > > > + lex->value.string.val =3D NULL; > > > > + lex->value.string.len =3D 0; > > > > +} > > > > + > > > > +/* assumes that str points to 'u' plus at least 4 valid hex > > > > +digits */ static int32_t decode_unicode_escape(const char *str) { > > > > + int i; > > > > + int32_t value =3D 0; > > > > + > > > > + assert(str[0] =3D=3D 'u'); > > > > + > > > > + for (i =3D 1; i <=3D 4; i++) { > > > > + char c =3D str[i]; > > > > + value <<=3D 4; > > > > + if (l_isdigit(c)) > > > > + value +=3D c - '0'; > > > > + else if (l_islower(c)) > > > > + value +=3D c - 'a' + 10; > > > > + else if (l_isupper(c)) > > > > + value +=3D c - 'A' + 10; > > > > + else > > > > + return -1; > > > > + } > > > > + > > > > + return value; > > > > +} > > > > + > > > > +static void lex_scan_string(lex_t *lex, json_error_t *error) { > > > > + int c; > > > > + const char *p; > > > > + char *t; > > > > + int i; > > > > + > > > > + lex->value.string.val =3D NULL; > > > > + lex->token =3D TOKEN_INVALID; > > > > + > > > > + c =3D lex_get_save(lex, error); > > > > + > > > > + while (c !=3D '"') { > > > > + if (c =3D=3D STREAM_STATE_ERROR) > > > > + goto out; > > > > + > > > > + else if (c =3D=3D STREAM_STATE_EOF) { > > > > + error_set(error, lex, json_error_premature_end_of_inp= ut, > > > > + "premature end of input"); > > > > + goto out; > > > > + } > > > > + > > > > + else if (0 <=3D c && c <=3D 0x1F) { > > > > + /* control character */ > > > > + lex_unget_unsave(lex, c); > > > > + if (c =3D=3D '\n') > > > > + error_set(error, lex, json_error_invalid_syntax, > > > > + "unexpected > > > newline"); > > > > + else > > > > + error_set(error, lex, json_error_invalid_syntax, > > > > + "control character > > > 0x%x", > > > > + c); > > > > + goto out; > > > > + } > > > > + > > > > + else if (c =3D=3D '\\') { > > > > + c =3D lex_get_save(lex, error); > > > > + if (c =3D=3D 'u') { > > > > + c =3D lex_get_save(lex, error); > > > > + for (i =3D 0; i < 4; i++) { > > > > + if (!l_isxdigit(c)) { > > > > + error_set(error, lex, json_error_invalid_= syntax, > > > > + "invalid escape"); > > > > + goto out; > > > > + } > > > > + c =3D lex_get_save(lex, error); > > > > + } > > > > + } else if (c =3D=3D '"' || c =3D=3D '\\' || c =3D=3D = '/' || c =3D=3D 'b' || c =3D=3D 'f' || > > > > + c =3D=3D 'n' || c =3D=3D 'r' || c =3D=3D '= t') > > > > + c =3D lex_get_save(lex, error); > > > > + else { > > > > + error_set(error, lex, json_error_invalid_syntax, = "invalid > escape"); > > > > + goto out; > > > > + } > > > > + } else > > > > + c =3D lex_get_save(lex, error); > > > > + } > > > > + > > > > + /* the actual value is at most of the same length as the sour= ce > > > > + string, because: > > > > + - shortcut escapes (e.g. "\t") (length 2) are converted = to 1 byte > > > > + - a single \uXXXX escape (length 6) is converted to at m= ost 3 bytes > > > > + - two \uXXXX escapes (length 12) forming an UTF-16 surro= gate > pair > > > > + are converted to 4 bytes > > > > + */ > > > > + t =3D jsonp_malloc(lex->saved_text.length + 1); > > > > + if (!t) { > > > > + /* this is not very nice, since TOKEN_INVALID is returned= */ > > > > + goto out; > > > > + } > > > > + lex->value.string.val =3D t; > > > > + > > > > + /* + 1 to skip the " */ > > > > + p =3D strbuffer_value(&lex->saved_text) + 1; > > > > + > > > > + while (*p !=3D '"') { > > > > + if (*p =3D=3D '\\') { > > > > + p++; > > > > + if (*p =3D=3D 'u') { > > > > + size_t length; > > > > + int32_t value; > > > > + > > > > + value =3D decode_unicode_escape(p); > > > > + if (value < 0) { > > > > + error_set(error, lex, json_error_invalid_synt= ax, > > > > + "invalid Unicode escape '%.6s'", p = - 1); > > > > + goto out; > > > > + } > > > > + p +=3D 5; > > > > + > > > > + if (0xD800 <=3D value && value <=3D 0xDBFF) { > > > > + /* surrogate pair */ > > > > + if (*p =3D=3D '\\' && *(p + 1) =3D=3D 'u') { > > > > + int32_t value2 =3D decode_unicode_escape(= ++p); > > > > + if (value2 < 0) { > > > > + error_set(error, lex, json_error_inva= lid_syntax, > > > > + "invalid Unicode escape '%.= 6s'", p - 1); > > > > + goto out; > > > > + } > > > > + p +=3D 5; > > > > + > > > > + if (0xDC00 <=3D value2 && value2 <=3D 0xD= FFF) { > > > > + /* valid second surrogate */ > > > > + value =3D > > > > + ((value - 0xD800) << 10) + (value= 2 - 0xDC00) + 0x10000; > > > > + } else { > > > > + /* invalid second surrogate */ > > > > + error_set(error, lex, json_error_inva= lid_syntax, > > > > + "invalid Unicode '\\u%04X\\= u%04X'", value, value2); > > > > + goto out; > > > > + } > > > > + } else { > > > > + /* no second surrogate */ > > > > + error_set(error, lex, json_error_invalid_= syntax, > > > > + "invalid Unicode '\\u%04X'", va= lue); > > > > + goto out; > > > > + } > > > > + } else if (0xDC00 <=3D value && value <=3D 0xDFFF= ) { > > > > + error_set(error, lex, json_error_invalid_synt= ax, > > > > + "invalid Unicode '\\u%04X'", value)= ; > > > > + goto out; > > > > + } > > > > + > > > > + if (utf8_encode(value, t, &length)) > > > > + assert(0); > > > > + t +=3D length; > > > > + } else { > > > > + switch (*p) { > > > > + case '"': > > > > + case '\\': > > > > + case '/': > > > > + *t =3D *p; > > > > + break; > > > > + case 'b': > > > > + *t =3D '\b'; > > > > + break; > > > > + case 'f': > > > > + *t =3D '\f'; > > > > + break; > > > > + case 'n': > > > > + *t =3D '\n'; > > > > + break; > > > > + case 'r': > > > > + *t =3D '\r'; > > > > + break; > > > > + case 't': > > > > + *t =3D '\t'; > > > > + break; > > > > + default: > > > > + assert(0); > > > > + } > > > > + t++; > > > > + p++; > > > > + } > > > > + } else > > > > + *(t++) =3D *(p++); > > > > + } > > > > + *t =3D '\0'; > > > > + lex->value.string.len =3D t - lex->value.string.val; > > > > + lex->token =3D TOKEN_STRING; > > > > + return; > > > > + > > > > +out: > > > > + lex_free_string(lex); > > > > +} > > > > + > > > > +#ifndef JANSSON_USING_CMAKE /* disabled if using cmake */ #if > > > > +JSON_INTEGER_IS_LONG_LONG #ifdef _MSC_VER /* Microsoft Visual > > > Studio > > > > +*/ #define json_strtoint _strtoi64 #else #define json_strtoint > > > > +strtoll #endif #else #define json_strtoint strtol #endif #endif > > > > + > > > > +static int lex_scan_number(lex_t *lex, int c, json_error_t *error= ) { > > > > + const char *saved_text; > > > > + char *end; > > > > + double doubleval; > > > > + > > > > + lex->token =3D TOKEN_INVALID; > > > > + > > > > + if (c =3D=3D '-') > > > > + c =3D lex_get_save(lex, error); > > > > + > > > > + if (c =3D=3D '0') { > > > > + c =3D lex_get_save(lex, error); > > > > + if (l_isdigit(c)) { > > > > + lex_unget_unsave(lex, c); > > > > + goto out; > > > > + } > > > > + } else if (l_isdigit(c)) { > > > > + do > > > > + c =3D lex_get_save(lex, error); > > > > + while (l_isdigit(c)); > > > > + } else { > > > > + lex_unget_unsave(lex, c); > > > > + goto out; > > > > + } > > > > + > > > > + if (!(lex->flags & JSON_DECODE_INT_AS_REAL) && c !=3D '.' && = c > > > > + !=3D 'E' && > > > c !=3D 'e') { > > > > + json_int_t intval; > > > > + > > > > + lex_unget_unsave(lex, c); > > > > + > > > > + saved_text =3D strbuffer_value(&lex->saved_text); > > > > + > > > > + errno =3D 0; > > > > + intval =3D json_strtoint(saved_text, &end, 10); > > > > + if (errno =3D=3D ERANGE) { > > > > + if (intval < 0) > > > > + error_set(error, lex, json_error_numeric_overflow= , > > > > + "too big negative integer"); > > > > + else > > > > + error_set(error, lex, > > > > + json_error_numeric_overflow, "too big > > > integer"); > > > > + goto out; > > > > + } > > > > + > > > > + assert(end =3D=3D saved_text + lex->saved_text.length); > > > > + > > > > + lex->token =3D TOKEN_INTEGER; > > > > + lex->value.integer =3D intval; > > > > + return 0; > > > > + } > > > > + > > > > + if (c =3D=3D '.') { > > > > + c =3D lex_get(lex, error); > > > > + if (!l_isdigit(c)) { > > > > + lex_unget(lex, c); > > > > + goto out; > > > > + } > > > > + lex_save(lex, c); > > > > + > > > > + do > > > > + c =3D lex_get_save(lex, error); > > > > + while (l_isdigit(c)); > > > > + } > > > > + > > > > + if (c =3D=3D 'E' || c =3D=3D 'e') { > > > > + c =3D lex_get_save(lex, error); > > > > + if (c =3D=3D '+' || c =3D=3D '-') > > > > + c =3D lex_get_save(lex, error); > > > > + > > > > + if (!l_isdigit(c)) { > > > > + lex_unget_unsave(lex, c); > > > > + goto out; > > > > + } > > > > + > > > > + do > > > > + c =3D lex_get_save(lex, error); > > > > + while (l_isdigit(c)); > > > > + } > > > > + > > > > + lex_unget_unsave(lex, c); > > > > + > > > > + if (jsonp_strtod(&lex->saved_text, &doubleval)) { > > > > + error_set(error, lex, json_error_numeric_overflow, "real > > > > + number > > > overflow"); > > > > + goto out; > > > > + } > > > > + > > > > + lex->token =3D TOKEN_REAL; > > > > + lex->value.real =3D doubleval; > > > > + return 0; > > > > + > > > > +out: > > > > + return -1; > > > > +} > > > > + > > > > +static int lex_scan(lex_t *lex, json_error_t *error) { > > > > + int c; > > > > + > > > > + strbuffer_clear(&lex->saved_text); > > > > + > > > > + if (lex->token =3D=3D TOKEN_STRING) > > > > + lex_free_string(lex); > > > > + > > > > + do > > > > + c =3D lex_get(lex, error); > > > > + while (c =3D=3D ' ' || c =3D=3D '\t' || c =3D=3D '\n' || c = =3D=3D '\r'); > > > > + > > > > + if (c =3D=3D STREAM_STATE_EOF) { > > > > + lex->token =3D TOKEN_EOF; > > > > + goto out; > > > > + } > > > > + > > > > + if (c =3D=3D STREAM_STATE_ERROR) { > > > > + lex->token =3D TOKEN_INVALID; > > > > + goto out; > > > > + } > > > > + > > > > + lex_save(lex, c); > > > > + > > > > + if (c =3D=3D '{' || c =3D=3D '}' || c =3D=3D '[' || c =3D=3D = ']' || c =3D=3D ':' || c =3D=3D ',') > > > > + lex->token =3D c; > > > > + > > > > + else if (c =3D=3D '"') > > > > + lex_scan_string(lex, error); > > > > + > > > > + else if (l_isdigit(c) || c =3D=3D '-') { > > > > + if (lex_scan_number(lex, c, error)) > > > > + goto out; > > > > + } > > > > + > > > > + else if (l_isalpha(c)) { > > > > + /* eat up the whole identifier for clearer error messages= */ > > > > + const char *saved_text; > > > > + > > > > + do > > > > + c =3D lex_get_save(lex, error); > > > > + while (l_isalpha(c)); > > > > + lex_unget_unsave(lex, c); > > > > + > > > > + saved_text =3D strbuffer_value(&lex->saved_text); > > > > + > > > > + if (strcmp(saved_text, "true") =3D=3D 0) > > > > + lex->token =3D TOKEN_TRUE; > > > > + else if (strcmp(saved_text, "false") =3D=3D 0) > > > > + lex->token =3D TOKEN_FALSE; > > > > + else if (strcmp(saved_text, "null") =3D=3D 0) > > > > + lex->token =3D TOKEN_NULL; > > > > + else > > > > + lex->token =3D TOKEN_INVALID; > > > > + } > > > > + > > > > + else { > > > > + /* save the rest of the input UTF-8 sequence to get an er= ror > > > > + message of valid UTF-8 */ > > > > + lex_save_cached(lex); > > > > + lex->token =3D TOKEN_INVALID; > > > > + } > > > > + > > > > +out: > > > > + return lex->token; > > > > +} > > > > + > > > > +static char *lex_steal_string(lex_t *lex, size_t *out_len) { > > > > + char *result =3D NULL; > > > > + if (lex->token =3D=3D TOKEN_STRING) { > > > > + result =3D lex->value.string.val; > > > > + *out_len =3D lex->value.string.len; > > > > + lex->value.string.val =3D NULL; > > > > + lex->value.string.len =3D 0; > > > > + } > > > > + return result; > > > > +} > > > > + > > > > +static int lex_init(lex_t *lex, get_func get, size_t flags, void = *data) { > > > > + stream_init(&lex->stream, get, data); > > > > + if (strbuffer_init(&lex->saved_text)) > > > > + return -1; > > > > + > > > > + lex->flags =3D flags; > > > > + lex->token =3D TOKEN_INVALID; > > > > + return 0; > > > > +} > > > > + > > > > +static void lex_close(lex_t *lex) { > > > > + if (lex->token =3D=3D TOKEN_STRING) > > > > + lex_free_string(lex); > > > > + strbuffer_close(&lex->saved_text); > > > > +} > > > > + > > > > +/*** parser ***/ > > > > + > > > > +static json_t *parse_value(lex_t *lex, size_t flags, json_error_t > > > > +*error); > > > > + > > > > +static json_t *parse_object(lex_t *lex, size_t flags, json_error_= t > *error) { > > > > + json_t *object =3D json_object(); > > > > + if (!object) > > > > + return NULL; > > > > + > > > > + lex_scan(lex, error); > > > > + if (lex->token =3D=3D '}') > > > > + return object; > > > > + > > > > + while (1) { > > > > + char *key; > > > > + size_t len; > > > > + json_t *value; > > > > + > > > > + if (lex->token !=3D TOKEN_STRING) { > > > > + error_set(error, lex, json_error_invalid_syntax, "str= ing or '}' > > > expected"); > > > > + goto error; > > > > + } > > > > + > > > > + key =3D lex_steal_string(lex, &len); > > > > + if (!key) > > > > + return NULL; > > > > + if (memchr(key, '\0', len)) { > > > > + jsonp_free(key); > > > > + error_set(error, lex, json_error_null_byte_in_key, > > > > + "NUL byte in object key not supported"); > > > > + goto error; > > > > + } > > > > + > > > > + if (flags & JSON_REJECT_DUPLICATES) { > > > > + if (json_object_get(object, key)) { > > > > + jsonp_free(key); > > > > + error_set(error, lex, json_error_duplicate_key, > > > > + "duplicate object > > > key"); > > > > + goto error; > > > > + } > > > > + } > > > > + > > > > + lex_scan(lex, error); > > > > + if (lex->token !=3D ':') { > > > > + jsonp_free(key); > > > > + error_set(error, lex, json_error_invalid_syntax, "':'= expected"); > > > > + goto error; > > > > + } > > > > + > > > > + lex_scan(lex, error); > > > > + value =3D parse_value(lex, flags, error); > > > > + if (!value) { > > > > + jsonp_free(key); > > > > + goto error; > > > > + } > > > > + > > > > + if (json_object_set_new_nocheck(object, key, value)) { > > > > + jsonp_free(key); > > > > + goto error; > > > > + } > > > > + > > > > + jsonp_free(key); > > > > + > > > > + lex_scan(lex, error); > > > > + if (lex->token !=3D ',') > > > > + break; > > > > + > > > > + lex_scan(lex, error); > > > > + } > > > > + > > > > + if (lex->token !=3D '}') { > > > > + error_set(error, lex, json_error_invalid_syntax, "'}' exp= ected"); > > > > + goto error; > > > > + } > > > > + > > > > + return object; > > > > + > > > > +error: > > > > + json_decref(object); > > > > + return NULL; > > > > +} > > > > + > > > > +static json_t *parse_array(lex_t *lex, size_t flags, json_error_t= *error) > { > > > > + json_t *array =3D json_array(); > > > > + if (!array) > > > > + return NULL; > > > > + > > > > + lex_scan(lex, error); > > > > + if (lex->token =3D=3D ']') > > > > + return array; > > > > + > > > > + while (lex->token) { > > > > + json_t *elem =3D parse_value(lex, flags, error); > > > > + if (!elem) > > > > + goto error; > > > > + > > > > + if (json_array_append_new(array, elem)) { > > > > + goto error; > > > > + } > > > > + > > > > + lex_scan(lex, error); > > > > + if (lex->token !=3D ',') > > > > + break; > > > > + > > > > + lex_scan(lex, error); > > > > + } > > > > + > > > > + if (lex->token !=3D ']') { > > > > + error_set(error, lex, json_error_invalid_syntax, "']' exp= ected"); > > > > + goto error; > > > > + } > > > > + > > > > + return array; > > > > + > > > > +error: > > > > + json_decref(array); > > > > + return NULL; > > > > +} > > > > + > > > > +static json_t *parse_value(lex_t *lex, size_t flags, json_error_t= *error) > { > > > > + json_t *json; > > > > + > > > > + lex->depth++; > > > > + if (lex->depth > JSON_PARSER_MAX_DEPTH) { > > > > + error_set(error, lex, json_error_stack_overflow, "maximum > > > > + parsing > > > depth reached"); > > > > + return NULL; > > > > + } > > > > + > > > > + switch (lex->token) { > > > > + case TOKEN_STRING: { > > > > + const char *value =3D lex->value.string.val; > > > > + size_t len =3D lex->value.string.len; > > > > + > > > > + if (!(flags & JSON_ALLOW_NUL)) { > > > > + if (memchr(value, '\0', len)) { > > > > + error_set(error, lex, json_error_null_charact= er, > > > > + "\\u0000 is not allowed without JSO= N_ALLOW_NUL"); > > > > + return NULL; > > > > + } > > > > + } > > > > + > > > > + json =3D jsonp_stringn_nocheck_own(value, len); > > > > + lex->value.string.val =3D NULL; > > > > + lex->value.string.len =3D 0; > > > > + break; > > > > + } > > > > + > > > > + case TOKEN_INTEGER: { > > > > + json =3D json_integer(lex->value.integer); > > > > + break; > > > > + } > > > > + > > > > + case TOKEN_REAL: { > > > > + json =3D json_real(lex->value.real); > > > > + break; > > > > + } > > > > + > > > > + case TOKEN_TRUE: > > > > + json =3D json_true(); > > > > + break; > > > > + > > > > + case TOKEN_FALSE: > > > > + json =3D json_false(); > > > > + break; > > > > + > > > > + case TOKEN_NULL: > > > > + json =3D json_null(); > > > > + break; > > > > + > > > > + case '{': > > > > + json =3D parse_object(lex, flags, error); > > > > + break; > > > > + > > > > + case '[': > > > > + json =3D parse_array(lex, flags, error); > > > > + break; > > > > + > > > > + case TOKEN_INVALID: > > > > + error_set(error, lex, json_error_invalid_syntax, "inv= alid token"); > > > > + return NULL; > > > > + > > > > + default: > > > > + error_set(error, lex, json_error_invalid_syntax, > > > > + "unexpected > > > token"); > > > > + return NULL; > > > > + } > > > > + > > > > + if (!json) > > > > + return NULL; > > > > + > > > > + lex->depth--; > > > > + return json; > > > > +} > > > > + > > > > +static json_t *parse_json(lex_t *lex, size_t flags, json_error_t = *error) > { > > > > + json_t *result; > > > > + > > > > + lex->depth =3D 0; > > > > + > > > > + lex_scan(lex, error); > > > > + if (!(flags & JSON_DECODE_ANY)) { > > > > + if (lex->token !=3D '[' && lex->token !=3D '{') { > > > > + error_set(error, lex, json_error_invalid_syntax, "'['= or '{' > expected"); > > > > + return NULL; > > > > + } > > > > + } > > > > + > > > > + result =3D parse_value(lex, flags, error); > > > > + if (!result) > > > > + return NULL; > > > > + > > > > + if (!(flags & JSON_DISABLE_EOF_CHECK)) { > > > > + lex_scan(lex, error); > > > > + if (lex->token !=3D TOKEN_EOF) { > > > > + error_set(error, lex, json_error_end_of_input_expecte= d, > > > > + "end of file expected"); > > > > + json_decref(result); > > > > + return NULL; > > > > + } > > > > + } > > > > + > > > > + if (error) { > > > > + /* Save the position even though there was no error */ > > > > + error->position =3D (int)lex->stream.position; > > > > + } > > > > + > > > > + return result; > > > > +} > > > > + > > > > +typedef struct { > > > > + const char *data; > > > > + size_t pos; > > > > +} string_data_t; > > > > + > > > > +static int string_get(void *data) { > > > > + char c; > > > > + string_data_t *stream =3D (string_data_t *)data; > > > > + c =3D stream->data[stream->pos]; > > > > + if (c =3D=3D '\0') > > > > + return EOF; > > > > + else { > > > > + stream->pos++; > > > > + return (unsigned char)c; > > > > + } > > > > +} > > > > + > > > > +json_t *json_loads(const char *string, size_t flags, json_error_t= *error) > { > > > > + lex_t lex; > > > > + json_t *result; > > > > + string_data_t stream_data; > > > > + > > > > + jsonp_error_init(error, ""); > > > > + > > > > + if (string =3D=3D NULL) { > > > > + error_set(error, NULL, json_error_invalid_argument, > > > > + "wrong > > > arguments"); > > > > + return NULL; > > > > + } > > > > + > > > > + stream_data.data =3D string; > > > > + stream_data.pos =3D 0; > > > > + > > > > + if (lex_init(&lex, string_get, flags, (void *)&stream_data)) > > > > + return NULL; > > > > + > > > > + result =3D parse_json(&lex, flags, error); > > > > + > > > > + lex_close(&lex); > > > > + return result; > > > > +} > > > > + > > > > +typedef struct { > > > > + const char *data; > > > > + size_t len; > > > > + size_t pos; > > > > +} buffer_data_t; > > > > + > > > > +static int buffer_get(void *data) { > > > > + char c; > > > > + buffer_data_t *stream =3D data; > > > > + if (stream->pos >=3D stream->len) > > > > + return EOF; > > > > + > > > > + c =3D stream->data[stream->pos]; > > > > + stream->pos++; > > > > + return (unsigned char)c; > > > > +} > > > > + > > > > +json_t *json_loadb(const char *buffer, size_t buflen, size_t > > > > +flags, > > > json_error_t *error) { > > > > + lex_t lex; > > > > + json_t *result; > > > > + buffer_data_t stream_data; > > > > + > > > > + jsonp_error_init(error, ""); > > > > + > > > > + if (buffer =3D=3D NULL) { > > > > + error_set(error, NULL, json_error_invalid_argument, > > > > + "wrong > > > arguments"); > > > > + return NULL; > > > > + } > > > > + > > > > + stream_data.data =3D buffer; > > > > + stream_data.pos =3D 0; > > > > + stream_data.len =3D buflen; > > > > + > > > > + if (lex_init(&lex, buffer_get, flags, (void *)&stream_data)) > > > > + return NULL; > > > > + > > > > + result =3D parse_json(&lex, flags, error); > > > > + > > > > + lex_close(&lex); > > > > + return result; > > > > +} > > > > + > > > > +json_t *json_loadf(FILE *input, size_t flags, json_error_t *error= ) { > > > > + lex_t lex; > > > > + const char *source; > > > > + json_t *result; > > > > +#ifdef HAVE_UNISTD_H > > > > + if (input =3D=3D stdin) > > > > + source =3D ""; > > > > + else > > > > +#endif > > > > + source =3D ""; > > > > + > > > > + jsonp_error_init(error, source); > > > > + > > > > + if (input =3D=3D NULL) { > > > > + error_set(error, NULL, json_error_invalid_argument, > > > > + "wrong > > > arguments"); > > > > + return NULL; > > > > + } > > > > + > > > > + if (lex_init(&lex, (get_func)fgetc, flags, input)) > > > > + return NULL; > > > > + > > > > + result =3D parse_json(&lex, flags, error); > > > > + > > > > + lex_close(&lex); > > > > + return result; > > > > +} > > > > + > > > > +static int fd_get_func(int *fd) { #ifdef HAVE_UNISTD_H > > > > + uint8_t c; > > > > + if (read(*fd, &c, 1) =3D=3D 1) > > > > + return c; > > > > +#endif > > > > + return EOF; > > > > +} > > > > + > > > > +json_t *json_loadfd(int input, size_t flags, json_error_t *error)= { > > > > + lex_t lex; > > > > + const char *source; > > > > + json_t *result; > > > > + > > > > +#ifdef HAVE_UNISTD_H > > > > + if (input =3D=3D STDIN_FILENO) > > > > + source =3D ""; > > > > + else > > > > +#endif > > > > + source =3D ""; > > > > + > > > > + jsonp_error_init(error, source); > > > > + > > > > + if (input < 0) { > > > > + error_set(error, NULL, json_error_invalid_argument, > > > > + "wrong > > > arguments"); > > > > + return NULL; > > > > + } > > > > + > > > > + if (lex_init(&lex, (get_func)fd_get_func, flags, &input)) > > > > + return NULL; > > > > + > > > > + result =3D parse_json(&lex, flags, error); > > > > + > > > > + lex_close(&lex); > > > > + return result; > > > > +} > > > > + > > > > +json_t *json_load_file(const char *path, size_t flags, > > > > +json_error_t *error) > > > { > > > > + json_t *result; > > > > + FILE *fp; > > > > + > > > > + jsonp_error_init(error, path); > > > > + > > > > + if (path =3D=3D NULL) { > > > > + error_set(error, NULL, json_error_invalid_argument, > > > > + "wrong > > > arguments"); > > > > + return NULL; > > > > + } > > > > + > > > > + fp =3D fopen(path, "rb"); > > > > + if (!fp) { > > > > + error_set(error, NULL, json_error_cannot_open_file, > > > > + "unable to > > > open %s: %s", path, > > > > + strerror(errno)); > > > > + return NULL; > > > > + } > > > > + > > > > + result =3D json_loadf(fp, flags, error); > > > > + > > > > + fclose(fp); > > > > + return result; > > > > +} > > > > + > > > > +#define MAX_BUF_LEN 1024 > > > > + > > > > +typedef struct { > > > > + char data[MAX_BUF_LEN]; > > > > + size_t len; > > > > + size_t pos; > > > > + json_load_callback_t callback; > > > > + void *arg; > > > > +} callback_data_t; > > > > + > > > > +static int callback_get(void *data) { > > > > + char c; > > > > + callback_data_t *stream =3D data; > > > > + > > > > + if (stream->pos >=3D stream->len) { > > > > + stream->pos =3D 0; > > > > + stream->len =3D stream->callback(stream->data, MAX_BUF_LE= N, > > > stream->arg); > > > > + if (stream->len =3D=3D 0 || stream->len =3D=3D (size_t)-1= ) > > > > + return EOF; > > > > + } > > > > + > > > > + c =3D stream->data[stream->pos]; > > > > + stream->pos++; > > > > + return (unsigned char)c; > > > > +} > > > > + > > > > +json_t *json_load_callback(json_load_callback_t callback, void > > > > +*arg, > > > size_t flags, > > > > + json_error_t *error) { > > > > + lex_t lex; > > > > + json_t *result; > > > > + > > > > + callback_data_t stream_data; > > > > + > > > > + memset(&stream_data, 0, sizeof(stream_data)); > > > > + stream_data.callback =3D callback; > > > > + stream_data.arg =3D arg; > > > > + > > > > + jsonp_error_init(error, ""); > > > > + > > > > + if (callback =3D=3D NULL) { > > > > + error_set(error, NULL, json_error_invalid_argument, > > > > + "wrong > > > arguments"); > > > > + return NULL; > > > > + } > > > > + > > > > + if (lex_init(&lex, (get_func)callback_get, flags, &stream_dat= a)) > > > > + return NULL; > > > > + > > > > + result =3D parse_json(&lex, flags, error); > > > > + > > > > + lex_close(&lex); > > > > + return result; > > > > +} > > > > diff --git a/RedfishPkg/RedfishPkg.ci.yaml > > > > b/RedfishPkg/RedfishPkg.ci.yaml index 9895fdac99..2a26769536 > > > > 100644 > > > > --- a/RedfishPkg/RedfishPkg.ci.yaml > > > > +++ b/RedfishPkg/RedfishPkg.ci.yaml > > > > @@ -35,7 +35,13 @@ > > > > "Include/Crt/string.h", > > > > "Include/Crt/time.h", > > > > "Include/Library/CrtLib.h", > > > > - "Library/CrtLib/CrtLib.c" > > > > + "Library/CrtLib/CrtLib.c", > > > > + ## > > > > + ## For jansson library open source > > > > + ## load.c is overrided from open source. > > > > + "Library/JsonLib/load.c", > > > > + "Library/JsonLib/jansson_config.h", > > > > + "Library/JsonLib/jansson_private_config.h" > > > > ] > > > > }, > > > > "CompilerPlugin": { > > > > diff --git a/RedfishPkg/RedfishPkg.dec b/RedfishPkg/RedfishPkg.dec > > > > index 9a9a1190fb..6499d77f3e 100644 > > > > --- a/RedfishPkg/RedfishPkg.dec > > > > +++ b/RedfishPkg/RedfishPkg.dec > > > > @@ -18,6 +18,12 @@ > > > > > > > > [Includes.Common.Private] > > > > Include/Crt # Header files for C RTL. > > > > + Library/JsonLib # Header files for jansson config= uration files. > > > > + # - jansson_config.h > > > > + # - jansson_private_config.h > > > > + # jansson.h refers to above two c= onfiguration > > > > + # files for building platform jan= sson library. > > > > + Library/JsonLib/jansson/src # For referring to jannson.h > > > > > > > > [LibraryClasses] > > > > ## @libraryclass Platform Redfish Host Interface Library @@ > > > > -39,6 > > > > +45,11 @@ > > > > # project). > > > > CrtLib|Include/Library/CrtLib.h > > > > > > > > + ## @libraryclass Provides the library functions based on > > > > + third party # jansson library to manipulate JSON data structur= e. > > > > + # > > > > + JsonLib|Include/Library/JsonLib.h > > > > + > > > > [Protocols] > > > > ## Include/Protocol/RedfishDiscover.h > > > > gEfiRedfishDiscoverProtocolGuid =3D { 0x5db12509, 0x4550, = 0x4347, > { 0x96, > > > 0xb3, 0x73, 0xc0, 0xff, 0x6e, 0x86, 0x9f }} > > > > -- > > > > 2.17.1 > > > > > > > > > > > > > > > > > > >=20 >=20 >=20 >=20