Log read is inlined based on a size that a symlinked log file does not describe
- Dominant language
- TypeScript
- Stars
- 145
- Forks
- 9
- Avg merge
- 20m
- Merged PRs (30d)
- 1
Description
`readLog` chooses between an inline read and a stream using the size `listFiles` reports for the log file (src/ci/runners/sandbox.ts). That size is not evidence about how much the read will pull in.
The container builds its listing with
```
find -not -path -printf '%p\t%y\t%s\t%TY-%Tm-%TdT%TH:%TM:%TS\t%m\n'
```
`%y` and `%s` do not follow symlinks, so a link is reported as type `l` with the size of the link itself, which the SDK surfaces as `type: 'symlink'`. Running that exact command against a symlink pointing at a 2,000,000 byte file gives `type=l size=98`. 98 is not greater than `INLINE_LOG_BYTES`, so the guard takes the inline branch, and the read follows the link and returns 2,000,000 bytes. The container's own inline cap is 32 MiB, so nothing else stops it.
The step executes commands from the repository under test, and those commands can replace `/tmp/ci-step.out` before the process exits. What the read returns becomes part of the value the `step.do` callback returns in src/pipeline/ci-workflow.ts, which Workflows persists with a 1 MB limit, and it reaches `CiRunnerResult.logs`. So a build can put the contents of a file it chooses into the step's persisted output, and can push that output past the size limit `INLINE_LOG_BYTES` exists to respect.
A missing listing entry had the same shape for a different reason: `sizes.get(FILE) ?? 0` treats "not listed" as zero, which also reads inline. I could not find a way to reach that one in practice, since the files exist before the listing and a deleted log makes `readFile` throw, but it fails in the same direction.
The fix I would suggest is to require the entry to prove the read is bounded rather than to assume it: present, `type === 'file'`, and within the limit, streaming otherwise, which is the branch that already exists for oversized output. PR to follow.
Note for whoever picks this up: it is in the same file as #7, though not the same function or lines.
Contributor guide
Research direction
Read readLog in src/ci/runners/sandbox.ts and compare its listing-based size guard with the existing streaming branch; the exact find command in the issue shows how symlinks are reported. Trace the returned value through the step.do callback in src/pipeline/ci-workflow.ts, and consider the work done when symlinked or unlisted logs no longer bypass the intended inline limit.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend, ci-cd
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100