mirror of
https://github.com/git/git.git
synced 2026-08-05 15:41:00 +00:00
sub-process: add a gentle status read
subprocess_read_status() reads "status=<key>" packets up to a flush with
packet_read_line_gently(), which is gentle only about EOF. A malformed
length header still dies inside pkt-line, and an empty packet is
indistinguishable from the flush that ends the section. A protocol
violation in a status section therefore either kills the whole command
or silently truncates the section. That posture fits the filter
protocol's callers, which treat their process as required
infrastructure; the diff process consult added later in this series
treats its process as optional, and any protocol error must degrade to
the builtin diff rather than abort the command.
Add subprocess_read_status_gently(): the same status loop, reading
through packet_read_with_status() with the gentle options, returning
-1 on a truncated or malformed packet and on an empty packet where a
status line or the terminating flush belongs. subprocess_read_status()
and its callers are unchanged.
The handshake has its gentle counterpart in 061a68e443 (sub-process:
use gentle handshake to avoid die() on startup failure, 2026-06-01),
which turned truncated handshake reads into error returns for every
caller. This series' base includes that commit, so a process that
dies during the handshake feeds the same non-fatal fallback as a
status failure here, and an optional diff process degrades to the
builtin diff on either kind of protocol error.
Signed-off-by: Michael Montalbo <mmontalbo@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
03e089b091
commit
1a2aca2be4
@@ -49,6 +49,30 @@ int subprocess_read_status(int fd, struct strbuf *status)
|
||||
return (len < 0) ? len : 0;
|
||||
}
|
||||
|
||||
int subprocess_read_status_gently(int fd, struct strbuf *status)
|
||||
{
|
||||
for (;;) {
|
||||
int pktlen = -1;
|
||||
enum packet_read_status rs;
|
||||
const char *value;
|
||||
|
||||
rs = packet_read_with_status(fd, NULL, NULL, packet_buffer,
|
||||
sizeof(packet_buffer), &pktlen,
|
||||
PACKET_READ_CHOMP_NEWLINE |
|
||||
PACKET_READ_GENTLE_ON_EOF |
|
||||
PACKET_READ_GENTLE_ON_READ_ERROR);
|
||||
if (rs == PACKET_READ_FLUSH)
|
||||
return 0;
|
||||
if (rs != PACKET_READ_NORMAL || !pktlen)
|
||||
return -1;
|
||||
if (skip_prefix(packet_buffer, "status=", &value)) {
|
||||
/* the last "status=<foo>" line wins */
|
||||
strbuf_reset(status);
|
||||
strbuf_addstr(status, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void subprocess_stop_command(struct subprocess_entry *entry)
|
||||
{
|
||||
if (!entry)
|
||||
|
||||
@@ -101,4 +101,14 @@ int subprocess_handshake(struct subprocess_entry *entry,
|
||||
|
||||
int subprocess_read_status(int fd, struct strbuf *status);
|
||||
|
||||
/*
|
||||
* Like subprocess_read_status(), but a malformed status section fails
|
||||
* instead of dying: a truncated or malformed packet, and an empty
|
||||
* packet where a status line or the terminating flush belongs, return
|
||||
* -1 and leave the stream unusable. subprocess_read_status() cannot
|
||||
* tell an empty packet from the flush that ends the section, and dies
|
||||
* on a framing error inside packet_read_line_gently().
|
||||
*/
|
||||
int subprocess_read_status_gently(int fd, struct strbuf *status);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user