From nobody Fri Apr 12 17:31:47 2024 X-Original-To: dev-commits-src-main@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 4VGNsc03Vvz5Hm0W; Fri, 12 Apr 2024 17:31:48 +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 4VGNsb6bdTz45Tm; Fri, 12 Apr 2024 17:31:47 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1712943107; 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=Z8qLfR5ZB12xV+YrvNRegVvI2OjPP8OEas4YrJZX6ik=; b=rdzLEUWzD8xP4V3xJbmKRjMfkfbCeOHOxddsIV02EXEQW1LHx+2UaWoW1x6KMbppsZcDu8 WMDRAHNPwgaiXFVC9gUBe01tc5lMeRpeuH4z6+V2Qa7C8aBpj8qWV1o8+FHKjMGb9DG963 QAFB/wcD01OvAGwypw8S/WOkJvrG2qYO10yLhduYeFYM0nlc8ae+sd+chaHBojSEW4kmAT gojyq7juzPwUQTCD0CgrVO2LQ/723d0QtKd9mzscNm5WyHen5zjM58N/m0Y8gXDFKhnPfI MxOVtZFl2yyJJz0YiFmoPisdUlZf+LfbZXg5bc+o0vqQxJZW1LMlf9a9q3ap7g== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1712943107; a=rsa-sha256; cv=none; b=dVhKg8gb398N5ntduuzfvHrx8oiNbH5tIWEHCHzOUi5xJ4nEAU35xCVvexI/3myCGCMx6k +K6ISm4ZF+CvBxaatSZjuTXFsF2STpA6H8Qm/sUREREYbWZ3w6eZSiKQBVEzizJ9LmSRJs 2Wq0uSbAaBxkCHCw1c4Jem9gOXL5KVluxIKBnofT3T32i0Y8rg8hn6voGKNShkGkqGfgDq 8JVDfNTB75PGx70d6gqv/E7sc8ZRFbJGnZROA7pu4RolI1roAcyc9M3UWaFXLCOZP+rtsn QbUtLNdc9sjsMk1Ab0x/A2KB1GawMoNsJz1Q25aTIPREYU0Sg25WGYsWBohNbw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1712943107; 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=Z8qLfR5ZB12xV+YrvNRegVvI2OjPP8OEas4YrJZX6ik=; b=PXQsA43v2CZMMhmbAvsZp1X891Mc0p/fvwAygqI8e7bvbl8o/ltjMS4LxJiMgbfSOh1uCa iEm/tsT8Wli4Mw1h/HwnnDE9wujq4aCovk62Yqgoubaw8BtSjRHci77kGJaQdS4QNMgDet Hgi8bBXGRG5NiNEAn43FusfefogF0YPuEIv9juS4Jc2nVinG4ZDWVwn199sZ1oJ3sO0kKv u43mFMfv/Cx6R6HHs3rg+O7V1dbk9bauSG7t1WkvwnItj74IWfxNfYCT/tWfTZL59TNfkv ytZsTp67uwgJDKLmX8jYWhdVvzxmZpynTdrTAX4mlzRVv9I3RO2+og9/fON9Vg== 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 4VGNsb5plpzy2K; Fri, 12 Apr 2024 17:31:47 +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 43CHVlck006749; Fri, 12 Apr 2024 17:31:47 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 43CHVl6S006746; Fri, 12 Apr 2024 17:31:47 GMT (envelope-from git) Date: Fri, 12 Apr 2024 17:31:47 GMT Message-Id: <202404121731.43CHVl6S006746@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Dag-Erling =?utf-8?Q?Sm=C3=B8rgrav?= Subject: git: 17dc7017d737 - main - install: Simplify path construction. List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@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/main X-Git-Reftype: branch X-Git-Commit: 17dc7017d7375b3463d65adffe1eb980b0f86795 Auto-Submitted: auto-generated The branch main has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=17dc7017d7375b3463d65adffe1eb980b0f86795 commit 17dc7017d7375b3463d65adffe1eb980b0f86795 Author: Dag-Erling Smørgrav AuthorDate: 2024-04-12 17:30:52 +0000 Commit: Dag-Erling Smørgrav CommitDate: 2024-04-12 17:31:35 +0000 install: Simplify path construction. There's no need to copy the path twice to split it into base and dir. We simply call `basename()` first, then handle the two trivial cases in which it isn't safe to call `dirname()`. While here, add an early check that the destination is not an empty string. This would always fail eventually, so it may as well fail right away. Also add a test case for this shortcut. MFC after: 1 week Sponsored by: Klara, Inc. Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D44743 --- usr.bin/xinstall/tests/install_test.sh | 8 ++++++++ usr.bin/xinstall/xinstall.c | 34 +++++++++++++++++++++------------- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/usr.bin/xinstall/tests/install_test.sh b/usr.bin/xinstall/tests/install_test.sh index cbe95f0dfbf3..b35706521ec3 100755 --- a/usr.bin/xinstall/tests/install_test.sh +++ b/usr.bin/xinstall/tests/install_test.sh @@ -25,6 +25,13 @@ # # +atf_test_case copy_to_empty +copy_to_empty_body() { + printf 'test\n123\r456\r\n789\0z' >testf + atf_check -s not-exit:0 -e match:"empty string" \ + install testf "" +} + copy_to_nonexistent_with_opts() { printf 'test\n123\r456\r\n789\0z' >testf atf_check install "$@" testf copyf @@ -497,6 +504,7 @@ set_optional_exec_body() } atf_init_test_cases() { + atf_add_test_case copy_to_empty atf_add_test_case copy_to_nonexistent atf_add_test_case copy_to_nonexistent_safe atf_add_test_case copy_to_nonexistent_comparing diff --git a/usr.bin/xinstall/xinstall.c b/usr.bin/xinstall/xinstall.c index 6d2f05d64e2c..6ab0a88d5cd7 100644 --- a/usr.bin/xinstall/xinstall.c +++ b/usr.bin/xinstall/xinstall.c @@ -657,8 +657,10 @@ static void makelink(const char *from_name, const char *to_name, const struct stat *target_sb) { - char src[MAXPATHLEN], dst[MAXPATHLEN], lnk[MAXPATHLEN]; - struct stat to_sb; + char src[MAXPATHLEN], dst[MAXPATHLEN], lnk[MAXPATHLEN]; + char *to_name_copy, *d, *ld, *ls, *s; + const char *base, *dir; + struct stat to_sb; /* Try hard links first. */ if (dolink & (LN_HARD|LN_MIXED)) { @@ -719,8 +721,6 @@ makelink(const char *from_name, const char *to_name, } if (dolink & LN_RELATIVE) { - char *to_name_copy, *cp, *d, *ld, *ls, *s; - if (*from_name != '/') { /* this is already a relative link */ do_symlink(from_name, to_name, target_sb); @@ -740,17 +740,23 @@ makelink(const char *from_name, const char *to_name, to_name_copy = strdup(to_name); if (to_name_copy == NULL) err(EX_OSERR, "%s: strdup", to_name); - cp = dirname(to_name_copy); - if (realpath(cp, dst) == NULL) - err(EX_OSERR, "%s: realpath", cp); - /* .. and add the last component. */ - if (strcmp(dst, "/") != 0) { - if (strlcat(dst, "/", sizeof(dst)) > sizeof(dst)) + base = basename(to_name_copy); + if (base == to_name_copy) { + /* destination is a file in cwd */ + (void)strlcpy(dst, "./", sizeof(dst)); + } else if (base == to_name_copy + 1) { + /* destination is a file in the root */ + (void)strlcpy(dst, "/", sizeof(dst)); + } else { + /* all other cases: safe to call dirname() */ + dir = dirname(to_name_copy); + if (realpath(dir, dst) == NULL) + err(EX_OSERR, "%s: realpath", dir); + if (strcmp(dst, "/") != 0 && + strlcat(dst, "/", sizeof(dst)) > sizeof(dst)) errx(1, "resolved pathname too long"); } - strcpy(to_name_copy, to_name); - cp = basename(to_name_copy); - if (strlcat(dst, cp, sizeof(dst)) > sizeof(dst)) + if (strlcat(dst, base, sizeof(dst)) > sizeof(dst)) errx(1, "resolved pathname too long"); free(to_name_copy); @@ -834,6 +840,8 @@ install(const char *from_name, const char *to_name, u_long fset, u_int flags) } else { devnull = 1; } + if (*to_name == '\0') + errx(EX_USAGE, "destination cannot be an empty string"); target = (lstat(to_name, &to_sb) == 0);