Ah, I was confused while reading the other one ;-)
Will queue this one instead. Thanks.
Show 167 quoted lines
> -- >8 --
> Subject: pack-protocol: clarify LF-handling in PKT-LINE()
>
> The spec is very inconsistent about which PKT-LINE() parts
> of the grammar include a LF. On top of that, the code is not
> consistent, either (e.g., send-pack does not put newlines
> into the ref-update commands it sends).
>
> Let's make explicit the long-standing expectation that we
> generally expect pkt-lines to end in a newline, but that
> receivers should be lenient. This makes the spec consistent,
> and matches what git already does (though it does not always
> fulfill the SHOULD).
>
> We do make an exception for the push-cert, where the
> receiving code is currently a bit pickier. This is a
> reasonable way to be, as the data needs to be byte-for-byte
> compatible with what was signed. We _could_ make up some
> rules about signing a canonicalized version including
> newlines, but that would require a code change, and is out
> of scope for this patch.
>
> Signed-off-by: Jeff King <peff@peff.net>
> ---
> Documentation/technical/pack-protocol.txt | 46 ++++++++++++++++-------------
> Documentation/technical/protocol-common.txt | 5 +++-
> 2 files changed, 30 insertions(+), 21 deletions(-)
>
> diff --git a/Documentation/technical/pack-protocol.txt b/Documentation/technical/pack-protocol.txt
> index 4064fc7..c6977bb 100644
> --- a/Documentation/technical/pack-protocol.txt
> +++ b/Documentation/technical/pack-protocol.txt
> @@ -14,6 +14,14 @@ data. The protocol functions to have a server tell a client what is
> currently on the server, then for the two to negotiate the smallest amount
> of data to send in order to fully update one or the other.
>
> +pkt-line Format
> +---------------
> +
> +The descriptions below build on the pkt-line format described in
> +protocol-common.txt. When the grammar indicate `PKT-LINE(...)`, unless
> +otherwise noted the usual pkt-line LF rules apply: the sender SHOULD
> +include a LF, but the receiver MUST NOT complain if it is not present.
> +
> Transports
> ----------
> There are three transports over which the packfile protocol is
> @@ -143,9 +151,6 @@ with the object name that each reference currently points to.
> 003fe92df48743b7bc7d26bcaabfddde0a1e20cae47c refs/tags/v1.0^{}
> 0000
>
> -Server SHOULD terminate each non-flush line using LF ("\n") terminator;
> -client MUST NOT complain if there is no terminator.
> -
> The returned response is a pkt-line stream describing each ref and
> its current value. The stream MUST be sorted by name according to
> the C locale ordering.
> @@ -165,15 +170,15 @@ MUST peel the ref if it's an annotated tag.
> flush-pkt
>
> no-refs = PKT-LINE(zero-id SP "capabilities^{}"
> - NUL capability-list LF)
> + NUL capability-list)
>
> list-of-refs = first-ref *other-ref
> first-ref = PKT-LINE(obj-id SP refname
> - NUL capability-list LF)
> + NUL capability-list)
>
> other-ref = PKT-LINE(other-tip / other-peeled)
> - other-tip = obj-id SP refname LF
> - other-peeled = obj-id SP refname "^{}" LF
> + other-tip = obj-id SP refname
> + other-peeled = obj-id SP refname "^{}"
>
> shallow = PKT-LINE("shallow" SP obj-id)
>
> @@ -216,8 +221,8 @@ out of what the server said it could do with the first 'want' line.
>
> depth-request = PKT-LINE("deepen" SP depth)
>
> - first-want = PKT-LINE("want" SP obj-id SP capability-list LF)
> - additional-want = PKT-LINE("want" SP obj-id LF)
> + first-want = PKT-LINE("want" SP obj-id SP capability-list)
> + additional-want = PKT-LINE("want" SP obj-id)
>
> depth = 1*DIGIT
> ----
> @@ -284,7 +289,7 @@ so that there is always a block of 32 "in-flight on the wire" at a time.
> compute-end
>
> have-list = *have-line
> - have-line = PKT-LINE("have" SP obj-id LF)
> + have-line = PKT-LINE("have" SP obj-id)
> compute-end = flush-pkt / PKT-LINE("done")
> ----
>
> @@ -348,10 +353,10 @@ Then the server will start sending its packfile data.
>
> ----
> server-response = *ack_multi ack / nak
> - ack_multi = PKT-LINE("ACK" SP obj-id ack_status LF)
> + ack_multi = PKT-LINE("ACK" SP obj-id ack_status)
> ack_status = "continue" / "common" / "ready"
> - ack = PKT-LINE("ACK SP obj-id LF)
> - nak = PKT-LINE("NAK" LF)
> + ack = PKT-LINE("ACK" SP obj-id)
> + nak = PKT-LINE("NAK")
> ----
>
> A simple clone may look like this (with no 'have' lines):
> @@ -467,10 +472,10 @@ references.
> ----
> update-request = *shallow ( command-list | push-cert ) [packfile]
>
> - shallow = PKT-LINE("shallow" SP obj-id LF)
> + shallow = PKT-LINE("shallow" SP obj-id)
>
> - command-list = PKT-LINE(command NUL capability-list LF)
> - *PKT-LINE(command LF)
> + command-list = PKT-LINE(command NUL capability-list)
> + *PKT-LINE(command)
> flush-pkt
>
> command = create / delete / update
> @@ -521,7 +526,8 @@ Push Certificate
>
> A push certificate begins with a set of header lines. After the
> header and an empty line, the protocol commands follow, one per
> -line.
> +line. Note that the the trailing LF in push-cert PKT-LINEs is _not_
> +optional; it must be present.
>
> Currently, the following header fields are defined:
>
> @@ -560,12 +566,12 @@ update was successful, or 'ng [refname] [error]' if the update was not.
> 1*(command-status)
> flush-pkt
>
> - unpack-status = PKT-LINE("unpack" SP unpack-result LF)
> + unpack-status = PKT-LINE("unpack" SP unpack-result)
> unpack-result = "ok" / error-msg
>
> command-status = command-ok / command-fail
> - command-ok = PKT-LINE("ok" SP refname LF)
> - command-fail = PKT-LINE("ng" SP refname SP error-msg LF)
> + command-ok = PKT-LINE("ok" SP refname)
> + command-fail = PKT-LINE("ng" SP refname SP error-msg)
>
> error-msg = 1*(OCTECT) ; where not "ok"
> ----
> diff --git a/Documentation/technical/protocol-common.txt b/Documentation/technical/protocol-common.txt
> index 889985f..bf30167 100644
> --- a/Documentation/technical/protocol-common.txt
> +++ b/Documentation/technical/protocol-common.txt
> @@ -62,7 +62,10 @@ A pkt-line MAY contain binary data, so implementors MUST ensure
> pkt-line parsing/formatting routines are 8-bit clean.
>
> A non-binary line SHOULD BE terminated by an LF, which if present
> -MUST be included in the total length.
> +MUST be included in the total length. Receivers MUST treat pkt-lines
> +with non-binary data the same whether or not they contain the trailing
> +LF (stripping the LF if present, and not complaining when it is
> +missing).
>
> The maximum length of a pkt-line's data component is 65520 bytes.
> Implementations MUST NOT send pkt-line whose length exceeds 65524