From patchwork Thu Dec 22 21:42:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alejandro Colomar X-Patchwork-Id: 62295 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 29DBB385B52C for ; Thu, 22 Dec 2022 21:45:22 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 29DBB385B52C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1671745522; bh=Fq0BwIlQYMS7VUMF+5mYrroz/YQemrjXoNsWBi7kVGk=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=K1JmIpGXc2mYOinBVpssELLKOz1/xV3vCzhICe5DheuvZcbFY+QJurd7qKyijyk+t DM4/WTN16ho6PLIgvYITXvY2JV0bydEgL26b3QgNBbaw7jVTdDUTWobrpNXiOPTM/z UbRt8+n/7uYy3DzS0LsnwmUoykZGUKWZ/XdeSJ9E= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-wr1-x42c.google.com (mail-wr1-x42c.google.com [IPv6:2a00:1450:4864:20::42c]) by sourceware.org (Postfix) with ESMTPS id 429EC3850F0F for ; Thu, 22 Dec 2022 21:45:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 429EC3850F0F Received: by mail-wr1-x42c.google.com with SMTP id co23so2948847wrb.4 for ; Thu, 22 Dec 2022 13:45:00 -0800 (PST) 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=Fq0BwIlQYMS7VUMF+5mYrroz/YQemrjXoNsWBi7kVGk=; b=wSYS1s1INgjwcxf27hlfMZfZdX9HEP5d7/qjU/IbM/RrQGWq4zTKv7boyXvaf9ep5V fihip/+CRKsZaWQlEmXBmBjOmeL6CNzu9TFS+vztJhozXzSBbCzejiEBEPugnt8GwKUS zeWjt3oZQY0COKwX/GsvH4slh0zB4NLiPpcvcmvJTPw6mmmB/vMFnJNQLg4RjxMG27cM 9vVpCZItSG2L80A43iscLX1Mn3KblknT7xKDEIgsZz0AfOD+PsQmcT9HhoQFrxb/PAG8 J6t+wNRoQVVcmUy7Z5pj+fBKWB+++HtvQ/glxZW2FMZ8H9CdOdM3kJsg4jYRyxq0rB8p TETA== X-Gm-Message-State: AFqh2koql5ltGIbTV+R6Qqyp42iISSxneDF63nHG940da0fF4gw1Add8 XtwngO5deTYMTgO3diN9ijCmczW6EsA= X-Google-Smtp-Source: AMrXdXth0e2fQect3acFnV6G6a+021QpryYNx11rvlFQs22yGxwZjLtLaHioUCm8Z11AyiS7r5l9oA== X-Received: by 2002:adf:f183:0:b0:255:96ed:950b with SMTP id h3-20020adff183000000b0025596ed950bmr4593525wro.60.1671745499007; Thu, 22 Dec 2022 13:44:59 -0800 (PST) Received: from asus5775.alejandro-colomar.es ([170.253.36.171]) by smtp.googlemail.com with ESMTPSA id j10-20020adff54a000000b002420d51e581sm1501295wrp.67.2022.12.22.13.44.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Dec 2022 13:44:58 -0800 (PST) X-Google-Original-From: Alejandro Colomar To: libc-alpha@sourceware.org Cc: Alejandro Colomar Subject: [PATCH 1/1] string: Add stpecpy(3) Date: Thu, 22 Dec 2022 22:42:19 +0100 Message-Id: <20221222214217.1619716-2-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=3557; i=alx@kernel.org; h=from:subject; bh=ahNVoJaC8IUoB680e8FoI515BLCH3j7FAfax6MfDNwU=; b=owEBbQKS/ZANAwAKAZ6MGvu+/9syAcsmYgBjpM84fdt5o5CH8KWh7kxG/14aa3uwSgc8XBOZel7P m2o2CiuJAjMEAAEKAB0WIQTqOofwpOugMORd8kCejBr7vv/bMgUCY6TPOAAKCRCejBr7vv/bMtW8D/ 9reJF4pBhkBWaSZbsowQ7lINsjfdK/QWDkVquSLlQPixD5bZ6nWCFGpVOVs3UZaR2+uLXldasJWhtH BgSUg4iAQQRVqfB5iuIVEId3PvXVOTWoOEUU2HXm+IfGZGmkOkL6uuy/JX8LrrohizdtJ8D6wvCS6Q btuOST7a1kyPg/GgSQC4Wciecxgsu/9T9hcFCSqD2VNPNhI198vdA4zUFvw1PwZDjISNBa/G7GLEwi sEujrEeU1Phvf2MylxoNRx8FFjxT/x1oVUJojz3EekpJ0gGVa7/eR2LTO7j1KO8cPKCuQrqNvvq/Hu Gj2SZvUvcT4kFjWpodgeyVTkVJJulbwEqZGRL0fWV5ZyHVorO11Px2UQ+lvwzK/e1egUlY51UsK3zV E1AkdgXChqJeOuBaLUW65rRzhKfY5idhBMaFZKrRFH1wZaHDfu4GgZPd0F7lIwD1GC70z4VNR6ohcR xi9hhITKBUDUrcgK6+oTRuYL8TWwHQ8PkYx77qSp2WNCKrFUtlCO0Tqo/W6S8VEv0Wx77wrC4C+uE9 lCfUZ1sc0ui8xnwgdF2dySTIAt4shnwr5EQJjZBCAV8c379j0s8li7P9JVb31swhSC3G8h3AdRQqRb EEvsdY72qkqsqzLyeEV5KKq/3/eFuxQOEdeuGHfbkS0Z5K0MM/Wn+H3AKjxA== X-Developer-Key: i=alx@kernel.org; a=openpgp; fpr=A9348594CE31283A826FBDD8D57633D441E25BB5 X-Spam-Status: No, score=-10.7 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 X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Alejandro Colomar via Libc-alpha From: Alejandro Colomar Reply-To: Alejandro Colomar Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" Glibc didn't provide any function that copies a string with truncation. It only provided strncpy(3) and stpncpy(3), which copy from a string into a null-padded character sequence at the destination fixed-width buffer, with truncation. Those old functions, which don't produce a string, have been misused for a long time as a poor-man's replacement for strlcpy(3), but doing that is a source of bugs, since it's hard to calculate the right size that should be passed to the function, and it's also necessary to explicitly terminate the buffer with a null byte. Detecting truncation is yet another problem. stpecpy(3), described in the new string_copying(7) manual page, is similar to OpenBSD's strlcpy(3)/strlcat(3), but: - It's simpler to implement. - It's faster. - It's simpler to detect truncation. Signed-off-by: Alejandro Colomar --- Of course this is still a very early patch. I just compiled it, but we'd need to write tests for it. I didn't want to do all of that work before the discussion. Since the source code has been copied from libstp, I can at least say that the function works, since I already used that library, but this still needs a lot of work to adapt to glibc, I guess. string/Makefile | 1 + string/stpecpy.c | 39 +++++++++++++++++++++++++++++++++++++++ string/string.h | 7 +++++++ 3 files changed, 47 insertions(+) create mode 100644 string/stpecpy.c diff --git a/string/Makefile b/string/Makefile index 938f528b8d..95e9ebce6d 100644 --- a/string/Makefile +++ b/string/Makefile @@ -73,6 +73,7 @@ routines := \ sigabbrev_np \ sigdescr_np \ stpcpy \ + stpecpy \ stpncpy \ strcasecmp \ strcasecmp_l \ diff --git a/string/stpecpy.c b/string/stpecpy.c new file mode 100644 index 0000000000..e6194559ee --- /dev/null +++ b/string/stpecpy.c @@ -0,0 +1,39 @@ +/* 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 3.0 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 + . */ + +#include + +char * +stpecpy (char *dest, char *end, const char *restrict src) +{ + char *p; + + if (dest == end) + return end; + if (dest == NULL) // Allow chaining with stpeprintf(3). + return NULL; + if (dest > end) + __builtin_unreachable(); + + p = memccpy(dest, src, '\0', end - dest); + if (p != NULL) + return p - 1; + + /* Truncation detected. */ + end[-1] = '\0'; + return end; +} diff --git a/string/string.h b/string/string.h index 54dd8344de..966a8cb744 100644 --- a/string/string.h +++ b/string/string.h @@ -502,6 +502,13 @@ extern char *stpncpy (char *__restrict __dest, #endif #ifdef __USE_GNU +/* Copy the string SRC into a null-terminated string at DEST, + truncating if it would run after END. Return a pointer to + the terminating null byte, or END if the string was truncated, + or NULL if DEST was NULL. */ +extern char *stpecpy (char *__dest, char *__end, const char *__restrict __src) + __THROW __nonnull ((2, 3)); + /* Compare S1 and S2 as strings holding name & indices/version numbers. */ extern int strverscmp (const char *__s1, const char *__s2) __THROW __attribute_pure__ __nonnull ((1, 2));