From patchwork Tue Aug 4 01:06:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Golle X-Patchwork-Id: 1340626 X-Patchwork-Delegate: daniel@makrotopia.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.openwrt.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=makrotopia.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=merlin.20170209 header.b=QJO1MZ3R; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BLGqZ1zWwz9sR4 for ; Tue, 4 Aug 2020 11:09:13 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:Message-ID:Subject:To:From:Date: Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender :Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Owner; bh=7SKTnVdff6ivF0N8HJEw9Lu8vlavOCfVrvHKXcjl11A=; b=QJO1MZ3RDqGxNlECLPGdBsH8Z3 LBPXHwyFoJLARIcdCLTcVKLHcoGWFs58kewVFmalxx3G/DAoZ9Oo21dXFtO/vFOILu/MbVfp/tVg6 yjPx7/VdVR7AGLWVp2Te6NBmuHxw/SpDo+CITLqHJgUimFOf3/rLZ5shOVhJ01Q81kg0yWDI8/ZOI CrUx8rnDnfBwtgK7T0qM6ko0HuP9jkYT5y9w2ATdVGgV9jtF4/nXinbh1dmbrV5t7v1r8pa/2jiXz ydpN7NST/ubK1JfILz5QbLYO0vfy9rXO3j4IscBIef2EDovdqzrN0+8s2GEk3mIX1ZNKSQM0Xx238 fZcIe83A==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1k2lPp-0000J6-3y; Tue, 04 Aug 2020 01:06:53 +0000 Received: from fudo.makrotopia.org ([2a07:2ec0:3002::71]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1k2lPm-0000Ic-LG for openwrt-devel@lists.openwrt.org; Tue, 04 Aug 2020 01:06:51 +0000 Received: from local by fudo.makrotopia.org with esmtpsa (TLS1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.93.0.4) (envelope-from ) id 1k2lPh-0003AN-P8; Tue, 04 Aug 2020 03:06:47 +0200 Date: Tue, 4 Aug 2020 02:06:30 +0100 From: Daniel Golle To: openwrt-devel@lists.openwrt.org Subject: [PATCH/RFC 1/2] libubox: blobmsg: introduce BLOBMSG_CAST_INT64 Message-ID: <20200804010630.GA161246@makrotopia.org> MIME-Version: 1.0 Content-Disposition: inline X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200803_210650_699384_B50D31DC X-CRM114-Status: GOOD ( 14.84 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: OpenWrt Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: John Crispin , Felix Fietkau Sender: "openwrt-devel" Errors-To: openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org When dealing with 64-bit integers in JSON documents, blobmsg_parse becomes useless as blobmsg-json only uses BLOBMSG_TYPE_INT64 if the value exceeds the range of a 32-bit integer, otherwise BLOBMSG_TYPE_INT32 is used. This is because blobmsg-json parses the JSON document ad-hoc without knowing the schema in advance and hence a result of the design of blobmsg-json (and the absence of JSON schema definitions). In practise, this made code less readable as instead of using blobmsg_parse() one had to to deal with *all* attributes manually just to catch fields which can be both, BLOBMSG_TYPE_INT32 or BLOBMSG_TYPE_INT64, but are always dealt with as uint64_t in code as they potentially could exceed the 32-bit range. To resolve this issue, introduce as special wildcard attribute type BLOBMSG_CAST_INT64 which should only be used in policies used by blobmsg_parse(). If used for an attribute in the policy, blobmsg_parse shall accept all integer types and allow the user to retrieve the value using the blobmsg_cast_u64() function which is also introduced by this commit. Signed-off-by: Daniel Golle --- blobmsg.c | 8 ++++++++ blobmsg.h | 17 +++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/blobmsg.c b/blobmsg.c index 7da4183..93172ab 100644 --- a/blobmsg.c +++ b/blobmsg.c @@ -195,9 +195,17 @@ int blobmsg_parse(const struct blobmsg_policy *policy, int policy_len, continue; if (policy[i].type != BLOBMSG_TYPE_UNSPEC && + policy[i].type != BLOBMSG_CAST_INT64 && blob_id(attr) != policy[i].type) continue; + if (policy[i].type == BLOBMSG_CAST_INT64 && + (blob_id(attr) != BLOBMSG_TYPE_INT64 && + blob_id(attr) != BLOBMSG_TYPE_INT32 && + blob_id(attr) != BLOBMSG_TYPE_INT16 && + blob_id(attr) != BLOBMSG_TYPE_INT8)) + continue; + if (blobmsg_namelen(hdr) != pslen[i]) continue; diff --git a/blobmsg.h b/blobmsg.h index 4565082..afb5a36 100644 --- a/blobmsg.h +++ b/blobmsg.h @@ -35,6 +35,7 @@ enum blobmsg_type { __BLOBMSG_TYPE_LAST, BLOBMSG_TYPE_LAST = __BLOBMSG_TYPE_LAST - 1, BLOBMSG_TYPE_BOOL = BLOBMSG_TYPE_INT8, + BLOBMSG_CAST_INT64, }; struct blobmsg_hdr { @@ -288,6 +289,22 @@ static inline uint64_t blobmsg_get_u64(struct blob_attr *attr) return tmp; } +static inline uint64_t blobmsg_cast_u64(struct blob_attr *attr) +{ + uint64_t tmp = 0; + + if (blobmsg_type(attr) == BLOBMSG_TYPE_INT64) + tmp = blobmsg_get_u64(attr); + else if (blobmsg_type(attr) == BLOBMSG_TYPE_INT32) + tmp = blobmsg_get_u32(attr); + else if (blobmsg_type(attr) == BLOBMSG_TYPE_INT16) + tmp = blobmsg_get_u16(attr); + else if (blobmsg_type(attr) == BLOBMSG_TYPE_INT8) + tmp = blobmsg_get_u8(attr); + + return tmp; +} + static inline double blobmsg_get_double(struct blob_attr *attr) { union {