Skip to content

zanlucathiago/ole2-reader

Repository files navigation

ole2-reader

Zero-dependency reader for OLE2 / Compound File Binary (CFB) containers — the storage format inside legacy Microsoft files (.xls, .doc, .ppt, .msg, …).
List the storages and streams, and read any stream's raw bytes. Node and the browser.

npm version npm downloads CI status zero dependencies MIT license

Runs in Node and the browser — it only needs Uint8Array / DataView. Zero runtime dependencies, dual ESM/CJS, fully typed, and published to npm with provenance.

npm install ole2-reader
# or: pnpm add ole2-reader / yarn add ole2-reader

Contents

Why this exists

Lots of legacy Microsoft formats — .xls, .doc, .ppt, .msg, .vsd, MSI — aren't single files; they're a tiny filesystem in a file, the OLE2 / Compound File Binary container. To read any of them you first have to walk that container and pull out its named streams.

The de-facto JS library for this, cfb, is a SheetJS package frozen on npm since 2022, and it pulls in extra dependencies. ole2-reader is a small, focused, actively maintained alternative for the common case: open a compound file and read its streams. No dependencies, MIT-licensed, and covered by npm audit / Dependabot like the rest of your tree.

It's also hardened against hostile input — it parses untrusted binary, so it's fuzz-tested to fail with a typed error rather than crash or run out of memory.

Usage

import { readFile } from "node:fs/promises";
import { openOle2 } from "ole2-reader";

const ole = openOle2(await readFile("report.xls"));

// What's inside?
for (const entry of ole.entries()) {
  console.log(entry.type, entry.name, entry.size);
  // "root"   "Root Entry" 0
  // "stream" "Workbook"   12345
}

// Pull a stream out by name — the raw bytes, ready for a format-specific parser.
const workbook = ole.readStream("Workbook");

In the browser (e.g. from a file <input>):

import { openOle2 } from "ole2-reader";

const ole = openOle2(await file.arrayBuffer());
const doc = ole.readStream("WordDocument"); // a .doc file's main stream

API

openOle2(data: ArrayBuffer | Uint8Array): Ole2File

Opens a compound file from its bytes. Throws Ole2Error if the bytes aren't a Compound File or are structurally corrupt.

Ole2File

interface Ole2File {
  entries(): Ole2Entry[]; // all storages and streams, in directory order
  readStream(name: string): Uint8Array | undefined; // a stream's bytes, or undefined
  hasStream(name: string): boolean;
}

interface Ole2Entry {
  name: string;
  type: "root" | "storage" | "stream";
  size: number; // stream length in bytes; 0 for storages
}

Both regular and mini streams are handled transparently — readStream returns the reassembled bytes regardless of how the stream is stored.

What is a Compound File?

A Compound File (OLE2, "Structured Storage", [MS-CFB]) is a hierarchical container: storages are like folders and streams are like files, all packed into one binary file via a FAT-style sector table. It's what Office 97–2003 used before the .xlsx/.docx ZIP formats. ole2-reader gives you the container layer; decoding a specific stream (BIFF for .xls, the Word document stream for .doc, MAPI properties for .msg) is the job of a format reader on top — for example xls-reader.

Limitations

  • Read-only, and it reads the container only — it does not interpret the format stored inside a stream.
  • Encrypted / password-protected compound files are not supported.

Contributing

Bug reports, sample files, and PRs are very welcome — see CONTRIBUTING.md and the Code of Conduct. To report a security issue, see the Security Policy.

License

MIT © Thiago Zanluca

About

Zero-dependency OLE2 / Compound File Binary (CFB) reader for Node and the browser — read the streams inside legacy Microsoft files (.xls, .doc, .ppt, .msg).

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors