NAME
Archive::Asar - list and extract Electron ASAR (Atom Shell Archive) files
SYNOPSIS
use Archive::Asar;
my $asar = Archive::Asar->new_from_file('app.asar');
# or
my $asar = Archive::Asar->new_from_string($blob);
# or
my $asar = Archive::Asar->new_from_fh('(stdin)', \*STDIN);
my $index_structure = $asar->index_raw;
my $info = $asar->get_entry('file/foo.txt');
$asar->extract_to($target_directory);
DESCRIPTION
Archive::Asar provides an object-oriented interface for handling Electron .asar files ("Atom Shell Archive").
Constructors
- new_from_fh
-
Usage:
my $asar = Archive::Asar->new_from_fh($name, $handle);$nameis the name of the archive (used in error messages).$handleis the filehandle to read from (must be seekable, i.e. not a pipe, terminal, socket, etc).$handleneed not be a built-in Perl filehandle; it can be any object that responds to the required methodsbinmode,seek,tell, andread.Returns the initialized object or throws an exception on error.
- new_from_file
-
Usage:
my $asar = Archive::Asar->new_from_file($file);Like "new_from_fh", but opens
$filefirst (and automatically uses$fileas the name of the archive in error messages). - new_from_string
-
Usage:
my $asar = Archive::Asar->new_from_string($blob);Like "new_from_fh", but reads the archive data directly from a scalar, not a filehandle.
Methods
- index_raw
-
Usage:
my $index = $asar->index_raw;Returns the parsed index data structure stored as JSON in the ASAR file.
The returned data structure must not be modified.
- get_entry
-
Usage:
my $entry = $asar->get_entry($path);Returns information about the archive member stored at
$path.$pathis either a reference to an array of path components (e.g.['foo', 'bar', 'hello.txt']) or a string with path components separated by/(e.g.'foo/bar/hello.txt') or (for Windows compatibility) by\(e.g.'foo\\bar\\hello.txt').Use an empty path (
[]or'') to get information about the root level of the archive, which should be of typedirectory.If the specified path doesn't exist or anything else goes wrong, an exception is thrown.
The return value is a hash reference with a
typefield. There are three possible types:- directory
-
{ type => 'directory', entries => [...], unpacked? => true }An entry of type
directoryhas anentriesfield (an arrayref of strings) listing the entries in that directory. It may also have anunpackedfield (normally set totrueif present). - link
-
{ type => 'link', target => '...', unpacked? => true }An entry of type
linkhas atargetfield (a string) specifying the target of the symbolic link.Beware: The
targetfield is not validated! It may be any string provided by the archive. It may refer to a file outside of the archive or it may not be a valid filename at all. - file
-
{ type => 'file', unpacked => true }{ type => 'file', contents => '...', executable? => true, integrity? => {...} }An entry of type
filehas either a trueunpackedfield, indicating that the file is stored externally (outside of the packed archive), or acontentsfield giving the contents of the file as a string.In the latter case, it may also have an
executablefield, which (if true) indicates that the file is executable, and/or anintegrityfield, which contains checksum information in the following format:{ algorithm => 'SHA256', hash => '...', # lowercase hex blockSize => ..., blocks => [...], }algorithmis the hashing algorithm to use (currently alwaysSHA256; see Digest::SHA).hashis the result of hashing the file contents (in lowercase hex format, two hex digits per byte).blockSizeis an integer. Theblocksfield is an array of the results of splitting the file contents into chunks of (at most)blockSizebytes and hashing each chunk separately, in the same format ashash.For example, an empty file may appear as:
{ type => 'file', contents => '', integrity => { algorithm => 'SHA256', hash => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', blockSize => 0x400000, blocks => ['e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'], }, }
- extract_to
-
Usage:
$asar->extract_to($target_directory, $options = {});Extracts the contents of the archive into the given
$target_directory, which is automatically created if it doesn't exist yet.The
$optionsargument is optional, but must be a hash reference if given. Currently only one option is supported:- unpacked_dir
-
If
unpacked_diris set to a defined value, files markedunpackedin the archive will be read from this directory (and copied to$target_directory).Otherwise
unpackedfiles will be skipped when extracting.
BUGS AND LIMITATIONS
Creating and modifying archives is not supported.
Support for "unpacked" archive members is rudimentary.
Tests are incomplete.
AUTHOR
Lukas Mai, <lmai at web.de>
COPYRIGHT & LICENSE
Copyright 2026 Lukas Mai.
This module is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.