Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/media-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Rules:
| Extension | `.mp4` only |
| Type | regular file after `lstat` + `realpath` |
| Symlink / reparse | rejected |
| Size | `1 byte … 500 MiB` |
| Size | `1 byte … 800 MiB` |
| Container | first ISO-BMFF box size sane and type `ftyp` |
| Companion image | required |

Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ export const SCHEMA_ID = "beauticode.background/v1" as const;
// Images are embedded into one CDP Runtime.evaluate payload. Keep validation
// and injection limits identical so an accepted import is always publishable.
export const MAX_IMAGE_BYTES = 18 * 1024 * 1024;
export const MAX_VIDEO_BYTES = 500 * 1024 * 1024;
export const MAX_VIDEO_BYTES = 800 * 1024 * 1024;

/**
* Max raw media bytes embedded as a data: URL inside one CDP evaluate.
Expand Down
18 changes: 18 additions & 0 deletions packages/core/test/media-validation.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import test from "node:test";
import { MAX_VIDEO_BYTES } from "../dist/constants.js";
import {
assertSafeBasename,
isMp4Container,
Expand Down Expand Up @@ -77,6 +78,23 @@ test("validateVideoFile enforces extension, size, ftyp, no symlink", async () =>
}
});

test("validateVideoFile defaults to an 800 MiB limit", async () => {
assert.equal(MAX_VIDEO_BYTES, 800 * 1024 * 1024);

const root = await fs.mkdtemp(path.join(os.tmpdir(), "bc-video-limit-"));
try {
const oversized = path.join(root, "oversized.mp4");
await fs.writeFile(oversized, mp4Fixture());
await fs.truncate(oversized, MAX_VIDEO_BYTES + 1);
await assert.rejects(
() => validateVideoFile(oversized),
/no larger than 838860800 bytes/,
);
Comment on lines +84 to +92

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

1. Huge truncate in test 🐞 Bug ☼ Reliability

The new regression test expands a temp MP4 to MAX_VIDEO_BYTES+1 (838,860,801 bytes) via fs.truncate,
which assumes the filesystem makes this enlargement sparse/cheap. On environments that
allocate/reserve blocks for such truncation, this can consume ~800 MiB and make the test suite slow
or fail due to disk/quota limits.
Agent Prompt
### Issue description
`packages/core/test/media-validation.test.js` creates an oversized MP4 by truncating it to `MAX_VIDEO_BYTES + 1` (an 800 MiB+ logical file). This test relies on filesystem behavior that may not be consistent across CI runners (sparse vs. fully allocated truncation), which can lead to slow/flaky tests or disk/quota failures.

### Issue Context
`validateVideoFile()` rejects oversized inputs based on `stat.size` before hashing/reading the file, so the regression can be tested without requiring a huge logical file.

### Fix Focus Areas
- packages/core/test/media-validation.test.js[81-96]

### Suggested fix approach
- Keep the configuration assertion (`MAX_VIDEO_BYTES === 800 * 1024 * 1024`).
- For the oversized rejection behavior, prefer a small file and pass a small `maxBytes` override to `validateVideoFile(..., { maxBytes: <small> })` to exercise the same rejection branch and error formatting without creating an 800 MiB+ file.
- If you must specifically test the *default* path, consider refactoring validation to allow injecting a `stat` provider in tests (so size can be simulated) rather than creating very large files.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

} finally {
await fs.rm(root, { recursive: true, force: true });
}
});

test("validateImageFile checks magic bytes", async () => {
const root = await fs.mkdtemp(path.join(os.tmpdir(), "bc-img-"));
try {
Expand Down
Loading