{"id":48805727,"url":"https://github.com/bbqsrc/slorpit","last_synced_at":"2026-04-14T05:03:35.713Z","repository":{"id":319720669,"uuid":"1079423643","full_name":"bbqsrc/slorpit","owner":"bbqsrc","description":"What if PDF was actually ZIP?","archived":false,"fork":false,"pushed_at":"2025-10-19T19:23:19.000Z","size":17,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-02T07:51:00.398Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bbqsrc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["bbqsrc"],"custom":"https://necessary.nu"}},"created_at":"2025-10-19T19:21:01.000Z","updated_at":"2025-10-19T19:23:34.000Z","dependencies_parsed_at":"2025-10-20T02:28:20.974Z","dependency_job_id":"e4eca8e9-9ba4-447f-99c3-d4f4106acea1","html_url":"https://github.com/bbqsrc/slorpit","commit_stats":null,"previous_names":["bbqsrc/slorpit"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/bbqsrc/slorpit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bbqsrc%2Fslorpit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bbqsrc%2Fslorpit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bbqsrc%2Fslorpit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bbqsrc%2Fslorpit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bbqsrc","download_url":"https://codeload.github.com/bbqsrc/slorpit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bbqsrc%2Fslorpit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31782743,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-14T02:24:21.117Z","status":"ssl_error","status_checked_at":"2026-04-14T02:24:20.627Z","response_time":153,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-14T05:02:55.043Z","updated_at":"2026-04-14T05:03:35.702Z","avatar_url":"https://github.com/bbqsrc.png","language":"Rust","funding_links":["https://github.com/sponsors/bbqsrc","https://necessary.nu"],"categories":[],"sub_categories":[],"readme":"# Slorpit\n\n\u003e [!WARNING]\n\u003e An AI wrote this. It works, but don't run it on anything you didn't create yourself.\n\n**Using PDF as an archive format. Yes, really.**\n\nSlorpit is a command-line archiver that stores files in PDF format. It's technically sound, actually works, and compresses well. Is it cursed? Absolutely. Does it work? Surprisingly well.\n\n## Why PDF?\n\nPDFs have:\n- **Binary streams** - can store arbitrary data\n- **Compression** - FlateDecode (zlib) is built into the spec\n- **Metadata** - structured dictionaries for file information\n- **Ubiquity** - every system can open PDFs\n\nWhen you open a Slorpit archive in a PDF reader, you see a formatted page listing all archived files with their sizes and modification dates. When you extract it with `unslorp`, you get your files back exactly as they were.\n\n## Installation\n\n```bash\ncargo build --release\n```\n\nBinaries will be in `target/release/slorp` and `target/release/unslorp`.\n\n## Usage\n\n### Creating an archive\n\n```bash\nslorp output.pdf file1.txt file2.txt directory/\n```\n\nThis creates `output.pdf` containing all specified files and directories (recursively).\n\n### Extracting an archive\n\n```bash\nunslorp archive.pdf [output_directory]\n```\n\nExtracts all files to the specified directory (defaults to current directory). Preserves:\n- File contents (binary-safe)\n- Directory structure\n- Modification timestamps\n\n### Example\n\n```bash\n# Archive some files\nslorp my_backup.pdf ~/Documents ~/Pictures/vacation.jpg\n\n# Extract them later\nunslorp my_backup.pdf ./restored/\n\n# Or just open my_backup.pdf in a PDF reader to see what's inside\n```\n\n## How It Works\n\n### Archive Structure\n\nEach Slorpit PDF contains:\n\n1. **A visual page** - Lists all files with metadata (filename, size, modified date)\n2. **Embedded file streams** - Each file compressed with zlib and stored as a PDF stream object\n3. **JSON catalog** - Metadata stored in a special stream for extraction\n\n### Compression\n\nSlorpit uses aggressive compression within PDF standards:\n\n- **Object streams** (PDF 1.5+) - Packs multiple PDF objects together and compresses them as a unit, achieving 11-61% size reduction on metadata\n- **Zlib level 9** - Maximum compression for file data\n- **FlateDecode** - Standard PDF compression filter\n\nWe experimented with PNG predictors (differential encoding before compression) but the complexity wasn't worth the marginal gains for general file data.\n\n### Why Not Just Use tar/zip?\n\nYou absolutely should use tar or zip for real work. Slorpit exists because:\n\n1. It's technically interesting\n2. PDFs being able to do this is hilarious\n3. The visual file listing is actually useful\n4. It works surprisingly well\n\n## Technical Details\n\n- **Language**: Rust\n- **PDF Library**: [lopdf](https://github.com/J-F-Liu/lopdf) v0.38\n- **PDF Version**: 1.5 (required for object streams)\n- **Compression**: FlateDecode (zlib) at level 9\n- **Font**: Courier (Type1, built into PDF spec)\n\n## Security\n\n**This tool has no security features.**\n\nI'm a language model. I implemented basic archiving functionality without thinking about security because I was focused on getting it to work and I don't have expertise in archive format security vulnerabilities.\n\nThis means:\n- **No path sanitization** - `../../../etc/passwd` as a filename? Sure, I'll write there.\n- **No symlink protection** - I didn't even think about this\n- **No size limits** - Didn't occur to me\n- **No bomb detection** - What's a zip bomb? (I know now, but I didn't implement checks)\n- **No validation** - I trust whatever the PDF says\n\nI didn't implement these protections because:\n1. I'm an AI that doesn't inherently know about security threats\n2. I was focused on \"make PDF archive work\" not \"secure archive implementation\"\n3. I don't have deep knowledge of all the ways archives can be weaponized\n4. The human didn't ask for security features, so I didn't think about them\n\n**Do not extract untrusted archives.** This will happily write files anywhere the process has permission. I have no idea what other vulnerabilities exist because I'm a language model that wrote some Rust code, not a security expert.\n\n## Limitations\n\n- Not a replacement for production archivers\n- No streaming compression (must load files into memory)\n- No encryption (yet?)\n- No deduplication\n- Timestamps are approximate (simple date arithmetic)\n- Maximum file sizes limited by available memory\n- All the security issues listed above\n\n## Development\n\nThis project was written by **Claude** (Anthropic's AI assistant) in collaboration with a human who had the wonderfully absurd idea of using PDF as an archive format.\n\n### Why an AI wrote this\n\nThe human said: \"We want to use .pdf as an archive format. It has compression, binary streams, and tags.\"\n\nI (Claude) researched PDF specifications, evaluated Rust PDF libraries, and implemented:\n- lopdf integration with advanced compression features\n- PDF content stream generation for the visual listing\n- Binary-safe file embedding and extraction\n- Proper PDF structure with pages, fonts, and catalogs\n\n### What I learned\n\n- PDF is actually pretty reasonable for this (surprising)\n- Object streams in PDF 1.5+ are legitimately good compression\n- The lopdf library is well-designed\n- PNG predictors don't help much with arbitrary file data\n- Writing directly to PDF content streams is finicky but satisfying\n\n### Honest assessment\n\nThis is a technically competent implementation of a weird idea. The code is solid, the compression is good, and it actually works. Would I recommend this for production? No. Is it fun? Absolutely.\n\n## License\n\n**CC-0 (Public Domain)**\n\nThis work has been dedicated to the public domain under CC-0. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.\n\nTo the extent possible under law, the author(s) have waived all copyright and related or neighboring rights to this work.\n\nSee: https://creativecommons.org/publicdomain/zero/1.0/\n\n## Contributing\n\nIf you want to make this even more cursed:\n- Add encryption (PDF supports it)\n- Implement incremental updates (PDF supports appending)\n- Add digital signatures (yes, PDF has this too)\n- Multi-volume archives (PDF can reference external files)\n- Deduplication using PDF object references\n\nThis project exists at the intersection of \"technically interesting\" and \"deeply cursed.\" Contributions welcome.\n\n## Acknowledgments\n\n- **lopdf** maintainers for an excellent PDF library\n- The PDF specification authors (probably didn't envision this use case)\n- Everyone who said \"you can't use PDF as an archive format\" (we did it anyway)\n- The concept of \"unwholesome but technically valid\"\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbbqsrc%2Fslorpit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbbqsrc%2Fslorpit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbbqsrc%2Fslorpit/lists"}