Hi Gary,
On Thu, 22 Oct 2026 23:30:26 -0700, Gary E. Miller wrote:
> I'm all for preventing a buffer overflow, but why are you remiving
> the stuff before the # in the path?
It doesn't remove it: what goes in front of the device is the same as
before. The old code copied all of dev.path in, then cut it at its
first '#' ("Avoid accumulating multiple device names"); the patch
inserts the same thing, the strcspn(dev.path, "#") bytes before any
'#', then a '#'. The source path before the '#' stays, and so does
the device after it.
I ran the same packets through the JSON passthrough driver built from
master (d627ef33d) and with the patch, source gpsd://example.com:2947:
TPV, "device":"/dev/ttyS0"
master: "device":"gpsd://example.com:2947#/dev/ttyS0"
patched: "device":"gpsd://example.com:2947#/dev/ttyS0"
DEVICE, "path":"/dev/ttyS0"
master: "path":"gpsd://example.com:2947#/dev/ttyS0"
patched: "path":"gpsd://example.com:2947#/dev/ttyS0"
TPV, source gpsd://example.com:2947#/dev/ttyUSB0
master: "device":"gpsd://example.com:2947#/dev/ttyS0"
patched: "device":"gpsd://example.com:2947#/dev/ttyS0"
TPV already holding "gpsd://example.com:2947#/dev/ttyS0"
master and patched: passed unchanged
DEVICES, paths /dev/ttyS0 and /dev/ttyS1
master: "gpsd://example.com:2947#/dev/ttyS0", "/dev/ttyS1"
patched: "gpsd://example.com:2947#/dev/ttyS0",
"gpsd://example.com:2947#/dev/ttyS1"
The DEVICES reply is the one difference: master stops scanning at the
packet's old length, so the second path, pushed past it by the first
insert, keeps its bare name. (This packet is short; in a full DEVICES
reply it takes a few devices behind a longer source name.)
> Also you said:
>
> " A JSON packet can be nearly as long as outbuffer,"
>
> #define GPS_JSON_RESPONSE_MAX 10240
> char buffer[GPS_JSON_RESPONSE_MAX * 2];
>
> Comments?
Fair point, that sentence left out where such a packet comes from.
GPS_JSON_RESPONSE_MAX bounds what a gpsd sends, and that buffer is
libgps's read buffer (struct privdata_t, include/gps.h).
path_rewrite() works on gpsd's own lexer.outbuffer, INOUTSTASHSZ =
MAX_PACKET_LENGTH * 2 + 1 = 18433 bytes (include/gpsd.h), and nothing
on the reading side holds a gpsd:// source to GPS_JSON_RESPONSE_MAX:
the JSON lexer in packet.c passes on any object that fits outbuffer.
A TPV padded to each length, through packet_parse() on master:
10240 bytes: JSON_PACKET, outbuflen 10240
18000 bytes: JSON_PACKET, outbuflen 18000
18432 bytes: JSON_PACKET, outbuflen 18432
So a well-behaved gpsd never comes near the overflow. It takes a
source that sends more than a gpsd would, or anything on the path
between the two, since a gpsd:// link is plain TCP: a packet a little
short of 18432 bytes, with a "device" value near its end.
I'll send a v2 in this thread that says this in the commit message.
The code is the same as v1.
Thanks,
Ana