The merged mp4 export is named '<Monitor> <start> to <end>.mp4', so it contains
spaces and colons, and download.php emitted it as a bare unquoted filename=
parameter. That is not a valid RFC 6266 token, so browsers that parse
Content-Disposition strictly find no filename and fall back to naming the
download after the last path segment of the URL - index.php. Firefox is lenient
and accepted it, which is why the report was Chrome-on-Windows only.
Add contentDispositionAttachment(), which emits a quoted ASCII filename with the
Windows-illegal characters folded to '_', plus the untouched name as RFC 5987
filename* whenever that folding changed anything, so unicode monitor names still
arrive intact.
Also in that path:
- urlencode the file and export_root query parameters; a monitor name containing
'&' or '+' would otherwise split or mis-decode the download URL. Read them back
in export.js with URLSearchParams so the link text shows the decoded name.
- drop the stray ';' from Content-Length, which made the value unparseable.
- silence the shutdown unlink()s, whose warnings would be appended to the body
of a download that had already started.
- log $this->filenamePath, not an undefined local, on the unreadable-file path.
Tests: tests/php/test_download_content_disposition.php, 12 assertions, all pass.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nr76CednxtDt2nPuq6WrbL
Closed: #4767
Also, an error when downloading an incomplete event has been fixed. This error occurred when $Event->DefaultVideo() started storing the value 'index.m3u8' instead of the incomplete event filename.
FilterTerm.php:
- Use intval() on AlarmedZoneId value in SQL subquery to prevent
injection via crafted filter val
report_event_audit.php, montagereview.php:
- Cast $selected_monitor_ids through array_map('intval') before
interpolating into SQL IN clause (values come from $_REQUEST)
download_functions.php:
- Replace manual single-quoting with escapeshellarg() for merged
file name in ffmpeg, tar, and zip commands (monitor names can
contain shell metacharacters including single quotes)
- Same fix for export list file path
export_functions.php:
- Use escapeshellarg() on source and destination paths in cp -as
commands during event export
functions.php:
- Validate column keys in getFormChanges() against /^[a-zA-Z0-9_]+$/
to prevent SQL injection via crafted array keys from $_REQUEST
- Use dbEscape() and intval() for image/document MIME type and size
fields instead of raw string interpolation
- Replace escapeshellcmd() with escapeshellarg() in deletePath()
rm -rf command
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>