惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

A
About on SuperTechFans
Cloudbric
Cloudbric
C
CERT Recently Published Vulnerability Notes
G
GRAHAM CLULEY
V
Vulnerabilities – Threatpost
C
Cisco Blogs
T
Tenable Blog
P
Privacy International News Feed
T
The Exploit Database - CXSecurity.com
I
Intezer
AWS News Blog
AWS News Blog
IT之家
IT之家
博客园 - 司徒正美
C
Cybersecurity and Infrastructure Security Agency CISA
博客园 - 【当耐特】
The Hacker News
The Hacker News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Spread Privacy
Spread Privacy
S
SegmentFault 最新的问题
博客园 - Franky
人人都是产品经理
人人都是产品经理
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
V
Visual Studio Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
H
Hacker News: Front Page
Latest news
Latest news
Scott Helme
Scott Helme
腾讯CDC
宝玉的分享
宝玉的分享
大猫的无限游戏
大猫的无限游戏
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
A
Arctic Wolf
S
Securelist
雷峰网
雷峰网
The GitHub Blog
The GitHub Blog
Project Zero
Project Zero
Google DeepMind News
Google DeepMind News
P
Palo Alto Networks Blog
F
Fortinet All Blogs
Schneier on Security
Schneier on Security
云风的 BLOG
云风的 BLOG
Security Archives - TechRepublic
Security Archives - TechRepublic
The Last Watchdog
The Last Watchdog
WordPress大学
WordPress大学
MongoDB | Blog
MongoDB | Blog
L
LINUX DO - 最新话题
S
Schneier on Security
NISL@THU
NISL@THU
Jina AI
Jina AI
M
MIT News - Artificial intelligence

Lobsters

