Python Pickle Parser for JavaScript
The `pickleparser` library provides a pure JavaScript and TypeScript implementation for parsing Python's pickle serialization format. It supports all pickle protocol versions from 0 to 5, allowing developers to deserialize Python objects directly within Node.js environments and web browsers. Currently stable at version 0.2.1, the project appears to have an active release cadence, frequently adding support for new opcodes and refining its API. A key differentiator is its full protocol support and its utility for converting pickle data to JSON, including a bundled `pickletojson` CLI tool, without relying on Python runtimes. It offers `ParserOptions` for customizing the unpickling process, making it flexible for various use cases.
Common errors
-
TypeError: Do not know how to serialize a BigInt
cause Attempting to `JSON.stringify()` an object parsed from a pickle file that contains `BigInt` values without a custom `replacer` function.fixModify your `JSON.stringify()` call to include a `replacer` function that converts `BigInt` values to strings or another serializable type: `JSON.stringify(obj, (key, value) => typeof value === 'bigint' ? value.toString() : value)`. -
Error: Input must be a Buffer or Uint8Array
cause The `parser.parse()` method was invoked with an incorrect data type (e.g., a plain string or an object) instead of a `Buffer` (Node.js) or `Uint8Array` (browser) containing the raw binary pickle data.fixEnsure the input data is read in binary format and converted to the correct type. For Node.js, use `fs.readFileSync(filePath, null)` to get a `Buffer`. For browsers, use a `FileReader` to read as `ArrayBuffer` and convert to `Uint8Array`. -
ReferenceError: pickleparser is not defined
cause This error typically occurs when trying to use `new pickleparser.Parser()` in a browser environment where the `pickleparser` global script was not correctly loaded, or in a Node.js environment where this global access pattern is invalid.fixIn browser applications, verify the library's `<script>` tag is correctly placed and loaded. In Node.js or module-based environments, use explicit ESM `import { Parser } from 'pickleparser';` or CJS `const { Parser } = require('pickleparser');`.
Warnings
- breaking The public API underwent a significant refactor for improved extensibility in version `0.1.0-beta.0`. Users upgrading from pre-`0.1.0-beta.0` versions must adjust their import statements and parsing logic.
- gotcha Python pickle files can contain large integers that, when parsed, are represented as JavaScript `BigInt` primitives. Standard `JSON.stringify()` cannot directly serialize `BigInt` values and will throw a `TypeError` if not handled.
- breaking Earlier versions (prior to `0.0.2-alpha.2`) contained an issue with insecure string handling in pickle protocol 0. This security vulnerability was addressed in `0.0.2-alpha.2`.
- gotcha Parsing untrusted Python pickle data is a significant security risk. In Python, unpickling arbitrary data can lead to arbitrary code execution due to the nature of the pickle protocol. While `pickleparser` is a JavaScript implementation and does not execute Python code, the reconstructed JavaScript objects could still contain malicious data structures (e.g., specific string values, function names) that, if processed without sanitization in the consuming JavaScript application, could lead to security vulnerabilities.
Install
-
npm install pickleparser -
yarn add pickleparser -
pnpm add pickleparser
Imports
- Parser
const { Parser } = require('pickleparser');import { Parser } from 'pickleparser'; - ParserOptions
import { ParserOptions } from 'pickleparser';import type { ParserOptions } from 'pickleparser'; - pickleparser (global)
import { pickleparser } from 'pickleparser';const parser = new pickleparser.Parser();
Quickstart
import fs from 'node:fs/promises';
import path from 'node:path';
import { Parser } from 'pickleparser';
async function unpickleFile(filePath: string) {
try {
// Read the pickle file as raw binary data (Buffer in Node.js)
const pklData = await fs.readFile(filePath, null);
const buffer = Buffer.from(pklData);
// Initialize the parser and parse the buffer
const parser = new Parser();
const obj = parser.parse(buffer);
// Log the parsed object. Use a replacer for JSON.stringify to handle BigInts.
console.log(JSON.stringify(obj, (key, value) =>
typeof value === 'bigint' ? value.toString() + 'n' : value
, 2));
} catch (error) {
console.error(`Error unpickling file ${filePath}:`, error);
}
}
// Example usage: Ensure a pickle file exists at the specified path.
// For demonstration, we use an environment variable or a default.
unpickleFile(process.env.PICKLE_FILE_PATH ?? './example.pkl');
// To create a dummy pickle file for testing (run this in Python):
// import pickle
// data = {'message': 'Hello from Python!', 'value': 12345678901234567890, 'items': [1, 2, 3]}
// with open('example.pkl', 'wb') as f:
// pickle.dump(data, f, pickle.HIGHEST_PROTOCOL)