Hey, I'm Tanvir 馃憢
I enjoy breaking things, fixing them, and occasionally figuring out why they broke in the first place.
Technologies
Go 路 Python 路 Docker 路 PostgreSQL 路 Redis 路 Linux
Still learning, still experimenting, still breaking things.
| Project | Merged PRs | Focus |
|---|---|---|
| ORAS | 10 | OCI, security, concurrency, filesystem safety, CLI, CI |
| oras-go | 1 | Credential handling, API correctness |
| Vinix | 2 | AArch64/QEMU, musl/Linux |
| go-criu | 1 | Documentation / code quality |
| PR | Severity | Title | Area |
|---|---|---|---|
| #2222 | 馃敶 HIGH | Limit manifest config fetch size | Security / resource exhaustion |
| #2218 | 馃敶 HIGH | Detect credentials in multiple JSON values | Security / credential redaction |
| #2194 | 馃敶 HIGH | Clean up partial pull output on failure | Filesystem safety |
| #2190 | 馃敶 HIGH | pull leaves corrupted files after digest failure |
Filesystem safety (issue report) |
| #2225 | 馃煛 MEDIUM | Restore --output - --pretty with bounded buffering |
CLI / compatibility |
| #2183 | 馃煛 MEDIUM | Fix concurrency in Tagged |
Go concurrency |
| #2177 | 馃煛 MEDIUM | Only infer platform from OCI image configs | OCI semantics |
| #1482 | 馃煛 MEDIUM | Make credential lookup case-insensitive | API correctness |
| #2203 | 馃煝 LOW | Correct manifest fetch format error | CLI correctness |
| #2214 | 馃煝 LOW | Fix coverage report generation | Dev tooling |
| #2207 | 馃煝 LOW | Update golang.org/x/crypto |
Dependency maintenance |
| #2199 | 馃煝 LOW | Replace action-publish with Snapcraft CLI |
CI / release infra |
| #223 | 馃煝 LOW | Fix AArch64 QEMU mktemp template |
Build environment |
| #221 | 馃煝 LOW | Disable backtrace for musl desktop | Runtime config |
| #278 | 鈿狹AINTENANCE | Fix typos and grammar | Code quality |
oras manifest fetch-config used to buffer an entire config blob in memory with no size cap. I reproduced this against a local registry serving a 1 GiB+ crafted blob: RSS ballooned to around 2 GiB before the fetch even reached digest verification, which made it a remotely triggerable, unauthenticated DoS. The fix adds a 4 MiB limit and rejects oversized configs before downloading them. The PR went through several review rounds (10 commits, plus a Codecov coverage fix), and I proactively added validation to reject --pretty combined with --output -. Two smaller output-handling edge cases (special file paths and file permission mode) surfaced after merge and are being tracked in follow-up issues/PRs.
Credential redaction in debug tracing stopped scanning after the first JSON value, so credentials appearing later in a response could leak into debug output. I fixed the detection logic to keep scanning across every JSON value, and added regression tests covering credentials that appear after the first value.
A failed multi-platform oras pull could leave partially written files behind after an output-path collision. Since manifests are pulled concurrently, which file survived depended on timing. I implemented pullCleanup, which tracks output paths before writing, distinguishes pre-existing files from ones created by the current run, and removes only what the failed operation created (never pre-existing files). The maintainer review asked for two changes, cleaning up newly created parent dirs and routing cleanup warnings through the logger, and both were implemented. Coverage includes cleanup/path-tracking/duplicate-file tests plus a CLI-level reproduction against a local registry.
#2190: pull leaves corrupted files after digest failure (issue report, not a PR)
I reported and reproduced a case where oras pull correctly detected a digest mismatch but left the corrupted blob on disk. To isolate it, I built a deterministic repro using a local HTTP proxy that corrupted blob responses in transit, which pinned the bug to the failed-verification path rather than the artifact itself. Fixed upstream. It's the same underlying class of bug as #2194: failed operations should not leave partial state behind.
The security fix in #2222 rejected oras manifest fetch-config --output - --pretty, even though the combination was previously supported. The issue was that pretty-printing requires the config to be buffered in memory.
I restored the previous behavior by routing the --output - --pretty case through the existing size-limited fetch path instead of the streaming path. Configs larger than the 4 MiB limit are still rejected, while --output - without --pretty continues to stream directly.
Added command-level regression coverage for pretty output and an oversized-config test proving that the 4 MiB memory limit from #2222 remains enforced.
Tagged.Tags() sorted its internal slice while holding only a read lock and returned the internal slice directly. That meant a data race under concurrent access, and callers could also mutate shared state. The fix sorts under an exclusive lock and returns a cloned slice. Verified with concurrent-access tests, slice-isolation tests, and the Go race detector.
ORAS inferred platform metadata from any config blob whose JSON happened to contain os/architecture fields, regardless of the actual media type. So non-image artifacts with similarly shaped config could end up with incorrect platform metadata. I restricted inference to configs with media type application/vnd.oci.image.config.v1+json. Reproduced with a non-image artifact and added regression tests for both valid and invalid config types.
Credential lookup failed whenever hostname casing differed between storing and retrieving (localhost:5020 vs LOCALHOST:5020). I made credential-address matching case-insensitive across all the relevant API functions, while preserving path case-sensitivity and giving exact matches precedence. Verified with targeted and full-suite tests, the race detector, and an independent reproduction through the public Go API.
- #2203:
manifest fetchreported the wrong--formatvalue in an error message (it usedopts.Templateinstead ofopts.FormatFlag). Fixed the error path and added regression coverage. - #2214:
make covhtmltried to open a coverage report that was never generated. Fixed the target to generate it first. - #2207: Routine dependency bump for
golang.org/x/crypto. - #2199: Replaced the unmaintained
canonical/action-publishGitHub Action with direct Snapcraft CLI usage in the Snap release workflow, preserving credentials and release-channel behavior. - Vinix #223: Fixed a missing
Xstemplate in an AArch64 QEMUmktempcall. - Vinix #221: Disabled backtrace support for the musl desktop build where it didn't apply.
