From patchwork Fri Jun 17 09:46:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: fengchengwen X-Patchwork-Id: 112993 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id B5409A0093; Fri, 17 Jun 2022 11:53:12 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 0AC6142847; Fri, 17 Jun 2022 11:52:59 +0200 (CEST) Received: from szxga08-in.huawei.com (szxga08-in.huawei.com [45.249.212.255]) by mails.dpdk.org (Postfix) with ESMTP id 208FA410FC for ; Fri, 17 Jun 2022 11:52:53 +0200 (CEST) Received: from dggpeml500024.china.huawei.com (unknown [172.30.72.55]) by szxga08-in.huawei.com (SkyGuard) with ESMTP id 4LPZ6f5KC7z1K9rM; Fri, 17 Jun 2022 17:50:50 +0800 (CST) Received: from localhost.localdomain (10.67.165.24) by dggpeml500024.china.huawei.com (7.185.36.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.24; Fri, 17 Jun 2022 17:52:51 +0800 From: Chengwen Feng To: , , , , , , , , CC: Subject: [PATCH v2 1/5] telemetry: escape special char when tel string Date: Fri, 17 Jun 2022 17:46:20 +0800 Message-ID: <20220617094624.17578-2-fengchengwen@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20220617094624.17578-1-fengchengwen@huawei.com> References: <20220615073915.14041-1-fengchengwen@huawei.com> <20220617094624.17578-1-fengchengwen@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.67.165.24] X-ClientProxiedBy: dggems702-chm.china.huawei.com (10.3.19.179) To dggpeml500024.china.huawei.com (7.185.36.10) X-CFilter-Loop: Reflected X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org This patch supports escape special characters (including: \",\\,/,\b, /f,/n,/r,/t) when telemetry string. This patch is used to support telemetry xxx-dump commands which the string may include special characters. Signed-off-by: Chengwen Feng Reviewed-by: Morten Brørup --- lib/telemetry/telemetry.c | 96 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 3 deletions(-) diff --git a/lib/telemetry/telemetry.c b/lib/telemetry/telemetry.c index c6fd03a5ab..0f762f633e 100644 --- a/lib/telemetry/telemetry.c +++ b/lib/telemetry/telemetry.c @@ -215,6 +215,94 @@ container_to_json(const struct rte_tel_data *d, char *out_buf, size_t buf_len) return used; } +static bool +json_is_special_char(char ch) +{ + static unsigned char is_spec[256] = { 0 }; + static bool init_once; + + if (!init_once) { + is_spec['\"'] = 1; + is_spec['\\'] = 1; + is_spec['/'] = 1; + is_spec['\b'] = 1; + is_spec['\f'] = 1; + is_spec['\n'] = 1; + is_spec['\r'] = 1; + is_spec['\t'] = 1; + init_once = true; + } + + return (bool)is_spec[(unsigned char)ch]; +} + +static size_t +json_escape_special_char(char *buf, const char ch) +{ + size_t used = 0; + + switch (ch) { + case '\"': + buf[used++] = '\\'; + buf[used++] = '\"'; + break; + case '\\': + buf[used++] = '\\'; + buf[used++] = '\\'; + break; + case '/': + buf[used++] = '\\'; + buf[used++] = '/'; + break; + case '\b': + buf[used++] = '\\'; + buf[used++] = 'b'; + break; + case '\f': + buf[used++] = '\\'; + buf[used++] = 'f'; + break; + case '\n': + buf[used++] = '\\'; + buf[used++] = 'n'; + break; + case '\r': + buf[used++] = '\\'; + buf[used++] = 'r'; + break; + case '\t': + buf[used++] = '\\'; + buf[used++] = 't'; + break; + default: + break; + } + + return used; +} + +static size_t +json_format_string(char *buf, size_t len, const char *str) +{ + size_t used = 0; + + while (*str) { + if (unlikely(len < used + 2)) { + TMTY_LOG(WARNING, "Insufficient buffer when json format string\n"); + break; + } + + if (json_is_special_char(*str)) + used += json_escape_special_char(buf + used, *str); + else + buf[used++] = *str; + + str++; + } + + return used; +} + static void output_json(const char *cmd, const struct rte_tel_data *d, int s) { @@ -232,9 +320,11 @@ output_json(const char *cmd, const struct rte_tel_data *d, int s) MAX_CMD_LEN, cmd ? cmd : "none"); break; case RTE_TEL_STRING: - used = snprintf(out_buf, sizeof(out_buf), "{\"%.*s\":\"%.*s\"}", - MAX_CMD_LEN, cmd, - RTE_TEL_MAX_SINGLE_STRING_LEN, d->data.str); + used = snprintf(out_buf, sizeof(out_buf), "{\"%.*s\":\"", + MAX_CMD_LEN, cmd); + used += json_format_string(out_buf + used, + sizeof(out_buf) - used - 3, d->data.str); + used += snprintf(out_buf + used, sizeof(out_buf) - used, "\"}"); break; case RTE_TEL_DICT: prefix_used = snprintf(out_buf, sizeof(out_buf), "{\"%.*s\":",