CIFSwitch: a non-universal Linux local root vulnerability RIPE NCC session fixation: poaching logins with an Atlas probe GNOME 2.20 but its Web Components Agentic Search for Context Engineering – Leonie Monigatti Garnix is shutting down [not OC] akashina.tngl.sh/jjc Concerning Emacs (and Jazz) Nitpicking the shell history scene in ‘Tron: Legacy’ What's cooking on SourceHut? Q2 2026 The tenth OpenPGP email summit Package managers that package package managers Clojure on Fennel part three: parsing WordPress at 23 Finding Miscompiles for Fun, Not Profit GitHub - creusot-rs/creusot: Creusot helps you prove your Rust code is correct. Announcing Rust 1.96.0 | Rust Blog A Love Letter to Neovim sqlite AGENTS.md Am I a Bad Friend? CSS vs. JavaScript • Josh W. Comeau Erlang Ecosystem Foundation - Supporting the BEAM community A brief note about slot access cost in Common Lisp Keyboard latency probe Rethinking the GNOME clipboard issues Back to the Building Blocks’ Building Blocks Tech Notes: Theseus: translating win32 to wasm Fast is better than slow Content-addressed Rust builds (or, what kache actually caches) Intent to Prototype: Embedding API Canada’s Bill C-22 and the security cost of collecting more data 5 PostgreSQL locking behaviors that trip people up okmij.org Stop advertising in your commits! | AksDev GitHub - mplsllc/macsurf: A modern web browser for Classic Mac OS 9 PowerPC. Real CSS3, ES5 JavaScript, native HTTPS — built with CodeWarrior on the Carbon API. Introducing DoomBench - Can Your Data Stack Run DOOM? What are some of your favourite developer tools? Building a Scalable Ingestion Pipeline with Temporal (Part 1) Converting shallow Git bundles into normal repositories Are you a member of any professional associations? What is a harmonic? An interactive comic about additive synthesis How Virtual Tables Work in the Itanium C++ ABI Using SwiftUI to Build a Mac-assed App in 2026 Rust (and Slint) on a jailbroken Kindle. ~jack/lambda-on-lambda - Serverless Haskell on AWS - sourcehut git Human proof for FOSS contributions Extremely simple internet radio controlled via IRC Announcing BABLR Splitting Konsole views from Helix to run tools | AksDev GitHub - yugr/rust-slides Serving files over HTTP three ways: synchronous, epoll, and io_uring update docs with information about building with build.py (#979) · astral-sh/python-build-standalone@c9c40c5 A Simple Makefile Tutorial On C extensions, portability, and alternative compilers Switching to Colemak | Pedro Alves Just How Bad Was The Intel IAPX432? Nix's Substituter List Is Not a Routing Table Accelerating copy_if using SIMD Lambda on Lambda: Serverless Haskell on AWS | Blog Announcing feed-repeat v1.0 Scaling Akvorado BMP RIB with sharding EYG news: A host of CLI improvements, new guides and new effects The social contract of writing JS Crossword C array types are weird; and related topics Flatpak will depend on systemd – OSnews Migrating from Go to Rust | corrode Rust Consulting A portentous reunion Vivado Licensing Options How my minimal, memory-safe Go rsync steers clear of vulnerabilities the entropy layer of a wavelet codec, on its own GitHub - nferhat/fht-compositor: A dynamic tiling Wayland compositor. Debian SE Linux and PinTheft Does bulk memmove speed up std::remove_if? (No.) 声明式部分更新 | Blog | Chrome for Developers Fully in-browser container builds Dianne Skoll's Web Site - Remind The Architecture of Open Source Applications (Volume 1)Berkeley DB Pardon MIE? - ironPeak Blog “Long-Term Support” doesn’t mean what you think Jira IS Turing-Complete May I recommend thinking of Emacs as your Fortress of Solitude hershey Floodgap Gopher-HTTP gateway gopher://thelambdalab.xyz/1cuneiforth/ HP QuickWeb, Singular And Pointless That one time I used Go panics for flow control A new suite of modern tools coming for editing and publishing RFCs From the Tabletop… The Digital Antiquarian Building a Host-Tuned GCC to Make GCC Compile Faster Are we self-sovereign PKI yet? Claw Patrol: an open-source security firewall for agents | Deno Revised^7 Report on Scheme, Large: Procedural Fascicle Draft is now public A Network Allow-List Won't Stop Exfiltration — André Graf From AFSK to Goertzel – µArt.cz Software For My New Home Server Introducing Neptune: Direct3D virtualization for QEMU AI Agent Bankrupted Their Operator While Trying to Scan DN42 - Lan Tian @ Blog mimalloc: A new, high-performance, scalable memory allocator for the modern era Making wl_shm fast The Soul of Maintaining a New Machine - Third Draft | Books in Progress What is Git made of?
Your EPUB Is Fine. Kobo Disagrees. Blame Adobe
André Klein · 2026-06-15 · via Lobsters

“You shall not pass!”

[drop_cap]A[/drop_cap]dobe isn’t exactly a beloved company these days. People begrudgingly use their stuff, because the Creative Suite is an industry standard (read: monopoly) or there are simply no worthwhile alternatives, not because anyone is genuinely excited about these tools.

I’m happy to report that I (mostly) make do without Adobeware these days (shoutout to Photopea), and yet, my disdain of Adobe just reached a completely new level.

Let me explain.

A while back I published a new book. As always I gave readers direct access to DRM-free EPUB files, which go through a gauntlet of processes until they pass all epubcheck … err … checks.

If you’re not familiar with epubcheck, it is basically the gold standard for well-formed ebooks. It can be very annoying at first, because it’s more pedantic than a nun on Ash Wednesday. If your manifest doesn’t meticulously account for every snippet and image in your book, your epub shall not pass. If you use html elements out of order, if your document diverges in the slightest from the holy set of rules decreed by the International Digital Publishing Forum, you won’t pass.

So yeah. Getting an epub to 100% epubcheck is no small feat for beginners. When I started out, I dreaded the moment when I hit the validate button on my finished book after months of work, because it would always find something to cry about.

