From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm1-x334.google.com (mail-wm1-x334.google.com [IPv6:2a00:1450:4864:20::334]) by sourceware.org (Postfix) with ESMTPS id C3608385840A for ; Wed, 28 Dec 2022 23:18:12 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org C3608385840A Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-wm1-x334.google.com with SMTP id i17-20020a05600c355100b003d99434b1cfso1966644wmq.1 for ; Wed, 28 Dec 2022 15:18:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=K8hzbh+cDnNzEDI6/zdf0g7DmHNEQmK9sguAkmhCpmA=; b=hE4prtqxJp0+2VopRWQF8SWHmCcqdrEuizu5xdwlvE0bIEpvqNgxlf/N48fymYjbVi gauvlQQR39vum4WJDDto7l2H+OXY2UzyozttanFFwgET5a0j2kyIMRb5blZ2AbkKVIRk u+IvuWRnpAgzyaziJI4GP5ESjrKvHW0sWdDW2jET/cCEQnoLGGxqOAy6W+lddUaVn2+M 7ehQY9J8HPFw0udYdw1U8KcG+VQpHpF7pzjzutgWWnbTApD10xZDRXPn5RkthNazCdjY CTA6L3PlXjAhHiSZIuOG351zgdMD2OWTleXHaS1Ur0lE/RZHxX/QbHrcRr2+cYSsx5C4 3u+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=K8hzbh+cDnNzEDI6/zdf0g7DmHNEQmK9sguAkmhCpmA=; b=VgJnJNkYYxkKt3xaGY8v4mB4KemPRjw7jVeSYvDGtTdd0o+qTHopUvPIeydSTlJMro jyCCiWbwHt0U+YNPe5fFh9nP6QvO9rXMdEMTvHzRx4Um0QPaoFnie06CPQlehalbn48z lU5STwkG0+3/7W6eHSsMZFgElftgUg00KYpNiIhN9yhGqofFQGUfb3O+/A/MCgQA1akj QqSF+pitGwj480Nw20WC9lExMSbOqfj2xh8UShKCcPGDWhKnuqgkQsSVdz8XSyVaoOOg 20eQivTUkePix4obAGq3mlCophf2CzLbd0qApJEsXGmJVR6FJkpTYpfXDOeu+iuy/hie u2+A== X-Gm-Message-State: AFqh2kpxz1KELeKxOH9qGgeRxA+Z7gMfVojPZfJcl2E4wA7AHKDRRYVz nqROgQjGEda6LLY5c0hpLSsOGPNVVB8= X-Google-Smtp-Source: AMrXdXt6/FpQbxU1x48I87BiYkOLZ+ExdOu599WghY7rvEHfw2s5Ymeqr/ZLc2nj7gMaEOr1voTImg== X-Received: by 2002:a05:600c:4255:b0:3d3:3d34:5d63 with SMTP id r21-20020a05600c425500b003d33d345d63mr19256505wmm.8.1672269491659; Wed, 28 Dec 2022 15:18:11 -0800 (PST) Received: from asus5775.alejandro-colomar.es ([170.253.36.171]) by smtp.googlemail.com with ESMTPSA id l27-20020a05600c1d1b00b003cfd4e6400csm24357367wms.19.2022.12.28.15.18.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 28 Dec 2022 15:18:11 -0800 (PST) From: Alejandro Colomar X-Google-Original-From: Alejandro Colomar To: libc-alpha@sourceware.org Cc: Alejandro Colomar Subject: [PATCH v2 2/3] stdio: Add vstpeprintf() Date: Thu, 29 Dec 2022 00:17:41 +0100 Message-Id: <20221228231741.125945-3-alx@kernel.org> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20221222214217.1619716-1-alx@kernel.org> References: <20221222214217.1619716-1-alx@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4288; i=alx@kernel.org; h=from:subject; bh=1AmAQxPfsfy0iDyVR3Xerp/tpdqPWSyXKi3+nlkN/Ps=; b=owEBbQKS/ZANAwAKAZ6MGvu+/9syAcsmYgBjrM6NZg1SRTiuY9slvWzfSyKAUbdYm+bMn9NEEENz f2Bmq0CJAjMEAAEKAB0WIQTqOofwpOugMORd8kCejBr7vv/bMgUCY6zOjQAKCRCejBr7vv/bMqdgD/ 4vwhdjrIy7iWcrMPNeM7X60gK7DrYV7XMg5se5McNb4nZ+KTpWKssOkrdFhZ9F8mc8ammSz4jc9XXS J8PWQe1sHoAv8UKSZ7W48SiPhq5AFhHD1Nz0k1l9icgjh9jgvhISMR1fA/oBugyGVfGM4UHCLk5For kXWHW+nUpPGapXRhLUIQ/WV1etpSg+ORwaxJvIMktEwErmBRBkvW41LgModn8Z7J7GqznZ9z0ctnrX +4MzCvBlMr/e82NiflcvgmAMLbLFKMWVSO0X2RuX+yJrpj346EQSDyUr5x0Lmgry3w82e3E0ZBL8Si TGv5zK2nwtYXznutPSxz3VlqosIKq7kmJUgkq175J/n0MRlTeUmnEuWc8ssLRRo4pzCqg8aW6lc2En BZ/jjDT5hw5c+vu5xM1fuD5AFe+Sn3GPL+oZFfSwrIC9/wqTcYRHyedtr0ebFpPtLFqUObX1LveheH RKW1kpx24Jx3p7kEYBgtYPFGpjD3WuYkrcrXEBx9sE1MdDHDXzHf4GHiMUBvs7EtxNtBx5WKUEUEet B5y9s1RMFW/twWhCdalTZwKEll4dY2d153kQ0iNL+dttiImjGl7eEOfXy8y8DHzGFbmz3Mzs+9v3Aj BhAI9roUi9kZW15Xj3Bt9N0+9vRw2YPz9lQDMp3ZiKQDYj0LzMywB1Eca65g== X-Developer-Key: i=alx@kernel.org; a=openpgp; fpr=A9348594CE31283A826FBDD8D57633D441E25BB5 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-10.6 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,GIT_PATCH_0,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: [v]snprintf(3) is error-prone, since it doesn't allow easy catenation or chaining. To catenate a formatted string after an existing string, the only possibility was to call [v]snprintf(3), adjusting the sizes and pointers. However, that is very error-prone, and has caused several bugs in existing software. I found several just in a small investigation in some noteworthy open-source projects. This API solves that problem by receiving a pointer to the end of the destination buffer, so there's no recalculation involved. It also always returns a pointer suitable for chaining with other calls to this function, or calls to stpecpy(3). Signed-off-by: Alejandro Colomar --- libio/Makefile | 4 ++-- libio/stdio.h | 6 ++++++ libio/vstpeprintf.c | 52 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 libio/vstpeprintf.c diff --git a/libio/Makefile b/libio/Makefile index 64398ab1ee..1924f7a65c 100644 --- a/libio/Makefile +++ b/libio/Makefile @@ -43,8 +43,8 @@ routines := \ \ clearerr feof ferror fileno fputc freopen fseek getc getchar \ memstream pclose putc putchar rewind setbuf setlinebuf vasprintf \ - iovdprintf vscanf vsnprintf obprintf fcloseall fseeko ftello \ - freopen64 fseeko64 ftello64 \ + iovdprintf vscanf vsnprintf vstpeprintf obprintf fcloseall \ + fseeko ftello freopen64 fseeko64 ftello64 \ \ __fbufsize __freading __fwriting __freadable __fwritable __flbf \ __fpurge __fpending __fsetlocking \ diff --git a/libio/stdio.h b/libio/stdio.h index 0e0f16b464..59b8047ecc 100644 --- a/libio/stdio.h +++ b/libio/stdio.h @@ -384,6 +384,12 @@ extern int vsnprintf (char *__restrict __s, size_t __maxlen, __THROWNL __attribute__ ((__format__ (__printf__, 3, 0))); #endif +#if __USE_GNU +extern char *vstpeprintf (char *__dest, char *__end, + const char *__restrict __fmt, __gnuc_va_list __arg) + __THROWNL __attribute__ ((__format__ (__printf__, 3, 0))); +#endif + #if __GLIBC_USE (LIB_EXT2) /* Write formatted output to a string dynamically allocated with `malloc'. Store the address of the string in *PTR. */ diff --git a/libio/vstpeprintf.c b/libio/vstpeprintf.c new file mode 100644 index 0000000000..a8becdc682 --- /dev/null +++ b/libio/vstpeprintf.c @@ -0,0 +1,52 @@ +/* Copyright (C) 2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include +#include + + +char * +vstpeprintf(char *dst, char *end, const char *restrict fmt, va_list ap) +{ + int dsize, len; + + if (dst == end) + return end; + if (dst == NULL) + return NULL; + if (dst > end) + __builtin_unreachable(); + + dsize = end - dst; + len = __vsnprintf_internal(dst, dsize, fmt, ap, 0); + + if (len == -1) + return NULL; + if (len >= dsize) + return end; + + return dst + len; +} -- 2.39.0