Single-pass replace can leave overlapping matches re-formed (e.g.
<scrip<script ...></script>t...></script>). Iterate until stable so
the dev-server injector never serves a half-stripped script tag.
Input is the package's own on-disk HTML, so this is defense-in-depth
rather than a live exploit, but it clears the CodeQL alert.
Closes CodeQL #108.
Transitive via mermaid@11.14.0 — only consumer in this package — uses
uuid v4 (random IDs for diagrams), unaffected by the buffer-bounds bug
in v3/v5/v6, but Dependabot still flags any uuid <14.0.0. Pinned via
overrides so future mermaid bumps stay on the patched line.
Closes Dependabot #88.
vite-plugin-singlefile@2.0.2 declares a peer dependency on
vite ^5.4.11 || ^6.0.0, but socratiq/ pins vite ^8.0.10. npm refused
to resolve the dep tree, so 'npm ci' failed in the SocratiQ Bundle
Drift workflow on every PR that touched socratiq/package-lock.json
— including dependabot bumps for unrelated transitive packages
(see #1538 markdown-it, #1539 solid-js).
vite-plugin-singlefile@2.3.0+ supports vite 5/6/7/8, so a one-line
bump unblocks 'npm ci', which lets the bundle drift check actually
run again.
Also commits the regenerated production bundle and stylesheet to
satisfy the drift check itself.
Align public README and site messaging around the curriculum components, adoption paths, and current early-release status so newcomers can move from reading to building, deployment, practice, and teaching.
The new bundle-drift CI guard caught a real inconsistency left over
from #1394: package.json declares "dompurify": "^3.4.0" (added as
part of the security-fix commits), but package-lock.json still
pinned dompurify@2.5.8. As a result:
- npm ci refused to install from the lock (exit code EUSAGE), which
broke both the drift guard and anyone running `npm ci` locally.
- The committed bundle.js was built against the old dompurify, so
the rendered book was silently serving the 2.5.x code instead of
the 3.4.x the package.json declared.
This commit runs `npm install` (lock: 2.5.8 -> 3.4.1) and `npm run
build:vite` to regenerate the bundle from sources that actually
match the declared dependency set. Vite reports 2976 modules
transformed, bundle size 6.6 MB unchanged.
The drift guard should now pass on this branch, validating that the
guard works end-to-end on its introduction PR.
The package had been carrying the legacy name "injectchat" inherited
from an earlier prototype. Rename to the scoped name matching the
rest of the mlsysbook ecosystem, add a real description, and mark the
package private so it cannot be accidentally published to npm.
No behavioural change — the package is consumed only via the prebuilt
bundle at book/quarto/tools/scripts/socratiQ/bundle.js; nothing in
the repository imports it by name.
The file-watcher and auto-refresh plugins in vite.config.prod.mjs were
no-ops in production:
- file-watcher called fs.watch() inside buildStart() with the comment
"The build will be triggered automatically by Vite's dev server" —
but there is no dev server in a production build. It only emitted
logs and held an active fs watcher handle.
- auto-refresh registered a vite:beforeUpdate hook inside
configureServer(server) — configureServer is dev-only and is
silently ignored by Vite during production builds.
Dev-time HMR is already handled by Vite's built-in mechanism plus the
server.watch polling configured in vite.config.dev.mjs; these prod
plugins added no behaviour.
Also drops the now-unused 'watch' and 'unlinkSync' imports from 'fs'.
- Delete Finder-duplicate artifacts: "webpack.config copy 2.js",
"testQuiz copy.html".
- Delete pre-rewrite orphan
create_quiz_button_grp_original_with_good_reinialization.js.js
(double .js.js extension, zero importers).
- Delete legacy webpack.config.js: not referenced by any npm script or
tooling; the widget has fully migrated to Vite's single-file bundle.
- Delete vite.config.coop.mjs and vite.dev.config.mjs: not referenced
by package.json scripts; COOP/COEP headers are already applied by
the active dev and prod configs.
No functional change; all referenced sources and configs are untouched.
bbe85444 deleted both 'copy_download copy.js' (orphan) and
'copy_download.js' (live import). index.js line 122 imports
initializeAllMessageButtons from this file — restore it.
- showQuizStats.js: add escapeHtml() and sanitize fileName/reason/details
before injecting into verificationModal.innerHTML (XSS: DOM text reinterpreted as HTML)
- injectQuizBtn.js: replace quizTitle string interpolation in innerHTML with
DOM construction (textContent) to prevent XSS (DOM text reinterpreted as HTML)
- highlight_menu.js: fix 'classList.contains === "hidden"' type error —
was comparing function reference to string; now correctly called as
classList.contains("hidden") (comparison between inconvertible types)
- index.html + indexHtml.js: rename malformed space-containing id attributes
'Show answers' -> 'show-answers' and 'Show chain of thought' -> 'show-chain-of-thought'
- settings.js: update three matching string keys to kebab-case to stay in sync
with renamed HTML ids (coordinated rename, no functionality change)
- demo_reference_rendering.html: add safeParseReferences() fallback wrapper,
replace direct parseReferences() call which was undefined in this context
- test_reference_renderer.js: remove parseReferences import (not exported),
rewrite testReferenceParsing() to use processReferences() with HTML output assertions
- XSS: validate URL (same-origin, http/https only) before window.location.href
in streamdown_markdown.js and reference_renderer.js
- XSS: replace tooltip.innerHTML with DOM construction in streamdown_markdown.js
- XSS: sanitize mermaid SVG with DOMPurify in renderMermaid() and at call site
- XSS: sanitize customContainerHtml, mathDiv, and preview.innerHTML with DOMPurify
- XSS: replace button.innerHTML with textContent for question buttons
- XSS: add escapeHtml() for mermaid error messages interpolated into innerHTML
- Add DOMPurify ^3.4.0 to dependencies
- Remove duplicate diagramId assignments in highlight.js and markdown.js
- Remove unused percentLineIndex variable in markdown.js and streamdown_markdown.js
- Remove useless targetElement assignment in streamdown_markdown.js
- chart.js: replace /auto import with tree-shaken named imports in spaced-repetition-stats.js
- Add _comments to package.json documenting bundle size analysis per dependency