* Fix instructor file browser dotfile downloads
* Handle symlinked roots in instructor file downloads
A question beneath a symlinked directory passed the file browser's path
checks but failed downloads because the resolved file was compared with
an unresolved context root. Resolve the course, context root, and excluded
directories before checking containment, allowing exclusions to be absent.
Consolidate the download tests around distinct behaviors instead of
repeating every filename and permission check in every context. Preserve
coverage for dotfiles, Viewer permissions, previews, ranges, and error
headers, and cover symlinked context roots and excluded directories.
Co-Authored-By: Codex <noreply@openai.com>
* Prevent symlink races in instructor file downloads
A file could be replaced with a symlink after path validation, causing
Express to download a file outside the allowed directory or inside .git.
Keep an open descriptor and serve through it so renames cannot redirect
the download, preserving Express's range and preview handling.
Open without following symlinks and recheck the descriptor's path on Linux
to catch parent-directory replacement. Add focused regressions for
replacement before opening and before serving the response.
Co-Authored-By: Codex <noreply@openai.com>
* Return clean errors for instructor file downloads
Convert path-validation failures to plain 404 responses so invalid
requests do not render filesystem paths from AugmentedError details.
Clear file metadata before rendering download errors, while restoring
any cache restrictions supplied by upstream middleware.
Update the existing HTTP cases to require 404s and clean error headers.
Exercise range errors both with and without the app's no-cache policy.
Co-Authored-By: Codex <noreply@openai.com>
---------
Co-authored-by: austinbillings-pl <austin@prairielearn.com>
Co-authored-by: Codex <noreply@openai.com>
PrairieLearn is an online problem-driven learning system for creating homeworks and tests. It allows questions to be written using arbitrary HTML, JavaScript, and Python, thus enabling very powerful questions that can randomize and autograde themselves, and can access client- and server-side libraries to handle tasks such as graphical drawing, symbolic algebra, and student code compilation and execution.