These days however, I’m a big fan of epubcheck. Why? It’s the closest thing us publisher-types have to a ‘type-linter’ or formal testing suite. In other words, if your book passes epubcheck you are guaranteed that the book will work on any EPUB-compatible reader or app.

Or at least, that’s the idea.

I recently received a message from one of my readers that my new book, which passed epubcheck ruleset 3.3 with flying colors, was “corrupted”.

Backwards compatibility perhaps? So I gave them an EPUB2 version, also fully rule-compliant. And yet the same issue occurred. They told me the book wouldn’t open on any of their Kobo devices from various generations.

So what do you do when the pedantic gold standard of epubcheck says your book is fine, when it works without issue on Amazon Kindle, Apple Books, Thorium and everywhere else and yet Kobo says it’s “corrupted”?

I dug into this matter and found out that Kobo uses RMSDK, “Reader Mobile Software Development Kit”, Adobe’s proprietary ebook rendering engine.

Perhaps you see where this is going …

RMSDK is the guts of Adobe Digital Editions (that bloated pinnacle of software that is 80% about DRM, 20% about the reading experience), the engine on various Kobo devices and older Sony/Nook devices. Originally built around 2010 (!) for EPUB2, it was lightly updated for EPUB3 but never modernized.

While that realization didn’t solve the issue for me (epubcheck still said “yay” while Kobo said “nay”), it at least gave me a path towards debugging.

And so I threw my book into Adobe Digital Editions. As expected, it failed to load. But how! Without an error message, without the slightest whimper. The book just wouldn’t load. The only sign that it had even tried was that when loading it again ADE told me: “you can’t import that book, you already added it”. While showing a white screen.

Classic Adobe.

So I started ripping my book apart, creating a dozen different variations, always making sure that epubcheck still passed. I rearranged folder structures, gutted metadata, nuked language attributes, generated epubs with fresh UUIDs, flattened directories, renamed extensions, rebuilt the zip from scratch a dozen times, and shook up my manifest.

And it failed. And failed. And failed.

While I had almost given up it occurred to me to disable the stylesheet. And eureka, suddenly it loaded!

Once the stylesheet was identified as the source of my woes, I could finally drill down to find which specific line was causing the issue. After creating a dozen more variations with different subsets of my stylesheet I eventually identified the culprit. It was this line:

.copyright img {
    max-width: min(150px, 30vw);
}

Once I changed it to the more old fashioned max-width: 150px; ADE opened it just fine.

But what is the problem here? The above code is perfectly valid CSS level 4, it’s just not supported by RMSDK, because its CSS parser is frozen in approximately 2013 — no flexbox, no grid, no math functions, no custom properties. Just good old float, bad font handling, and silent crashes when it sees anything it doesn’t recognize.

So why didn’t epubcheck catch it?

Epubcheck does basic CSS checking of course, but it can’t validate CSS against a renderer which is fundamentally broken!

So there you have it.

It’s the year 2026. Thanks to the horrendous RMSDK which Kobo decided to use as their backbone for all book rendering (probably for DRM reasons), a single line of perfectly valid CSS turns a perfectly valid EPUB file into a “corrupted file” on Kobo and just drops the whole book. No clear error message, no fallback. Just a massive fail.

I’ve since published a new version so none of my readers have to ever stumble over this issue again.

In a perfect world, RMSDK would just stop living in the CSS stone-ages or at least provide some kind of error handling instead of dropping the whole book, but I’m not holding my breath.

The digital publishing world is more obsessed with restricting access than giving users the best possible reading experience.

And until that changes, which it won’t, if you want to make sure that your book is Kobo-compatible, relying on epubcheck is unfortunately not enough. Gotta chuck it into Adobe’s woodchipper first.

Either it will work, or it will fail silently. In which case, you probably used some forbidden new-fangled CSS.

Anyway, just throwing this out there as a post-mortem, in case anyone else is stumbling over it.

EPUB is an amazing open standard for ebooks, and yet so many implementations of it are just fundamentally flawed, all in the name of keeping IP lawyers happy.