m4b / m4b/goblin

Goblin ergonomics

Open
#58 18 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

question
Dominant language
Rust
Stars
1.5k
Forks
202
PR merge metrics
No merged PRs in 30d

Description

This deeply annoys me:

```rust
let peek = goblin::peek(&mut fd)?;
if let Hint::Unknown(magic) = peek {
println!("unknown magic: {:#x}", magic)
} else {
let bytes = { let mut v = Vec::new(); fd.read_to_end(&mut v)?; v };
match peek {
Hint::Elf(_) => {
```

I think there's an architectural problem and an ergonomics problem here.

1. We don't want to read the entire binary/file if it doesn't even have proper magic; this is what peek is for
2. If we pass the peek test, we want to read the file in full, and pass these bytes into goblin, and receive the enum variant
3. We don't want to even think about the `Unknown` variant - we already peeked to make sure the magic is good! - everything else is just a parse error _for that respective file format_

So, what I want is my cake and eat it too:

I want the peek to ensure the magic is correct, and route to the correct binary parser, and return this result, without the `Unknown` variant, without temporarily allocations (or the full fd read is passed through).

@philipc @endeav0r you seem to be using `goblin::Object` as clients, does this bother you?

Anyone who happens to be watching/reading this, I'm open to proposals how to fix this make it nicer.

Afaics, being flexible w.r.t. the bytes + reading is going to be tricky; first thing that comes to my mind is some kind of closure style or an inout, like:

```rust
// has no Unknown variant, and is also totally me just randomly typing stuff
let object: Option> = Object::parse_and_fill(fd, &mut bytes);
```

This would be a breaking change, but I think its important to get right sooner rather than later

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing goblin::peek and goblin::Object, including the Object::parse_and_fill proposal. Trace how peeking, full reads, and format parsing currently interact. Done means agreeing on an API that routes by magic, avoids the Unknown variant and unnecessary temporary allocation, and preserves format-specific parse errors.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
reverse-engineering
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.