# necessary integrity checks (if a checksum is included), and return the object
# data.
sub load_ref {
- # First, try to parse the object reference string into constituent pieces.
- # The format is segment/object(checksum)[range]. Both the checksum and
- # range are optional.
my $ref_str = shift;
+ # Check for special objects before attempting general parsing.
+ if ($ref_str =~ m/^zero\[((\d+)\+)?(\d+)\]$/) {
+ return "\0" x ($3 + 0);
+ }
+
+ # Try to parse the object reference string into constituent pieces. The
+ # format is segment/object(checksum)[range]. Both the checksum and range
+ # are optional.
if ($ref_str !~ m/^([-0-9a-f]+)\/([0-9a-f]+)(\(\S+\))?(\[\S+\])?$/) {
die "Malformed object reference: $ref_str";
}
# If a range was specified, then only a subset of the bytes of the object
# are desired. Extract just the desired bytes.
if ($range) {
- if ($range !~ m/^\[(\d+)\+(\d+)\]$/) {
+ my $object_size = length $contents;
+ my ($start, $length);
+
+ if ($range =~ m/^\[=(\d+)\]$/) {
+ die "Object size incorrect (ref $ref_str, actual size $object_size"
+ if $object_size != $1;
+ ($start, $length) = (0, $1 + 0);
+ } elsif ($range =~ m/^\[(\d+)\]$/) {
+ ($start, $length) = (0, $1 + 0);
+ } elsif ($range =~ m/^\[(\d+)\+(\d+)\]$/) {
+ ($start, $length) = ($1 + 0, $2 + 0);
+ } else {
die "Malformed object range: $range";
}
- my $object_size = length $contents;
- my ($start, $length) = ($1 + 0, $2 + 0);
if ($start >= $object_size || $start + $length > $object_size) {
die "Object range $range falls outside object bounds "
. "(actual size $object_size)";
# Try to parse the data as "key: value" pairs of file metadata. Also
# handle continuation lines, which start with whitespace and continue
# the previous "key: value" pair.
- if ($line =~ m/^(\w+):\s*(.*)$/) {
+ if ($line =~ m/^([-\w]+):\s*(.*)$/) {
$info{$1} = $2;
$last_key = $1;
} elsif ($line =~/^\s/ && defined $last_key) {
# lines.
chomp $line;
- if ($line =~ m/^(\w+):\s*(.*)$/) {
+ if ($line =~ m/^([-\w]+):\s*(.*)$/) {
$descriptor{$1} = $2;
$last_key = $1;
} elsif ($line =~/^\s/ && defined $last_key) {