From patchwork Fri Nov 18 11:46:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsCBCamFybWFzb24=?= X-Patchwork-Id: 13048142 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 90557C43217 for ; Fri, 18 Nov 2022 11:47:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241309AbiKRLrK (ORCPT ); Fri, 18 Nov 2022 06:47:10 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45288 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241653AbiKRLrF (ORCPT ); Fri, 18 Nov 2022 06:47:05 -0500 Received: from mail-ej1-x62a.google.com (mail-ej1-x62a.google.com [IPv6:2a00:1450:4864:20::62a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A3C9B2182A for ; Fri, 18 Nov 2022 03:47:04 -0800 (PST) Received: by mail-ej1-x62a.google.com with SMTP id f27so12477144eje.1 for ; Fri, 18 Nov 2022 03:47:04 -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=VUOskB7cUnbKwbJc7ZWKlpeX+jnnAEIE6O+6lNHuGzk=; b=cJifsZZPpF4Xai8s6HnGkZcq/ASvMv99TB7Crs64Tg2Ug89/DftP5DCdPX8Bja0ViP ztfeCePRwEu261VeGfSI5KUnORwnl/XvVokuEw/27QwSups7uawCbTltEnES68qO2VI4 d3IcviYSPlmVFfZ6e9ADyUL8pjUiPDCG66Q89h1wc1dEYgwR+tEP6HchtBB9Oq5Wzvtv vYR3HSsDB+oZGGq8wnWNTkG7+0TR9jsPXHFAnkVX5yL+eP8hteuIWecwyuHuVCMTQDE9 LsM1kBcHmKTgOUMxIQ747mNdqYc0GCe9yUH8Lb8d8XAswNldE0RtEpAOW8dtGmB0scbX hcjw== 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=VUOskB7cUnbKwbJc7ZWKlpeX+jnnAEIE6O+6lNHuGzk=; b=Evyiu0swEWCfA1sJBC+4BavpbCFqyDGebYEr4Py5qG3zRdfadrKknAaDMxK/VYMJDX P3YCyi9iaN5is0/1InL+8Z/qtDe7k+pnOPbkJ2rih+StsexqunX3dDNNKrx025Q7xavm 41yMKYFdKurEMPI6YOG7NwZNQWC3UKjNoTOSHpylAEPti7RZu8CVliQe+UQYNQhuRvDT F35KKUMWPn7tk7bwGrRyBXrsNB3y3PTtCpsNsdw4fDLxhwJ7zpVALI40c6rElGsDJwbS 7LmfSHbCGJdPx0SjKm4gmlajzPZngG0iaVYK5ehGk2LRcgJ/uZw1vycozi93TYQeQfIr /TLQ== X-Gm-Message-State: ANoB5pkwKsb8uyu4G63uk0CeRs6RCd6aplp80dojaOV+EHtLOaO/LtaE 9rvtJp7PUYc3mL/YcDrn98H+XpQS5mgEbA== X-Google-Smtp-Source: AA0mqf7Vft/3FKQH/JyVZaUSZZMYt59vZZuQBJrwTI6Okv4K5+vDMtw3f2oPVO6kx4OBLjBixkgZpg== X-Received: by 2002:a17:906:eb8e:b0:7b2:a2c3:2ff0 with SMTP id mh14-20020a170906eb8e00b007b2a2c32ff0mr5018511ejb.561.1668772022821; Fri, 18 Nov 2022 03:47:02 -0800 (PST) Received: from vm.nix.is (vm.nix.is. [2a01:4f8:120:2468::2]) by smtp.gmail.com with ESMTPSA id o8-20020aa7dd48000000b004615e1bbaf4sm1705349edw.87.2022.11.18.03.47.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 18 Nov 2022 03:47:02 -0800 (PST) From: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsCBCamFybWFzb24=?= To: git@vger.kernel.org Cc: Taylor Blau , Junio C Hamano , Jeff King , Jonathan Tan , Kousik Sanagavarapu , =?utf-8?b?w4Z2YXIgQXJuZmrDtnI=?= =?utf-8?b?w7AgQmphcm1hc29u?= Subject: [PATCH 1/4] object-file.c: free the "t.tag" in check_tag() Date: Fri, 18 Nov 2022 12:46:56 +0100 Message-Id: X-Mailer: git-send-email 2.38.0.1512.g9e0c09a155f In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Fix a memory leak that's been with us ever since c879daa2372 (Make hash-object more robust against malformed objects, 2011-02-05). With "HASH_FORMAT_CHECK" (used by "hash-object" and "replace") we'll parse tags into a throwaway variable on the stack, but weren't freeing the "item->tag" we might malloc() when doing so. Mark the tests that now pass in their entirety as passing under "SANITIZE=leak", which means we'll test them as part of the "linux-leaks" CI job. Signed-off-by: Ævar Arnfjörð Bjarmason --- object-file.c | 1 + t/t3800-mktag.sh | 1 + t/t5302-pack-index.sh | 2 ++ 3 files changed, 4 insertions(+) diff --git a/object-file.c b/object-file.c index 957790098fa..a13edba0753 100644 --- a/object-file.c +++ b/object-file.c @@ -2338,6 +2338,7 @@ static void check_tag(const void *buf, size_t size) memset(&t, 0, sizeof(t)); if (parse_tag_buffer(the_repository, &t, buf, size)) die(_("corrupt tag")); + free(t.tag); } static int index_mem(struct index_state *istate, diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh index e3cf0ffbe59..d3e428ff46e 100755 --- a/t/t3800-mktag.sh +++ b/t/t3800-mktag.sh @@ -4,6 +4,7 @@ test_description='git mktag: tag object verify test' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh ########################################################### diff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh index b0095ab41d3..54b11f81c63 100755 --- a/t/t5302-pack-index.sh +++ b/t/t5302-pack-index.sh @@ -4,6 +4,8 @@ # test_description='pack index with 64-bit offsets and object CRC' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' From patchwork Fri Nov 18 11:46:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsCBCamFybWFzb24=?= X-Patchwork-Id: 13048143 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A0A99C433FE for ; Fri, 18 Nov 2022 11:47:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241494AbiKRLrM (ORCPT ); Fri, 18 Nov 2022 06:47:12 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45298 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241669AbiKRLrG (ORCPT ); Fri, 18 Nov 2022 06:47:06 -0500 Received: from mail-ed1-x529.google.com (mail-ed1-x529.google.com [IPv6:2a00:1450:4864:20::529]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 86EC112AF1 for ; Fri, 18 Nov 2022 03:47:05 -0800 (PST) Received: by mail-ed1-x529.google.com with SMTP id y24so1775811edi.10 for ; Fri, 18 Nov 2022 03:47:05 -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=SeibMuXDOcrY1SB7ENh6HTqdiuDSmneLOLX8+J/ew/A=; b=KQJUkU9a/fp5jRNtL7slJy+WzzfxUnLrme7peMoqiPQ5yiglYzRrsh1QT4OSI9L8wb qPZC6pltOIp8Ft6UzkXAZlP5KJxEAK24c9xLGRD2lGiCHTiWLyT4yL9UafPM0S7mRLig wH0IBNz2rfJGzYhECp3yUndox4jspc2F2KB/DzrTevTv0dCdKAVYJ3F9EBwlsfEGWjmM 7P6xB9wKXB064XcwqTQlUyfjLJzY3yfIfgP8+dKMfQH9lZ0FAIcvHmmhWcO8qoH2Q51R iAM3vp6Ln1HndfS+ivt4G5+XkbYacLsX/Ms2dW9Coca0lIwIRX4rjzM9gOPxMn0tbfHP 3gjQ== 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=SeibMuXDOcrY1SB7ENh6HTqdiuDSmneLOLX8+J/ew/A=; b=Hi3SobcmhBEpX7IZ1UKd+sDB0IL8PKc/xObHJRj1bsYRKqFzoyVUyUpnqver5djg9A 6/KznC7ksTYgOecz5lGyofh+1CFXGQkgvLlTD8Sh0p4sOit8hYWqbzkdgqNk6R1c8pvg QjNslfpJ7DaeDxVtcU+dS9uHhaziaAXbjuBRdutIlJpaXyz60HAgh88J+lhCvo1FpPJn kLEUqoCILFWnYMI5SMOfJsOtjCf4TFwGpU/1MrI2s8qDOAaubXxHeMpmGtqwX357N0rQ haIYLliMI5qFuX9PMWJwmST91A0AObg3K+kQqh4h7gtYFXmxG9YNhIFplihNlV9fmIkR FaVQ== X-Gm-Message-State: ANoB5pl/i3TojxJKNRhWWR143VTkb7hs6Zd0yajFRRE60PJIw3qrMYr7 ZCVw5BxB7BMnW+NXJA/ykx6J0SGBzkrvaA== X-Google-Smtp-Source: AA0mqf65JrO6YHKdFogERlhayTYt7qKPwiDFTpnyiKGqHgIQhkrETihYrillHQ6NIo7YZLwpJIm7wQ== X-Received: by 2002:a05:6402:347:b0:469:2f23:3b99 with SMTP id r7-20020a056402034700b004692f233b99mr320921edw.44.1668772023706; Fri, 18 Nov 2022 03:47:03 -0800 (PST) Received: from vm.nix.is (vm.nix.is. [2a01:4f8:120:2468::2]) by smtp.gmail.com with ESMTPSA id o8-20020aa7dd48000000b004615e1bbaf4sm1705349edw.87.2022.11.18.03.47.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 18 Nov 2022 03:47:03 -0800 (PST) From: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsCBCamFybWFzb24=?= To: git@vger.kernel.org Cc: Taylor Blau , Junio C Hamano , Jeff King , Jonathan Tan , Kousik Sanagavarapu , =?utf-8?b?w4Z2YXIgQXJuZmrDtnI=?= =?utf-8?b?w7AgQmphcm1hc29u?= Subject: [PATCH 2/4] object tests: add test for unexpected objects in tags Date: Fri, 18 Nov 2022 12:46:57 +0100 Message-Id: X-Mailer: git-send-email 2.38.0.1512.g9e0c09a155f In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Fix a blind spot in the tests added in 0616617c7e1 (t: introduce tests for unexpected object types, 2019-04-09), there were no meaningful tests for checking how we reported on finding the incorrect object type in a tag, i.e. one that broke the "type" promise in the tag header. We'll report the wrong object type in these cases, and thus fail on the "test_cmp", e.g. for the first "error: " output being tested here we should say "$commit is a tag, not a commit", instead we say "$commit is a commit, not a tag". This will be fixed in a subsequent commit. See the discussion & notes in [1] and downthread of there for test snippets that are adapted here. In the case of "fsck" which objects we visit in what order, and if we report errors on them depends on their OIDs. So the test uses the technique of extracting the OID/type combinations that fsck does report, and asserting that those are correct (currently, it's far from correct). 1. https://lore.kernel.org/git/YGTGgFI19fS7Uv6I@coredump.intra.peff.net/ Helped-by: Jeff King Signed-off-by: Ævar Arnfjörð Bjarmason --- t/t6102-rev-list-unexpected-objects.sh | 146 +++++++++++++++++++++++++ 1 file changed, 146 insertions(+) diff --git a/t/t6102-rev-list-unexpected-objects.sh b/t/t6102-rev-list-unexpected-objects.sh index 9350b5fd2c2..ac49f7182fd 100755 --- a/t/t6102-rev-list-unexpected-objects.sh +++ b/t/t6102-rev-list-unexpected-objects.sh @@ -130,4 +130,150 @@ test_expect_success 'traverse unexpected non-blob tag (seen)' ' test_i18ngrep "not a blob" output ' +test_expect_success 'setup unexpected non-tag tag' ' + test_when_finished "git tag -d tag-commit tag-tag" && + + git tag -a -m"my tagged commit" tag-commit $commit && + tag_commit=$(git rev-parse tag-commit) && + git tag -a -m"my tagged tag" tag-tag tag-commit && + tag_tag=$(git rev-parse tag-tag) && + + git cat-file tag tag-tag >good-tag-tag && + git cat-file tag tag-commit >good-commit-tag && + + sed -e "s/$tag_commit/$commit/" broken-tag-tag-commit && + sed -e "s/$tag_commit/$tree/" broken-tag-tag-tree && + sed -e "s/$tag_commit/$blob/" broken-tag-tag-blob && + + sed -e "s/$commit/$tag_commit/" broken-commit-tag-tag && + sed -e "s/$commit/$tree/" broken-commit-tag-tree && + sed -e "s/$commit/$blob/" broken-commit-tag-blob && + + tag_tag_commit=$(git hash-object -w -t tag broken-tag-tag-commit) && + tag_tag_tree=$(git hash-object -w -t tag broken-tag-tag-tree) && + tag_tag_blob=$(git hash-object -w -t tag broken-tag-tag-blob) && + + git update-ref refs/tags/tag_tag_commit $tag_tag_commit && + git update-ref refs/tags/tag_tag_tree $tag_tag_tree && + git update-ref refs/tags/tag_tag_blob $tag_tag_blob && + + commit_tag_tag=$(git hash-object -w -t tag broken-commit-tag-tag) && + commit_tag_tree=$(git hash-object -w -t tag broken-commit-tag-tree) && + commit_tag_blob=$(git hash-object -w -t tag broken-commit-tag-blob) && + + git update-ref refs/tags/commit_tag_tag $commit_tag_tag && + git update-ref refs/tags/commit_tag_tree $commit_tag_tree && + git update-ref refs/tags/commit_tag_blob $commit_tag_blob +' + +test_expect_failure 'traverse unexpected incorrectly typed tag (to commit & tag)' ' + test_must_fail git rev-list --objects $tag_tag_commit 2>err && + cat >expect <<-EOF && + error: object $commit is a commit, not a tag + fatal: bad object $commit + EOF + test_cmp expect err && + + test_must_fail git rev-list --objects $commit_tag_tag 2>err && + cat >expect <<-EOF && + error: object $tag_commit is a tag, not a commit + fatal: bad object $tag_commit + EOF + test_cmp expect err +' + +test_expect_failure 'traverse unexpected incorrectly typed tag (to tree)' ' + test_must_fail git rev-list --objects $tag_tag_tree 2>err && + cat >expect <<-EOF && + error: object $tree is a tree, not a tag + fatal: bad object $tree + EOF + test_cmp expect err && + + test_must_fail git rev-list --objects $commit_tag_tree 2>err && + cat >expect <<-EOF && + error: object $tree is a tree, not a commit + fatal: bad object $tree + EOF + test_cmp expect err +' + +test_expect_failure 'traverse unexpected incorrectly typed tag (to blob)' ' + test_must_fail git rev-list --objects $tag_tag_blob 2>err && + cat >expect <<-EOF && + error: object $blob is a blob, not a tag + fatal: bad object $blob + EOF + test_cmp expect err && + + test_must_fail git rev-list --objects $commit_tag_blob 2>err && + cat >expect <<-EOF && + error: object $blob is a blob, not a commit + fatal: bad object $blob + EOF + test_cmp expect err +' + +test_expect_failure 'traverse unexpected non-tag tag (tree seen to blob)' ' + test_must_fail git rev-list --objects $tree $commit_tag_blob 2>err && + cat >expect <<-EOF && + error: object $blob is a blob, not a commit + fatal: bad object $blob + EOF + test_cmp expect err && + + test_must_fail git rev-list --objects $tree $tag_tag_blob 2>err && + cat >expect <<-EOF && + error: object $blob is a blob, not a tag + fatal: bad object $blob + EOF + test_cmp expect err +' + + +test_expect_failure 'traverse unexpected objects with for-each-ref' ' + cat >expect <<-EOF && + error: bad tag pointer to $tree in $tag_tag_tree + fatal: parse_object_buffer failed on $tag_tag_tree for refs/tags/tag_tag_tree + EOF + test_must_fail git for-each-ref --format="%(*objectname)" 2>actual && + test_cmp expect actual +' + +>fsck-object-isa +test_expect_failure 'setup: unexpected objects with fsck' ' + test_must_fail git fsck 2>err && + sed -n -e "/^error: object .* is a .*, not a .*$/ { + s/^error: object \([0-9a-f]*\) is a \([a-z]*\), not a [a-z]*$/\\1 \\2/; + p; + }" fsck-object-isa +' + +while read oid type +do + test_expect_failure "fsck knows unexpected object $oid is $type" ' + git cat-file -t $oid >expect && + echo $type >actual && + test_cmp expect actual + ' +done err && + cat >expected <<-EOF && + error: object $blob is a blob, not a commit + error: bad tag pointer to $blob in $commit_tag_blob + fatal: bad object $commit_tag_blob + EOF + test_cmp expected err && + + test_must_fail git rev-list --objects $blob $tag_tag_blob 2>err && + cat >expected <<-EOF && + error: object $blob is a blob, not a tag + error: bad tag pointer to $blob in $tag_tag_blob + fatal: bad object $tag_tag_blob + EOF + test_cmp expected err +' + test_done From patchwork Fri Nov 18 11:46:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsCBCamFybWFzb24=?= X-Patchwork-Id: 13048146 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 24C24C433FE for ; Fri, 18 Nov 2022 11:47:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241438AbiKRLrV (ORCPT ); Fri, 18 Nov 2022 06:47:21 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45312 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241683AbiKRLrI (ORCPT ); Fri, 18 Nov 2022 06:47:08 -0500 Received: from mail-ej1-x631.google.com (mail-ej1-x631.google.com [IPv6:2a00:1450:4864:20::631]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 818B882BCB for ; Fri, 18 Nov 2022 03:47:06 -0800 (PST) Received: by mail-ej1-x631.google.com with SMTP id f18so12430884ejz.5 for ; Fri, 18 Nov 2022 03:47:06 -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=KqXhBc329812HBPTfgww2TQRGYdF3e1M0LMZ0mDcuP4=; b=ptTJLikLhCGPKOAPJkX//vmcFsU+KGRkmU0HvTS4vnJyZ4TulE14xDrUORc8rO422r GyqkAaG1QfvyAC2yG1EXHsFNOANjeq2XDRnCcsc0EdE9D6to4cLAdqJlTdLpKJCbPg9m DJ9q7wk20Qv14WTbP4vc376Nk0jrMmbYQCgio4QJa3rFSKftqgf8UdtIGG8/xtXvxrlR yoQKlBjLfi73OiUHD/a1oyAyZqYvp+Kv8YKAPOFA/t3j1ofduHaxRAeahnVENmdo6hJR +7DddNOWwWv2mDGC5jYPPCVFySsudO9nut8RxP7xS1tlwepAkfj/2tCO7HlGP+UYOdUW tcPQ== 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=KqXhBc329812HBPTfgww2TQRGYdF3e1M0LMZ0mDcuP4=; b=HLSBYcV41ekczj1Ql9zLkSsqvs8GQvK3hMuI5Ucd9gu28E+JSdQPqc2ZGfOyb4Upzm rgBUaNHZAUJ0uRc0z42XD9C8tuv9eZYgyA1y8TdzSIJbE/3UW6fIuDLFnf4jYk+zbuYm OQNAPiVi70GeU/2Mlk5NXO8Zi/ettI9rrBalZPNGnm/gMJwE8cfNSNrUSu+8azSdbf5V ytXFVWr91smeloOwl2NVQsaji5DoGvwJmpOUEvCnIKjf6YHlWFEWnxfVaPDDRZspGMzb c90xPfAeUMF5jJBDv9EdyysXYTjfgsqlVZr4oko1IJxxcTFW+maIYMLdHT8k95FQ1b58 Q2ZQ== X-Gm-Message-State: ANoB5pnMS7lcf2m9sBTGwmGvoPg+KQ6/C1k7djyEP1Bo/+LfNdRPCb3m 4fBxRprB/dmwBCzMsI+2l2W7O1bZl9M6oA== X-Google-Smtp-Source: AA0mqf6YUiA2tIuhkMPSRGbR5mp1UMqgrf6zRUwr5zKiKWcjLUebgeCAy57NlrFzo/cvJ6dvGQk0IA== X-Received: by 2002:a17:906:c052:b0:79a:101a:7e57 with SMTP id bm18-20020a170906c05200b0079a101a7e57mr5649090ejb.368.1668772024656; Fri, 18 Nov 2022 03:47:04 -0800 (PST) Received: from vm.nix.is (vm.nix.is. [2a01:4f8:120:2468::2]) by smtp.gmail.com with ESMTPSA id o8-20020aa7dd48000000b004615e1bbaf4sm1705349edw.87.2022.11.18.03.47.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 18 Nov 2022 03:47:03 -0800 (PST) From: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsCBCamFybWFzb24=?= To: git@vger.kernel.org Cc: Taylor Blau , Junio C Hamano , Jeff King , Jonathan Tan , Kousik Sanagavarapu , =?utf-8?b?w4Z2YXIgQXJuZmrDtnI=?= =?utf-8?b?w7AgQmphcm1hc29u?= Subject: [PATCH 3/4] tag: don't misreport type of tagged objects in errors Date: Fri, 18 Nov 2022 12:46:58 +0100 Message-Id: X-Mailer: git-send-email 2.38.0.1512.g9e0c09a155f In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Fix a regression in 89e4202f982 ([PATCH] Parse tags for absent objects, 2005-06-21) (yes, that ancient!) and correctly report an error on a tag like: object type commit As: error: object is tree, not a commit Instead of our long-standing misbehavior of inverting the two, and reporting: error: object is commit, not a tree Which, as can be trivially seen with 'git cat-file -t ' is incorrect. The reason for this misreporting is that in parse_tag_buffer() we end up doing a lookup_{blob,commit,tag,tree}() depending on what we read out of the "type" line. If we haven't parsed that object before we end up dispatching to the type-specific lookup functions, e.g. this for commit.c in lookup_commit_type(): struct object *obj = lookup_object(r, oid); if (!obj) return create_object(r, oid, alloc_commit_node(r)); Its allocation will then set the obj->type according to what the tag told us the type was, but which we've never validated. At this point we've got an object in memory that hasn't been parsed, and whose type is incorrect, since we mistrusted a tag to tell us the type. Then when we actually load the object with parse_object() we read it and find that it's a "tree". See 8ff226a9d5e (add object_as_type helper for casting objects, 2014-07-13) for that behavior (that's just a refactoring commit, but shows all the code involved). Which explains why we inverted the error report. Normally when object_as_type() is called it's by the lookup_{blob,commit,tag,tree}() functions via parse_object(). At that point we can trust the obj->type. In the case of parsing objects we've learned about via a tag with an incorrect type it's the opposite, the obj->type isn't correct and holds the mislabeled type, but we're parsing the object and know for sure what object type we're dealing with. So, let's add "lookup_{blob,commit,tag,tree}_type()" functions to go with the existing ""lookup_{blob,commit,tag,tree}()", we'll call these from "parse_object_buffer()" where we actually know the type, as opposed to the "parse_tag_buffer()" code where we're just guessing what it might be. This only help with the cases where we do see the tag reference, and then end up doing a full parse of the object. But as seen in the "for-each-ref" and "fsck" tests we have cases where we'll never fully parse it. Those will be handled in a subsequent commit, but for now this handles the common case of "show" etc. running into these. Signed-off-by: Ævar Arnfjörð Bjarmason --- blob.c | 11 +++++++++-- blob.h | 3 +++ commit.c | 11 +++++++++-- commit.h | 2 ++ object.c | 20 ++++++++++++++++---- object.h | 2 ++ t/t6102-rev-list-unexpected-objects.sh | 8 ++++---- tag.c | 21 +++++++++++++++++---- tag.h | 2 ++ tree.c | 11 +++++++++-- tree.h | 2 ++ 11 files changed, 75 insertions(+), 18 deletions(-) diff --git a/blob.c b/blob.c index 182718aba9f..ca30a22b2e8 100644 --- a/blob.c +++ b/blob.c @@ -5,12 +5,19 @@ const char *blob_type = "blob"; -struct blob *lookup_blob(struct repository *r, const struct object_id *oid) +struct blob *lookup_blob_type(struct repository *r, + const struct object_id *oid, + enum object_type type) { struct object *obj = lookup_object(r, oid); if (!obj) return create_object(r, oid, alloc_blob_node(r)); - return object_as_type(obj, OBJ_BLOB, 0); + return object_as_type_hint(obj, OBJ_BLOB, type); +} + +struct blob *lookup_blob(struct repository *r, const struct object_id *oid) +{ + return lookup_blob_type(r, oid, OBJ_NONE); } int parse_blob_buffer(struct blob *item, void *buffer, unsigned long size) diff --git a/blob.h b/blob.h index 16648720557..066a2effcbf 100644 --- a/blob.h +++ b/blob.h @@ -10,6 +10,9 @@ struct blob { }; struct blob *lookup_blob(struct repository *r, const struct object_id *oid); +struct blob *lookup_blob_type(struct repository *r, + const struct object_id *oid, + enum object_type type); int parse_blob_buffer(struct blob *item, void *buffer, unsigned long size); diff --git a/commit.c b/commit.c index 572301b80a2..8a90f279e24 100644 --- a/commit.c +++ b/commit.c @@ -67,12 +67,19 @@ struct commit *lookup_commit_object(struct repository *r, } -struct commit *lookup_commit(struct repository *r, const struct object_id *oid) +struct commit *lookup_commit_type(struct repository *r, + const struct object_id *oid, + enum object_type type) { struct object *obj = lookup_object(r, oid); if (!obj) return create_object(r, oid, alloc_commit_node(r)); - return object_as_type(obj, OBJ_COMMIT, 0); + return object_as_type_hint(obj, OBJ_COMMIT, type); +} + +struct commit *lookup_commit(struct repository *r, const struct object_id *oid) +{ + return lookup_commit_type(r, oid, OBJ_NONE); } struct commit *lookup_commit_reference_by_name(const char *name) diff --git a/commit.h b/commit.h index fa39202fa6b..95001a29d6b 100644 --- a/commit.h +++ b/commit.h @@ -78,6 +78,8 @@ struct commit *lookup_commit_object(struct repository *r, const struct object_id * "oid" is not in the object cache. */ struct commit *lookup_commit(struct repository *r, const struct object_id *oid); +struct commit *lookup_commit_type(struct repository *r, const struct object_id *oid, + enum object_type type); struct commit *lookup_commit_reference(struct repository *r, const struct object_id *oid); struct commit *lookup_commit_reference_gently(struct repository *r, diff --git a/object.c b/object.c index fad1a5af4a6..cc17ed0606e 100644 --- a/object.c +++ b/object.c @@ -177,6 +177,18 @@ void *object_as_type(struct object *obj, enum object_type type, int quiet) } } +void *object_as_type_hint(struct object *obj, enum object_type type, + enum object_type hint) +{ + if (hint != OBJ_NONE && obj->type != OBJ_NONE && obj->type != type) { + error(_("object %s is a %s, not a %s"), oid_to_hex(&obj->oid), + type_name(type), type_name(obj->type)); + obj->type = type; + return NULL; + } + return object_as_type(obj, type, 0);; +} + struct object *lookup_unknown_object(struct repository *r, const struct object_id *oid) { struct object *obj = lookup_object(r, oid); @@ -210,14 +222,14 @@ struct object *parse_object_buffer(struct repository *r, const struct object_id obj = NULL; if (type == OBJ_BLOB) { - struct blob *blob = lookup_blob(r, oid); + struct blob *blob = lookup_blob_type(r, oid, type); if (blob) { if (parse_blob_buffer(blob, buffer, size)) return NULL; obj = &blob->object; } } else if (type == OBJ_TREE) { - struct tree *tree = lookup_tree(r, oid); + struct tree *tree = lookup_tree_type(r, oid, type); if (tree) { obj = &tree->object; if (!tree->buffer) @@ -229,7 +241,7 @@ struct object *parse_object_buffer(struct repository *r, const struct object_id } } } else if (type == OBJ_COMMIT) { - struct commit *commit = lookup_commit(r, oid); + struct commit *commit = lookup_commit_type(r, oid, type); if (commit) { if (parse_commit_buffer(r, commit, buffer, size, 1)) return NULL; @@ -241,7 +253,7 @@ struct object *parse_object_buffer(struct repository *r, const struct object_id obj = &commit->object; } } else if (type == OBJ_TAG) { - struct tag *tag = lookup_tag(r, oid); + struct tag *tag = lookup_tag_type(r, oid, type); if (tag) { if (parse_tag_buffer(r, tag, buffer, size)) return NULL; diff --git a/object.h b/object.h index 31ebe114585..042c304d3a4 100644 --- a/object.h +++ b/object.h @@ -122,6 +122,8 @@ struct object *lookup_object(struct repository *r, const struct object_id *oid); void *create_object(struct repository *r, const struct object_id *oid, void *obj); void *object_as_type(struct object *obj, enum object_type type, int quiet); +void *object_as_type_hint(struct object *obj, enum object_type type, + enum object_type hint); /* * Returns the object, having parsed it to find out what it is. diff --git a/t/t6102-rev-list-unexpected-objects.sh b/t/t6102-rev-list-unexpected-objects.sh index ac49f7182fd..2e36d8bcfd9 100755 --- a/t/t6102-rev-list-unexpected-objects.sh +++ b/t/t6102-rev-list-unexpected-objects.sh @@ -166,7 +166,7 @@ test_expect_success 'setup unexpected non-tag tag' ' git update-ref refs/tags/commit_tag_blob $commit_tag_blob ' -test_expect_failure 'traverse unexpected incorrectly typed tag (to commit & tag)' ' +test_expect_success 'traverse unexpected incorrectly typed tag (to commit & tag)' ' test_must_fail git rev-list --objects $tag_tag_commit 2>err && cat >expect <<-EOF && error: object $commit is a commit, not a tag @@ -182,7 +182,7 @@ test_expect_failure 'traverse unexpected incorrectly typed tag (to commit & tag) test_cmp expect err ' -test_expect_failure 'traverse unexpected incorrectly typed tag (to tree)' ' +test_expect_success 'traverse unexpected incorrectly typed tag (to tree)' ' test_must_fail git rev-list --objects $tag_tag_tree 2>err && cat >expect <<-EOF && error: object $tree is a tree, not a tag @@ -198,7 +198,7 @@ test_expect_failure 'traverse unexpected incorrectly typed tag (to tree)' ' test_cmp expect err ' -test_expect_failure 'traverse unexpected incorrectly typed tag (to blob)' ' +test_expect_success 'traverse unexpected incorrectly typed tag (to blob)' ' test_must_fail git rev-list --objects $tag_tag_blob 2>err && cat >expect <<-EOF && error: object $blob is a blob, not a tag @@ -214,7 +214,7 @@ test_expect_failure 'traverse unexpected incorrectly typed tag (to blob)' ' test_cmp expect err ' -test_expect_failure 'traverse unexpected non-tag tag (tree seen to blob)' ' +test_expect_success 'traverse unexpected non-tag tag (tree seen to blob)' ' test_must_fail git rev-list --objects $tree $commit_tag_blob 2>err && cat >expect <<-EOF && error: object $blob is a blob, not a commit diff --git a/tag.c b/tag.c index dfbcd7fcc24..19453c2edbf 100644 --- a/tag.c +++ b/tag.c @@ -100,12 +100,18 @@ struct object *deref_tag_noverify(struct object *o) return o; } -struct tag *lookup_tag(struct repository *r, const struct object_id *oid) +struct tag *lookup_tag_type(struct repository *r, const struct object_id *oid, + enum object_type type) { struct object *obj = lookup_object(r, oid); if (!obj) return create_object(r, oid, alloc_tag_node(r)); - return object_as_type(obj, OBJ_TAG, 0); + return object_as_type_hint(obj, OBJ_TAG, type); +} + +struct tag *lookup_tag(struct repository *r, const struct object_id *oid) +{ + return lookup_tag_type(r, oid, OBJ_NONE); } static timestamp_t parse_tag_date(const char *buf, const char *tail) @@ -135,6 +141,7 @@ void release_tag_memory(struct tag *t) int parse_tag_buffer(struct repository *r, struct tag *item, const void *data, unsigned long size) { + struct object *obj; struct object_id oid; char type[20]; const char *bufptr = data; @@ -169,7 +176,10 @@ int parse_tag_buffer(struct repository *r, struct tag *item, const void *data, u type[nl - bufptr] = '\0'; bufptr = nl + 1; - if (!strcmp(type, blob_type)) { + obj = lookup_object(r, &oid); + if (obj) { + item->tagged = obj; + } else if (!strcmp(type, blob_type)) { item->tagged = (struct object *)lookup_blob(r, &oid); } else if (!strcmp(type, tree_type)) { item->tagged = (struct object *)lookup_tree(r, &oid); @@ -182,10 +192,13 @@ int parse_tag_buffer(struct repository *r, struct tag *item, const void *data, u type, oid_to_hex(&item->object.oid)); } - if (!item->tagged) + if (!item->tagged || strcmp(type_name(item->tagged->type), type)) { + error(_("object %s is a %s, not a %s"), oid_to_hex(&oid), + type_name(item->tagged->type), type); return error("bad tag pointer to %s in %s", oid_to_hex(&oid), oid_to_hex(&item->object.oid)); + } if (bufptr + 4 < tail && starts_with(bufptr, "tag ")) ; /* good */ diff --git a/tag.h b/tag.h index 3ce8e721924..42bd3e64011 100644 --- a/tag.h +++ b/tag.h @@ -12,6 +12,8 @@ struct tag { timestamp_t date; }; struct tag *lookup_tag(struct repository *r, const struct object_id *oid); +struct tag *lookup_tag_type(struct repository *r, const struct object_id *oid, + enum object_type type); int parse_tag_buffer(struct repository *r, struct tag *item, const void *data, unsigned long size); int parse_tag(struct tag *item); void release_tag_memory(struct tag *t); diff --git a/tree.c b/tree.c index 410e3b477e5..1a730249bb8 100644 --- a/tree.c +++ b/tree.c @@ -102,12 +102,19 @@ int cmp_cache_name_compare(const void *a_, const void *b_) ce2->name, ce2->ce_namelen, ce_stage(ce2)); } -struct tree *lookup_tree(struct repository *r, const struct object_id *oid) +struct tree *lookup_tree_type(struct repository *r, + const struct object_id *oid, + enum object_type type) { struct object *obj = lookup_object(r, oid); if (!obj) return create_object(r, oid, alloc_tree_node(r)); - return object_as_type(obj, OBJ_TREE, 0); + return object_as_type_hint(obj, OBJ_TREE, type); +} + +struct tree *lookup_tree(struct repository *r, const struct object_id *oid) +{ + return lookup_tree_type(r, oid, OBJ_NONE); } int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size) diff --git a/tree.h b/tree.h index 6efff003e21..4af3b617f3d 100644 --- a/tree.h +++ b/tree.h @@ -15,6 +15,8 @@ struct tree { extern const char *tree_type; struct tree *lookup_tree(struct repository *r, const struct object_id *oid); +struct tree *lookup_tree_type(struct repository *r, const struct object_id *oid, + enum object_type type); int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size); From patchwork Fri Nov 18 11:46:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsCBCamFybWFzb24=?= X-Patchwork-Id: 13048145 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4C2A7C433FE for ; Fri, 18 Nov 2022 11:47:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241514AbiKRLrR (ORCPT ); Fri, 18 Nov 2022 06:47:17 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45310 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241686AbiKRLrI (ORCPT ); Fri, 18 Nov 2022 06:47:08 -0500 Received: from mail-ej1-x62a.google.com (mail-ej1-x62a.google.com [IPv6:2a00:1450:4864:20::62a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7D56085156 for ; Fri, 18 Nov 2022 03:47:07 -0800 (PST) Received: by mail-ej1-x62a.google.com with SMTP id gv23so12442435ejb.3 for ; Fri, 18 Nov 2022 03:47:07 -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=ST5HLlFMCCR17IA9DT6M4TPm2jEcQSxejTvgA6hgMkE=; b=pZSuUv20L9KRKy6STXgZe2AyZ6CkcKm84Ub710nMcpsQODhWeGZCMETmTjQrlnEKKT sjkT2v8rfb/mkaczr96+v/O3JI10ekR12+r4hJKQTEvmDN1SLnXM0/1nSyXVZFmRuMZY BMAxb9E0u9d9WJWpulB6qOuwtL1rcpsTpfmpc1PSs+nIjrPE/EavZpbeaBpXUX5xnUfb TVLBtwOpvY4hi3k4dT3lNMRR5vJNF1IF/4202gWRei/EpEL8Su2o6pyzT/hKbUkTB+xe wdWSqwK2dWLHxjoDBFBi3MiuZAnpH99hP0gE0j0UW3uS+1TkXD7Zq4uNy6q3rpnB6fVG i7Ng== 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=ST5HLlFMCCR17IA9DT6M4TPm2jEcQSxejTvgA6hgMkE=; b=WSbdSO5Qu7ACCqPTIlwJjxuf5xn04jHo/JUQHwOWg7OpJcr35AAbnKZ2uEg4Bq9elN kHvChK5qSCPR1ceKzqUwjXHi4XFeEq02TZzQrt//SRZ3NE7hnY4zwPkrAjvkvGEQmdeO DPUpDm7UQ1ivBntERCo0vH+YLJepM0QRmsLqWitX1QLw+7eP9nehnKbKyAq3OwXTrW5V VV6qKOk1K/7dsC8BWLzrcnRRfnZt/D57XCgcPYcXnFt4SpSaaXvvS34qhR41EXUY8Goq HgP9hphqywIF8hwbl9TgQfjjJEXN5byv0ZFlDlfD8QYL8YQQwaQycogjG3gQti5sOD0Z QOGA== X-Gm-Message-State: ANoB5pmngNgL/crytDV5hJpbZ6STcZ3VGxZSU5sSSDQOVJI9SSo2RyTd Lf2ZLsQjpPcx/QeoyE5d/9Dds9JgBjtRoA== X-Google-Smtp-Source: AA0mqf5uxIJLX8AK8heMvQFt99Nlb5qSGAIjGIUopi6e1Ed/w+enYyX0o+kJVTxaUOs0Fx64KhKpBg== X-Received: by 2002:a17:907:378:b0:7ad:db82:d071 with SMTP id rs24-20020a170907037800b007addb82d071mr5925594ejb.200.1668772025696; Fri, 18 Nov 2022 03:47:05 -0800 (PST) Received: from vm.nix.is (vm.nix.is. [2a01:4f8:120:2468::2]) by smtp.gmail.com with ESMTPSA id o8-20020aa7dd48000000b004615e1bbaf4sm1705349edw.87.2022.11.18.03.47.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 18 Nov 2022 03:47:04 -0800 (PST) From: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsCBCamFybWFzb24=?= To: git@vger.kernel.org Cc: Taylor Blau , Junio C Hamano , Jeff King , Jonathan Tan , Kousik Sanagavarapu , =?utf-8?b?w4Z2YXIgQXJuZmrDtnI=?= =?utf-8?b?w7AgQmphcm1hc29u?= Subject: [PATCH 4/4] tag: don't emit potentially incorrect "object is a X, not a Y" Date: Fri, 18 Nov 2022 12:46:59 +0100 Message-Id: X-Mailer: git-send-email 2.38.0.1512.g9e0c09a155f In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org As noted in the preceding commit we weren't handling cases where we see a reference to a bad "type" in a "tag", but then end up not fully parsing the object. In those cases let's only claim that we have a bad tag pointer, but emit "is a %s, not a %s". Signed-off-by: Ævar Arnfjörð Bjarmason --- t/t6102-rev-list-unexpected-objects.sh | 6 +++--- tag.c | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/t/t6102-rev-list-unexpected-objects.sh b/t/t6102-rev-list-unexpected-objects.sh index 2e36d8bcfd9..ffc1672d7dc 100755 --- a/t/t6102-rev-list-unexpected-objects.sh +++ b/t/t6102-rev-list-unexpected-objects.sh @@ -231,7 +231,7 @@ test_expect_success 'traverse unexpected non-tag tag (tree seen to blob)' ' ' -test_expect_failure 'traverse unexpected objects with for-each-ref' ' +test_expect_success 'traverse unexpected objects with for-each-ref' ' cat >expect <<-EOF && error: bad tag pointer to $tree in $tag_tag_tree fatal: parse_object_buffer failed on $tag_tag_tree for refs/tags/tag_tag_tree @@ -241,7 +241,7 @@ test_expect_failure 'traverse unexpected objects with for-each-ref' ' ' >fsck-object-isa -test_expect_failure 'setup: unexpected objects with fsck' ' +test_expect_success 'setup: unexpected objects with fsck' ' test_must_fail git fsck 2>err && sed -n -e "/^error: object .* is a .*, not a .*$/ { s/^error: object \([0-9a-f]*\) is a \([a-z]*\), not a [a-z]*$/\\1 \\2/; @@ -251,7 +251,7 @@ test_expect_failure 'setup: unexpected objects with fsck' ' while read oid type do - test_expect_failure "fsck knows unexpected object $oid is $type" ' + test_expect_success "fsck knows unexpected object $oid is $type" ' git cat-file -t $oid >expect && echo $type >actual && test_cmp expect actual diff --git a/tag.c b/tag.c index 19453c2edbf..ad92cf89209 100644 --- a/tag.c +++ b/tag.c @@ -193,8 +193,9 @@ int parse_tag_buffer(struct repository *r, struct tag *item, const void *data, u } if (!item->tagged || strcmp(type_name(item->tagged->type), type)) { - error(_("object %s is a %s, not a %s"), oid_to_hex(&oid), - type_name(item->tagged->type), type); + if (item->tagged && item->tagged->parsed) + error(_("object %s is a %s, not a %s"), oid_to_hex(&oid), + type_name(item->tagged->type), type); return error("bad tag pointer to %s in %s", oid_to_hex(&oid), oid_to_hex(&item->object.oid));