From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: * X-Spam-ASN: AS3215 2.6.0.0/16 X-Spam-Status: No, score=1.2 required=3.0 tests=AWL,BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,LIST_MIRROR_RECEIVED,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE shortcircuit=no autolearn=no autolearn_force=no version=3.4.2 Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by dcvr.yhbt.net (Postfix) with ESMTP id 15B061F852 for ; Thu, 10 Feb 2022 22:47:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345155AbiBJWq4 (ORCPT ); Thu, 10 Feb 2022 17:46:56 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:35506 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345219AbiBJWqv (ORCPT ); Thu, 10 Feb 2022 17:46:51 -0500 Received: from mail-pf1-f181.google.com (mail-pf1-f181.google.com [209.85.210.181]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7A4B95F50 for ; Thu, 10 Feb 2022 14:46:51 -0800 (PST) Received: by mail-pf1-f181.google.com with SMTP id 9so10013075pfx.12 for ; Thu, 10 Feb 2022 14:46:51 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=RgQwPopRpAUyEmh976fnIQ6dzxN1Tud/GGLGVAJWV2c=; b=Uqq3w+e8hTcIEMC8JVPGRq3FU96fnIsPQTgu0EYbc/Dwn7hb3d15yJYTuvuxUMYvB4 PS3P/G4a5GZ2LRSPdDOpU777bWkuU4HIf+E+WraOz9Q/+tPtMEMd4DS8raSIbCoZPgBC bgvT6fSz2JSTd8o+fHyxGWQQYnO/n0nQcdwmdVr3f0nr+6odt4SVoYR1cdnz4glbbnFy rRu2MgfrrcVppBeF2Eclx1PfEQmTYZzyeWXzw4y4KyQHGHiNegJ5AQtjqk3yLCeDcRAa xoqTP0yF57KF3XFZzpaD15ZQuiIAB5I5dg24DivALcccSOQYBLDQ5M46Ua2LTdvQ8ZDr 8l8Q== X-Gm-Message-State: AOAM5304yJ/sM9Du9kwlpNyfeZKXQHjmoBvpmuvVfv8YLCt38NjEuAVV 9u244JcVr/2XRGqW+eGRcBBnrjgWbfVtlvcoTsM= X-Google-Smtp-Source: ABdhPJwsBvD1UanpGXfjFha2BJy2za3r3d8XLyG2Q7VkjP86TLpwdmCoZOQBgDDUEZVUZtEI3Ze6mgsiBHFKzCRu3q4= X-Received: by 2002:a63:571f:: with SMTP id l31mr4172364pgb.181.1644533210753; Thu, 10 Feb 2022 14:46:50 -0800 (PST) MIME-Version: 1.0 References: <6c51324a6623b62c385ec707a773c21375596584.1644465706.git.gitgitgadget@gmail.com> In-Reply-To: <6c51324a6623b62c385ec707a773c21375596584.1644465706.git.gitgitgadget@gmail.com> From: Eric Sunshine Date: Thu, 10 Feb 2022 17:46:39 -0500 Message-ID: Subject: Re: [PATCH v4 3/3] cat-file: add --batch-command mode To: John Cai via GitGitGadget Cc: Git List , Taylor Blau , Phillip Wood , =?UTF-8?B?w4Z2YXIgQXJuZmrDtnLDsCBCamFybWFzb24=?= , Eric Wong , Bagas Sanjaya , Junio C Hamano , Jonathan Tan , John Cai Content-Type: text/plain; charset="UTF-8" Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org On Wed, Feb 9, 2022 at 11:01 PM John Cai via GitGitGadget wrote: > Add a new flag --batch-command that accepts commands and arguments > from stdin, similar to git-update-ref --stdin. Some comments not offered by other reviewers... > This patch adds the basic structure for adding command which can be > extended in the future to add more commands. It also adds the following > two commands (on top of the flush command): > > contents LF > info LF > > The contents command takes an argument and prints out the object > contents. > > The info command takes a argument and prints out the object > metadata. > > These can be used in the following way with --buffer: > > info LF > contents LF > contents LF > info LF > flush > info LF > flush s/// for consistency with the usage information earlier in the commit message, and since Git is migrating to SHA-256, and to avoid reviewer confusion as occurred earlier[1]. Also: s/flush$/flush LF/ > When used without --buffer: > > info LF > contents LF > contents LF > info LF > info LF Ditto. [1]: https://lore.kernel.org/git/CAPig+cTeqhOYTu9WBiY=LnZtt35hAp3Qa5RduC2yLut6p01_1w@mail.gmail.com/ > diff --git a/Documentation/git-cat-file.txt b/Documentation/git-cat-file.txt > @@ -96,6 +96,30 @@ OPTIONS > +--batch-command:: > + Enter a command mode that reads commands and arguments from stdin. > + May not be combined with any other options or arguments except > + `--textconv` or `--filters`, in which case the input lines also need to > + specify the path, separated by whitespace. See the section > + `BATCH OUTPUT` below for details. The SYNOPSIS probably needs an update too. Perhaps say something like "Recognized commands include:" here before enumerating the commands themselves? > +-- > +contents :: > + Print object contents for object reference . This corresponds to > + the output of --batch. s//``/ s/--batch/`--batch`/ > +info :: > + Print object info for object reference . This corresponds to the > + output of --batch-check. s//``/ s/--batch/`--batch-check`/ > +flush:: > + Used in --buffer mode to execute all preceding commands that were issued > + since the beginning or since the last flush was issued. When --buffer > + is used, no output will come until flush is issued. When --buffer is not > + used, commands are flushed each time without issuing `flush`. > +-- s/--buffer/`--buffer`/g s/flush/`flush`/g This says that it's legal to use `--buffer` along with `--batch-command`, but the description of `--batch-command` itself just above says that it can be combined only with `--textconv` or `--filters`. (I see you copied the problematic text from the other batch options, so they also are guilty of not mentioning `--buffer`. This series doesn't necessarily need to fix those existing documentation problems, but perhaps don't repeat the problem with newly-added text?) The description of the `--buffer` option probably also needs to be updated to mention the new `--batch-command` option, and there may be other places in this document which should mention it, as well. > diff --git a/builtin/cat-file.c b/builtin/cat-file.c > +static const struct parse_cmd { > + const char *prefix; > + parse_cmd_fn_t fn; > + unsigned takes_args; > +} commands[] = { > + { "contents", parse_cmd_contents, 1}, > + { "info", parse_cmd_info, 1}, > +}; > + > +static void batch_objects_command(struct batch_options *opt, > + struct strbuf *output, > + struct expand_data *data) > +{ > + while (!strbuf_getline(&input, stdin)) { > + if (!input.len) > + die(_("empty command in input")); > + if (isspace(*input.buf)) > + die(_("whitespace before command: '%s'"), input.buf); > + > + if (skip_prefix(input.buf, "flush", &cmd_end)) { > + if (!opt->buffer_output) > + die(_("flush is only for --buffer mode")); > + if (*cmd_end) > + die(_("flush takes no arguments")); > + > + dispatch_calls(opt, output, data, queued_cmd, nr); > + nr = 0; > + continue; > + } > + > + for (i = 0; i < ARRAY_SIZE(commands); i++) { > + if (!skip_prefix(input.buf, commands[i].prefix, &cmd_end)) > + continue; This prefix-matching is going to incorrectly match non-commands such as "contentsify " and "information " and then treat them as "contents fy " and "info mation ", respectively, with undesirable results. You need to verify that there is a space or NUL at `*cmd_end` before treating `input.buf` as an actual command. > + cmd = &commands[i]; > + if (cmd->takes_args) What happens if `cmd->takes_arg` is true but no arguments follow the command? Should that be diagnosed as an error? > + p = cmd_end + 1; This unconditional +1 is going to make `p` point beyond the NUL character if the input is just a bare command, such as "contents" or "info" without any space or any argument... > + break; > + } > + > + if (!cmd) > + die(_("unknown command: '%s'"), input.buf); > + > + if (!opt->buffer_output) { > + cmd->fn(opt, p, output, data); > + continue; > + } > + > + ALLOC_GROW(queued_cmd, nr + 1, alloc); > + call.fn = cmd->fn; > + call.line = xstrdup_or_null(p); ... which means that xstrdup_or_null() will be copying whatever random garbage is in memory following the bare command. > + queued_cmd[nr++] = call; > + } > + > + if (opt->buffer_output && nr) > + dispatch_calls(opt, output, data, queued_cmd, nr); > + > + free(queued_cmd); > + strbuf_release(&input); > +}