The Options field was a single line text input, so a list of options had to
be typed as one comma separated run. Make it a textarea, sized to the number
of entries it already holds, so each option can go on its own line.
Nothing needs to parse this: both consumers already take a set of separator
characters, they were just never given the newlines.
av_dict_parse_string() (Ffmpeg) and Split() (Libvlc) both skip empty
entries, so a blank line, crlf, or a trailing newline all work, and comma
separated values keep working unchanged.
The separator set is a named constant rather than a literal at each call
site so the tests exercise the value the cameras actually pass - with a
literal they would keep passing if a call site were reverted. Verified by
setting it back to "," which fails both test cases.
RemoteCameraHTTP::GetResponse()'s non-PCRE parser (the default when built
without PCRE) copied server-controlled HTTP response header values into
fixed-size static buffers with unbounded strcpy()/sprintf(), and with
strncpy() bounds derived from delimiters rather than the buffer size. A
malicious or MitM'd HTTP camera could overflow status_mesg[256],
connection_type[32], content_type[32] and content_boundary[64],
corrupting adjacent parser state (content_length, content_boundary_len)
for DoS and secondary heap corruption.
Add zm_strncpy(): a bounded copy that always null-terminates (strcpy
overflows; strncpy skips the terminator on truncation) and optionally
caps to a field length n for delimiter-bounded values whose source is
not null-terminated at the field end. Route every header copy in
GetResponse() through it. The content_boundary "--" prefix is written
separately and content_boundary_len is taken from strlen() of the
resulting (now bounded) string so the compare length at the multipart
subheader match stays correct.
The two subcontent-header strncpy() calls were already bounded to
sizeof-1 with an explicit terminator and are left as-is.
Adds a tests/zm_utils.cpp self-check covering fit, truncation,
delimiter-limit, delimiter-over-buffer, and empty-source cases.
Refs GHSA-93j4-rcp9-9jx6.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>