├── Makefile ├── lz4jsoncat.1 ├── README ├── lz4jsoncat.c └── lz4jsonpack.c /Makefile: -------------------------------------------------------------------------------- 1 | PKG_CONFIG ?= pkg-config 2 | CFLAGS := -g -O2 -Wall 3 | LDLIBS := $(shell $(PKG_CONFIG) --cflags --libs liblz4) 4 | 5 | all: lz4jsoncat lz4jsonpack 6 | 7 | lz4jsoncat: lz4jsoncat.c 8 | lz4jsonpack: lz4jsonpack.c 9 | 10 | clean: 11 | rm -f lz4jsoncat 12 | -------------------------------------------------------------------------------- /lz4jsoncat.1: -------------------------------------------------------------------------------- 1 | .TH lz4jsoncat 1 2018-12-25 2 | .SH NAME 3 | lz4jsoncat \- decompress tool for mozilla lz4json format 4 | .SH SYNOPSIS 5 | .B lz4jsoncat 6 | .I somefile.mozlz4 7 | > 8 | .I somefile.json 9 | .SH DESCRIPTION 10 | .B lz4jsoncat 11 | can unpack lz4json files as generated by Firefox's bookmark backups and 12 | session restore. The data is dumped to stdout. 13 | .SH CAVEATS 14 | The input file must be mmappable \- so you can't use a pipe here. 15 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | A little utility to unpack lz4json files as generated by Firefox's bookmark backups and session restore. 2 | This is a different format from what the normal lz4 utility expects. 3 | The data is dumped to stdout. 4 | 5 | Requires liblz4 (Debian package liblz4-dev, Fedora package lz4-devel) to be installed. 6 | 7 | lz4jsoncat ~/.mozilla/.../bookmarkbackups/bookmarks-2014-12-27_151_0UCIWGB4x3hhQXpuSMs5WQ==.jsonlz4 8 | 9 | On some non Linux systems the lz libraries might be installed into directories 10 | that are not searched by the linker by default. If that's the case 11 | please override the CFLAGS and LDFLAGS on the command line 12 | 13 | e.g. if they are in /usr/local: 14 | 15 | make CFLAGS="-I/usr/local/include -O2" LDFLAGS="-L/usr/local/lib" 16 | 17 | -Andi Kleen 18 | -------------------------------------------------------------------------------- /lz4jsoncat.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Dump mozilla style lz4json files. 3 | * 4 | * Copyright (c) 2014 Intel Corporation 5 | * Author: Andi Kleen 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that: (1) source code distributions 9 | * retain the above copyright notice and this paragraph in its entirety, (2) 10 | * distributions including binary code include the above copyright notice and 11 | * this paragraph in its entirety in the documentation or other materials 12 | * provided with the distribution 13 | * 14 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 15 | * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 16 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 17 | */ 18 | 19 | /* File format reference: 20 | https://dxr.mozilla.org/mozilla-central/source/toolkit/components/lz4/lz4.js 21 | */ 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #ifndef __APPLE__ 32 | #include 33 | #else 34 | #define htole32(x) x /* assume apple targets are little endian */ 35 | #endif 36 | 37 | #include "lz4.h" 38 | 39 | int main(int ac, char **av) 40 | { 41 | while (*++av) { 42 | int fd = open(*av, O_RDONLY); 43 | if (fd < 0) { 44 | perror(*av); 45 | continue; 46 | } 47 | struct stat st; 48 | if (fstat(fd, &st) < 0) { 49 | perror(*av); 50 | exit(1); 51 | } 52 | if (st.st_size < 12) { 53 | fprintf(stderr, "%s: file too short\n", *av); 54 | exit(1); 55 | } 56 | 57 | char *map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); 58 | if (map == (char *)-1) { 59 | perror(*av); 60 | exit(1); 61 | } 62 | if (memcmp(map, "mozLz40", 8)) { 63 | fprintf(stderr, "%s: not a mozLZ4a file\n", *av); 64 | exit(1); 65 | } 66 | size_t outsz = htole32(*(uint32_t *) (map + 8)); 67 | char *out = malloc(outsz); 68 | if (!out) { 69 | fprintf(stderr, "Cannot allocate memory\n"); 70 | exit(1); 71 | } 72 | if (LZ4_decompress_safe_partial(map + 12, out, st.st_size - 12, outsz, outsz) < 0) { 73 | fprintf(stderr, "%s: decompression error\n", *av); 74 | exit(1); 75 | } 76 | ssize_t decsz = write(1, out, outsz); 77 | if (decsz < 0 || decsz != outsz) { 78 | if (decsz >= 0) 79 | errno = EIO; 80 | perror("write"); 81 | exit(1); 82 | } 83 | free(out); 84 | munmap(map, st.st_size); 85 | close(fd); 86 | 87 | } 88 | return 0; 89 | } 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /lz4jsonpack.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Compress mozilla style lz4json files. 3 | * 4 | * Copyright (c) 2014 Intel Corporation 5 | * Copyright (c) 2025 SUSE 6 | * Author: Andi Kleen 7 | * Author: Jiri Slaby 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that: (1) source code distributions 11 | * retain the above copyright notice and this paragraph in its entirety, (2) 12 | * distributions including binary code include the above copyright notice and 13 | * this paragraph in its entirety in the documentation or other materials 14 | * provided with the distribution 15 | * 16 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 17 | * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 18 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19 | */ 20 | 21 | /* File format reference: 22 | https://dxr.mozilla.org/mozilla-central/source/toolkit/components/lz4/lz4.js 23 | */ 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #ifndef __APPLE__ 34 | #include 35 | #else 36 | #define htole32(x) x /* assume apple targets are little endian */ 37 | #endif 38 | 39 | #include "lz4.h" 40 | 41 | int main(int, char **av) 42 | { 43 | while (*++av) { 44 | int fd = open(*av, O_RDONLY); 45 | if (fd < 0) { 46 | perror(*av); 47 | continue; 48 | } 49 | char outfile[strlen(*av) + strlen("lz4") + 1]; 50 | strcpy(outfile, *av); 51 | strcat(outfile, "lz4"); 52 | int fd2 = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0644); 53 | if (fd2 < 0) { 54 | perror(outfile); 55 | exit(1); 56 | } 57 | struct stat st; 58 | if (fstat(fd, &st) < 0) { 59 | perror(*av); 60 | exit(1); 61 | } 62 | if (st.st_size > LZ4_MAX_INPUT_SIZE) { 63 | exit(1); 64 | } 65 | char *map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); 66 | if (map == (char *)-1) { 67 | perror(*av); 68 | exit(1); 69 | } 70 | size_t outsz = LZ4_compressBound(st.st_size); 71 | char *out = malloc(outsz); 72 | if (!out) { 73 | fprintf(stderr, "Cannot allocate memory\n"); 74 | exit(1); 75 | } 76 | int compsize = LZ4_compress_default(map, out, st.st_size, outsz); 77 | if (compsize < 0) { 78 | fprintf(stderr, "%s: compression error\n", *av); 79 | exit(1); 80 | } 81 | 82 | ssize_t decsz = write(fd2, "mozLz40", 8); 83 | if (decsz < 8) { 84 | if (decsz >= 0) 85 | errno = EIO; 86 | perror("write"); 87 | exit(1); 88 | } 89 | uint32_t outszLE = htole32(st.st_size); 90 | decsz = write(fd2, &outszLE, 4); 91 | if (decsz < 4) { 92 | if (decsz >= 0) 93 | errno = EIO; 94 | perror("write"); 95 | exit(1); 96 | } 97 | decsz = write(fd2, out, compsize); 98 | if (decsz < 0 || decsz != compsize) { 99 | if (decsz >= 0) 100 | errno = EIO; 101 | perror("write"); 102 | exit(1); 103 | } 104 | free(out); 105 | munmap(map, st.st_size); 106 | close(fd2); 107 | close(fd); 108 | } 109 | 110 | return 0; 111 | } 112 | 113 | --------------------------------------------------------------------------------