From nobody Wed Jan 17 18:28:38 2024 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4TFZBt5RmZz56P99; Wed, 17 Jan 2024 18:28:38 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (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 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4TFZBt4LRlz4c5k; Wed, 17 Jan 2024 18:28:38 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1705516118; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=HebBYh6OSCqGAcrH08zYERSeSdmeLv/i7uicQbFbPUk=; b=tTVRddHRO3rgpQHRYH7L0vc/hf43e8LkL7DCGwMkbiZso09tgW8nHEFWaJSzVsZrmk0AMp zVqh0ejkL2gk7jWshIj2Fpj9Z46DixQTuqSy+izW2KJHHwyXrykgV00DOgHSeD4np+SRrr uNH4jJQL02w86M8u20pwvODcPqUMigv1Htewx3+scJfiSouLNvIM6BAarqly0M5w31sbBT 5oeNsprTazXbEhxSRgBlq40p/e3TU9MzJSV0dLiMfsVLXIEPlb/AgnlWHEt1aPSJhjUIH1 h2tLvsc01loJRory0SbgFv3/WjRZdCN0LBGO/Uwq/8mSADPBfeByLPnoBjpl9A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1705516118; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=HebBYh6OSCqGAcrH08zYERSeSdmeLv/i7uicQbFbPUk=; b=i24G+P2IkCKUDiKsLFIPEEeJWYIC1iN2dLrryBuXVLy2conABSbvDzNVAdffL0EPHCGwwH b81f7SBUbcSp0Y4Rkhd+9Pz26NQgK//jjGdm4G9aI8XEqp6sZCNCwbiX8ag4Igb9wpZHRf 209oVIbAR+QePZeLMvDVClBPxtfxgMDuP29FTTwSGRmiKiXAZGssO5wYZ/U4MfHPkU8vkJ MpyrAly1aCV/IOFsCUHkl7m8daHa8niF+tUN1YVcCoYeLmpCSMgKEYGdfOTNz7RuuzHCNA s1jy41e+ZVVxq3rNGblakfWMpQrdvMbkkxZe3y9239uSjqTJ+h92gZQ2oaydNw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1705516118; a=rsa-sha256; cv=none; b=kuuaJAnesHk2lOIpBHrbilrcSPOVukK3X5H/qISczxLus9lA9vAxwP4MDMw/vCPLLEzW3T yj0L9LPzHzNhYf5YmbEIgXhiNjfu9zERj1x78O2s6c8je5D/z5lXaI5qs0hlmZrA62XPAJ BhZYqxUQPyjoNWT6BPZqWXO2Lc88tMcYf11/pOVLC6Kz6K2ix+iiRGjJth1p9ci9DKbrd7 HOWZaAP6aJ4fu6AXtOHveXjx5z6Qe8Bb4lK/67irgunxNB/IRP71TVnesv4W+1grs6desS nyTv58tVBS4MB/+n2/hQ4LruNpAjlAmDV9k99YH5py2MF+xITOwIleBiYCXHJw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (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) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4TFZBt3MDBzZ5T; Wed, 17 Jan 2024 18:28:38 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 40HISc8S063732; Wed, 17 Jan 2024 18:28:38 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 40HIScw9063729; Wed, 17 Jan 2024 18:28:38 GMT (envelope-from git) Date: Wed, 17 Jan 2024 18:28:38 GMT Message-Id: <202401171828.40HIScw9063729@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Dag-Erling =?utf-8?Q?Sm=C3=B8rgrav?= Subject: git: ed1967df2de8 - stable/13 - asa: Rewrite to fix line termination issue. List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: des X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: ed1967df2de8887793b93b3a4a86dc108a082cd5 Auto-Submitted: auto-generated The branch stable/13 has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=ed1967df2de8887793b93b3a4a86dc108a082cd5 commit ed1967df2de8887793b93b3a4a86dc108a082cd5 Author: Dag-Erling Smørgrav AuthorDate: 2024-01-09 14:09:41 +0000 Commit: Dag-Erling Smørgrav CommitDate: 2024-01-17 16:16:00 +0000 asa: Rewrite to fix line termination issue. The standard is somewhat unclear, but on the balance, I believe that the phrase “the rest of the input line” should be interpreted to mean the rest of the input line including the terminating newline if and only if there is one. This means the current implementation is incorrect on two points: - First, it suppresses the previous line's newline in the '1' case. - Second, it unconditionally emits a newline at the end of the output for non-empty input, even if the input did not end with a newline. Resolve this by rewriting the main loop. Instead of special-casing the first line and then assuming that every line ends with a newline, we remember how each line ends and emit that either at the beginning of the next line or at the end of the file except in the one case ('+') where the standard explicitly says not to. While here, try to reduce diff to upstream a little and update their RCS tag to reflect the fact that while we've diverged significantly from them, we've incorporated all their changes. Remove the useless second RCS tag. We also update the tests to account for the change in interpretation of the '1' case and add a test case for unterminated input. MFC after: 1 week Sponsored by: Klara, Inc. Reviewed by: kevans Differential Revision: https://reviews.freebsd.org/D43326 (cherry picked from commit c2356a440db91c106867d45c94b3d6d7bc0e50f0) --- usr.bin/asa/asa.c | 102 +++++++++++++++++++----------------------- usr.bin/asa/tests/asa_test.sh | 15 ++++++- 2 files changed, 59 insertions(+), 58 deletions(-) diff --git a/usr.bin/asa/asa.c b/usr.bin/asa/asa.c index 2033bc1ee63c..34365b671f00 100644 --- a/usr.bin/asa/asa.c +++ b/usr.bin/asa/asa.c @@ -1,4 +1,4 @@ -/* $NetBSD: asa.c,v 1.11 1997/09/20 14:55:00 lukem Exp $ */ +/* $NetBSD: asa.c,v 1.17 2016/09/05 00:40:28 sevan Exp $ */ /*- * SPDX-License-Identifier: BSD-4-Clause @@ -32,13 +32,8 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#if 0 -#ifndef lint -__RCSID("$NetBSD: asa.c,v 1.11 1997/09/20 14:55:00 lukem Exp $"); -#endif -#endif #include +#include #include #include #include @@ -50,38 +45,33 @@ static void usage(void); int main(int argc, char *argv[]) { - int ch, exval; FILE *fp; - const char *fn; + int ch, exval; while ((ch = getopt(argc, argv, "")) != -1) { switch (ch) { - case '?': default: usage(); - /*NOTREACHED*/ } } argc -= optind; argv += optind; exval = 0; - if (argc == 0) + if (*argv == NULL) { asa(stdin); - else { - while ((fn = *argv++) != NULL) { - if (strcmp(fn, "-") == 0) { + } else { + do { + if (strcmp(*argv, "-") == 0) { asa(stdin); + } else if ((fp = fopen(*argv, "r")) == NULL) { + warn("%s", *argv); + exval = 1; } else { - if ((fp = fopen(fn, "r")) == NULL) { - warn("%s", fn); - exval = 1; - continue; - } asa(fp); fclose(fp); } - } + } while (*++argv != NULL); } if (fflush(stdout) != 0) @@ -93,7 +83,6 @@ main(int argc, char *argv[]) static void usage(void) { - fprintf(stderr, "usage: asa [file ...]\n"); exit(1); } @@ -101,52 +90,53 @@ usage(void) static void asa(FILE *f) { - size_t len; char *buf; + size_t len; + bool eol = false; - if ((buf = fgetln(f, &len)) != NULL) { - if (buf[len - 1] == '\n') - buf[--len] = '\0'; - /* special case the first line */ + while ((buf = fgetln(f, &len)) != NULL) { + /* in all cases but '+', terminate previous line, if any */ + if (buf[0] != '+' && eol) + putchar('\n'); + /* examine and translate the control character */ switch (buf[0]) { + default: + /* + * “It is suggested that implementations treat + * characters other than 0, 1, and '+' as + * in the absence of any compelling reason to do + * otherwise” (POSIX.1-2017) + */ + case ' ': + /* nothing */ + break; case '0': putchar('\n'); break; case '1': putchar('\f'); break; - } - - if (len > 1 && buf[0] && buf[1]) - printf("%.*s", (int)(len - 1), buf + 1); - - while ((buf = fgetln(f, &len)) != NULL) { - if (buf[len - 1] == '\n') - buf[--len] = '\0'; - switch (buf[0]) { - default: - case ' ': - putchar('\n'); - break; - case '0': - putchar('\n'); - putchar('\n'); - break; - case '1': - putchar('\f'); - break; - case '+': + case '+': + /* + * “If the '+' is the first character in the + * input, it shall be equivalent to .” + * (POSIX.1-2017) + */ + if (eol) putchar('\r'); - break; - } - - if (len > 1 && buf[0] && buf[1]) - printf("%.*s", (int)(len - 1), buf + 1); + break; } - - putchar('\n'); + /* trim newline if there is one */ + if ((eol = (buf[len - 1] == '\n'))) + --len; + /* print the rest of the input line */ + if (len > 1 && buf[0] && buf[1]) + fwrite(buf + 1, 1, len - 1, stdout); } - + /* terminate the last line, if any */ + if (eol) + putchar('\n'); + /* check for output errors */ if (ferror(stdout) != 0) err(1, "stdout"); } diff --git a/usr.bin/asa/tests/asa_test.sh b/usr.bin/asa/tests/asa_test.sh index 429342d530e4..91515bb55d95 100644 --- a/usr.bin/asa/tests/asa_test.sh +++ b/usr.bin/asa/tests/asa_test.sh @@ -38,8 +38,8 @@ one_head() { atf_set descr "First character on line is '1'" } one_body() { - printf " %s\n1%s\n" "$a" "$b" >infile - printf "%s\f%s\n" "$a" "$b" >outfile + printf "1%s\n1%s\n" "$a" "$b" >infile + printf "\f%s\n\f%s\n" "$a" "$b" >outfile atf_check_asa infile outfile } @@ -87,6 +87,16 @@ dashdash_body() { atf_check -o inline:"$a $b\n" asa -- -infile } +atf_test_case unterminated +unterminated_head() { + atf_set descr "Unterminated input" +} +unterminated_body() { + printf " %s\n %s" "$a" "$b" >infile + printf "%s\n%s" "$a" "$b" >outfile + atf_check_asa infile outfile +} + atf_init_test_cases() { atf_add_test_case space @@ -96,4 +106,5 @@ atf_init_test_cases() atf_add_test_case plus_top atf_add_test_case stdout atf_add_test_case dashdash + atf_add_test_case unterminated }