indygreg / apple-platform-rs

Rust crates supporting Apple platform development
565 stars 38 forks source link

Failed to fill whole buffer #90

Closed bonigarcia closed 10 months ago

bonigarcia commented 11 months ago

Hello,

I'm using apple-xar version 0.13.0 to try to unpack the following pkg file. For that, I implemented a small Rust program, as follows:

use std::error::Error;
use std::io::Cursor;
use apple_xar::reader::XarReader;

fn main() -> Result<(), Box<dyn Error>> {
    let source = r#"C:\Users\boni\Downloads\MicrosoftEdge-116.0.1938.76.pkg"#;
    let target = r#"C:\Users\boni\Downloads\extract"#;

    let cursor = Cursor::new(source);
    let mut reader = XarReader::new(cursor)?;
    reader.unpack(target)?;

    Ok(())
}

But when running it, I got the following error:

Error: Io(Error { kind: UnexpectedEof, message: "failed to fill whole buffer" })

Am I doing something wrong or is it a bug? Thanks.

ionescofung commented 10 months ago

same error

indygreg commented 10 months ago

This works for me. It looks like your Rust code to load a file is wrong. You are constructing a Cursor from the &str filename. What you really want is something like:

let mut reader = crate::reader::XarReader::new(std::File::open(source)?)?;

I confirmed that this particular XAR file is able to extract just fine.

bonigarcia commented 10 months ago

Thanks a lot. Indeed, that code works. With it, I get a folder called MicrosoftEdge-116.0.1938.76.pkg, and inside that folder, the following files: Bom, PackageInfo, Payload, and Scripts. Is it possible to extract the content of Payload using apple-xar?

indygreg commented 10 months ago

The Payload file is a cpio archive. The apple-flat-package crate in this repo has support for decoding this file.

XAR archives are a generic archive format. .pkg files are Apple flavored XAR archives known as flat packages. So you really want to be using the apple-flat-package crate to deeply read .pkg files.

bonigarcia commented 10 months ago

Thanks for the suggestion. Indeed, I want to read pkg files (like this one) to extract their payload. I tried to use the apple-flat-package crate with that pkg file as follows:

use apple_flat_package::reader::PkgReader;
use std::error::Error;
use std::fs::File;

fn main() -> Result<(), Box<dyn Error>> {
    let source = r#"C:\Users\boni\Downloads\MicrosoftEdge-116.0.1938.76.pkg"#;
    let mut reader = PkgReader::new(File::open(source)?)?;
    let packages = reader.component_packages()?;
    println!("Number of components: {}", packages.len());

    Ok(())
}

But I get the following error:

Error: SerdeXml(UnexpectedToken { token: "XmlEvent::EndElement { name, .. }", found: "StartElement(postinstall, {\"\": \"\", \"xml\": \"http://www.w3.org/XML/1998/namespace\", \"xmlns\": \"http://www.w3.org/2000/xmlns/\"}, [file -> ./postinstall])" })

But maybe I am doing something wrong. What is the correct way to extract the payload of a pkg file with apple-flat-package? Many thanks again.

indygreg commented 10 months ago

That postinstall issue is likely #9. Let's move the discussion there.

bonigarcia commented 10 months ago

Issue #9 has been closed and fixed through https://github.com/indygreg/apple-platform-rs/commit/8e29d3d5c72ea9218ae61677885fe6df18bc8302. Is this fix available in apple-flat-package version 0.15.0?

If so, there should be something else, since I continue experiencing this issue using apple-flat-package 0.15.0.

See example to reproduce it: https://github.com/bonigarcia/rust-examples/blob/main/xar/src/main.rs

And the output is:

Error: SerdeXml(UnexpectedToken { token: "XmlEvent::EndElement { name, .. }", found: "StartElement(postinstall, {\"\": \"\", \"xml\": \"http://www.w3.org/XML/1998/namespace\", \"xmlns\": \"http://www.w3.org/2000/xmlns/\"}, [file -> ./postinstall])" })
indygreg commented 10 months ago

No, #9 is not fixed in any released package. I'll hopefully publish a version with the fix in the next few days. In the meantime, you can use the crate via a Git commit in your cargo.toml.

bonigarcia commented 10 months ago

Thank you. Indeed, using the main branch of the GitHub repo, the problem is fixed. But now I don't know how to use the apple-flat-package API to extract the Payload of my PKG file.

Given a PkgReader reader, I want to resolve the component Payload, but it is empty:

let resolve = reader.resolve_component("Payload")?;

Can you guide me on how to extract this PKG using the apple-flat-package?

The complete example I am developing is the following: https://github.com/bonigarcia/rust-examples/blob/main/xar/src/main.rs

Thanks again.