I can't get this working with LevelDB #57
-
I'm trying to parse the JSON from LevelDB, I'm pretty sure it's lz-string compressed, it comes from Electron. There are only a few characters that are 2 or 3 bytes long, it looks like UTF-16-BE to me, but it doesn't parse correctly using UTF-16-BE or LE, and I found this blog that says chrome uses lz-string. I included use std::{fs::File, io::Write};
use anyhow::bail;
use lz_str::IntoWideIter;
use rusty_leveldb::{Options, DB};
fn main() -> anyhow::Result<()> {
println!("Hello, world!");
let mut db = DB::open(
"leveldb",
Options {
create_if_missing: false,
paranoid_checks: true,
..Default::default()
},
)?;
let key = "_file://\0\u{1}persist:root";
let Some(mut value) = db.get(key.as_bytes()) else {
bail!("None - Failed to get value from key: '{key}'");
};
println!("Value Length: {}", value.len());
if let Ok(mut file) = File::create("value.txt") {
file.write_all(&value)?;
}
if value.len() & 1 == 1 {
println!("Length not even, removing the last element");
value.pop();
}
let buffer = value
.chunks(2)
.map(|slice| {
// The slice is always guaranteed to be 2 here.
// We check to see if the length is a multiple of 2 earlier.
u16::from_be_bytes(slice.try_into().unwrap())
})
.collect::<Vec<u16>>()
.into_wide_iter();
if let Some(decompressed_value) = lz_str::decompress_internal(buffer, 8) {
println!("1: Decompressed Value Length: {}", decompressed_value.len());
}
if let Some(decompressed_value) = lz_str::decompress_from_uint8_array(&value) {
println!("2: Decompressed Value Length: {}", decompressed_value.len());
}
println!("Goodbye, world!");
Ok(())
}
Here's my test project with the LevelDB database included |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 4 replies
-
Hey, thanks for the interest. First of all, I don't believe any of this is an issue with this library, but I'll try to help out the best I can.
You've misunderstood the blog post. The blog says that instead of saving raw strings to localstorage, some websites compress them with lz-string before saving. This is a technique implemented by the websites themselves, not Chrome; the same compression with lz-string would also be performed with Firefox. Its been a while since I've messed around with Chrome's localstorage; last I remember, they didn't use any compression. However, I just did a quick check, and they now seem to use Snappy compression, which is the standard compression for leveldb databases. The library you are trying to use actually has support for it built in: https://docs.rs/rusty-leveldb/1.0.8/rusty_leveldb/enum.CompressionType.html.
From my quick testing, your database is probably corrupted. Hope it wasn't too important. When iterating keys I see sane results, but retrieving a single key gives the strange UTF-16 like behavior. The likely culprit is your leveldb library: https://docs.rs/rusty-leveldb/1.0.8/rusty_leveldb/struct.Options.html#structfield.compression_type. Kind of strange they made a release like that, I would think there are many cases where you can't remember what compression you used to create the database. As for the parts relating to this library, I don't want to make
I want to force the user to decode into an Also, I think you've misunderstood the binary data example so it should be reworked a bit. I think its too easy to misunderstand and misuse in its current state as a go-to for forcibly trying to decode binary with lz-string. I should update it to remove references to "padding" the data since that is usually the wrong answer and instead focus on the capabilities of I'll also put large warning signs next to the internal functions, 99.99% of users shouldn't need to touch them. Overall, I think the main issues WRT Hope all of this helps, let me know if you have any questions. |
Beta Was this translation helpful? Give feedback.
Hey, thanks for the interest. First of all, I don't believe any of this is an issue with this library, but I'll try to help out the best I can.
You've misunderstood the blog post. The blog says that instead of saving raw strings to localstorage, some websites compress them with lz-string before saving. This is a technique implemented by the websites themselves, not Chrome; the same compression with lz-string would also be performed with Firefox.
Its been a while since I've messed around with Chrome's localstorage; last I remember, they didn't use any compression. However, I just did a quick check, and they now seem to use Snappy compres…