Skip to content

Commit

Permalink
tar: remove strconv dependency for tar checksum octal numbers (gabrie…
Browse files Browse the repository at this point in the history
…l-vasile#536)

goos: linux
goarch: amd64
pkg: github.com/gabriel-vasile/mimetype
cpu: Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz
               │ common_master │              common_dev              │
               │    sec/op     │    sec/op     vs base                │
Common/.xlsx-8    401.2n ±  3%   312.2n ±  5%  -22.17% (p=0.000 n=10)
Common/.pptx-8    1.708µ ±  4%   1.535µ ±  3%  -10.10% (p=0.000 n=10)
Common/.docx-8    1.260µ ±  7%   1.116µ ±  4%  -11.43% (p=0.000 n=10)
Common/.tar-8    1011.0n ±  7%   785.0n ±  4%  -22.35% (p=0.000 n=10)
Common/.zip-8     742.3n ± 11%   616.2n ± 16%  -16.99% (p=0.003 n=10)
Common/.pdf-8     291.6n ±  4%   191.9n ±  4%  -34.20% (p=0.000 n=10)
Common/.jpg-8     410.7n ±  9%   374.1n ± 17%   -8.90% (p=0.019 n=10)
Common/.png-8     425.1n ±  8%   327.8n ±  8%  -22.89% (p=0.000 n=10)
Common/.gif-8     480.4n ±  4%   396.9n ±  7%  -17.38% (p=0.000 n=10)
Common/.xls-8     427.2n ±  6%   324.7n ±  4%  -24.00% (p=0.000 n=10)
Common/.webm-8   1160.0n ±  5%   724.8n ±  5%  -37.52% (p=0.000 n=10)
Common/.csv-8     6.965µ ±  7%   5.671µ ±  6%  -18.57% (p=0.000 n=10)
geomean           784.9n         620.0n        -21.01%

               │ common_master │              common_dev               │
               │     B/op      │     B/op      vs base                 │
Common/.xlsx-8      312.0 ± 0%     312.0 ± 0%       ~ (p=1.000 n=10) ¹
Common/.pptx-8      592.0 ± 0%     592.0 ± 0%       ~ (p=1.000 n=10) ¹
Common/.docx-8      504.0 ± 0%     504.0 ± 0%       ~ (p=1.000 n=10) ¹
Common/.tar-8       200.0 ± 0%     192.0 ± 0%  -4.00% (p=0.000 n=10)
Common/.zip-8       224.0 ± 0%     224.0 ± 0%       ~ (p=1.000 n=10) ¹
Common/.pdf-8       192.0 ± 0%     192.0 ± 0%       ~ (p=1.000 n=10) ¹
Common/.jpg-8       192.0 ± 0%     192.0 ± 0%       ~ (p=1.000 n=10) ¹
Common/.png-8       192.0 ± 0%     192.0 ± 0%       ~ (p=1.000 n=10) ¹
Common/.gif-8       192.0 ± 0%     192.0 ± 0%       ~ (p=1.000 n=10) ¹
Common/.xls-8       288.0 ± 0%     288.0 ± 0%       ~ (p=1.000 n=10) ¹
Common/.webm-8      192.0 ± 0%     192.0 ± 0%       ~ (p=1.000 n=10) ¹
Common/.csv-8     7.390Ki ± 0%   7.323Ki ± 0%  -0.90% (p=0.000 n=10)
geomean             339.8          338.4       -0.41%
¹ all samples are equal

               │ common_master │              common_dev              │
               │   allocs/op   │ allocs/op   vs base                  │
Common/.xlsx-8      4.000 ± 0%   4.000 ± 0%        ~ (p=1.000 n=10) ¹
Common/.pptx-8      15.00 ± 0%   15.00 ± 0%        ~ (p=1.000 n=10) ¹
Common/.docx-8      13.00 ± 0%   13.00 ± 0%        ~ (p=1.000 n=10) ¹
Common/.tar-8       3.000 ± 0%   2.000 ± 0%  -33.33% (p=0.000 n=10)
Common/.zip-8       6.000 ± 0%   6.000 ± 0%        ~ (p=1.000 n=10) ¹
Common/.pdf-8       2.000 ± 0%   2.000 ± 0%        ~ (p=1.000 n=10) ¹
Common/.jpg-8       2.000 ± 0%   2.000 ± 0%        ~ (p=1.000 n=10) ¹
Common/.png-8       2.000 ± 0%   2.000 ± 0%        ~ (p=1.000 n=10) ¹
Common/.gif-8       2.000 ± 0%   2.000 ± 0%        ~ (p=1.000 n=10) ¹
Common/.xls-8       3.000 ± 0%   3.000 ± 0%        ~ (p=1.000 n=10) ¹
Common/.webm-8      2.000 ± 0%   2.000 ± 0%        ~ (p=1.000 n=10) ¹
Common/.csv-8       34.00 ± 0%   31.00 ± 0%   -8.82% (p=0.000 n=10)
geomean             4.349        4.173        -4.06%
¹ all samples are equal

            │ rand_master │              rand_dev               │
            │   sec/op    │   sec/op     vs base                │
SliceRand-8   457.4n ± 4%   398.1n ± 3%  -12.96% (p=0.000 n=10)

            │ rand_master │              rand_dev              │
            │    B/op     │    B/op     vs base                │
SliceRand-8   160.00 ± 0%   96.00 ± 0%  -40.00% (p=0.000 n=10)

            │ rand_master │              rand_dev              │
            │  allocs/op  │ allocs/op   vs base                │
SliceRand-8    4.000 ± 0%   1.000 ± 0%  -75.00% (p=0.000 n=10)
  • Loading branch information
gabriel-vasile authored May 27, 2024
1 parent 09ff708 commit 77e3848
Showing 2 changed files with 27 additions and 39 deletions.
31 changes: 14 additions & 17 deletions internal/magic/archive.go
Original file line number Diff line number Diff line change
@@ -3,7 +3,6 @@ package magic
import (
"bytes"
"encoding/binary"
"strconv"
)

var (
@@ -110,37 +109,35 @@ func Tar(raw []byte, _ uint32) bool {
}

// Get the checksum recorded into the file.
recsum, err := tarParseOctal(raw[148:156])
if err != nil {
recsum := tarParseOctal(raw[148:156])
if recsum == -1 {
return false
}
sum1, sum2 := tarChksum(raw)
return recsum == sum1 || recsum == sum2
}

// tarParseOctal converts octal string to decimal int.
func tarParseOctal(b []byte) (int64, error) {
func tarParseOctal(b []byte) int64 {
// Because unused fields are filled with NULs, we need to skip leading NULs.
// Fields may also be padded with spaces or NULs.
// So we remove leading and trailing NULs and spaces to be sure.
b = bytes.Trim(b, " \x00")

if len(b) == 0 {
return 0, nil
return -1
}
x, err := strconv.ParseUint(tarParseString(b), 8, 64)
if err != nil {
return 0, err
}
return int64(x), nil
}

// tarParseString converts a NUL ended bytes slice to a string.
func tarParseString(b []byte) string {
if i := bytes.IndexByte(b, 0); i >= 0 {
return string(b[:i])
ret := int64(0)
for _, b := range b {
if b == 0 {
break
}
if !(b >= '0' && b <= '7') {
return -1
}
ret = (ret << 3) | int64(b-'0')
}
return string(b)
return ret
}

// tarChksum computes the checksum for the header block b.
35 changes: 13 additions & 22 deletions internal/magic/archive_test.go
Original file line number Diff line number Diff line change
@@ -6,32 +6,23 @@ func TestTarParseOctal(t *testing.T) {
tests := []struct {
in string
want int64
ok bool
}{
{"0000000\x00", 0, true},
{" \x0000000\x00", 0, true},
{" \x0000003\x00", 3, true},
{"00000000227\x00", 0227, true},
{"032033\x00 ", 032033, true},
{"320330\x00 ", 0320330, true},
{"0000660\x00 ", 0660, true},
{"\x00 0000660\x00 ", 0660, true},
{"0123456789abcdef", 0, false},
{"0123456789\x00abcdef", 0, false},
{"01234567\x0089abcdef", 342391, true},
{"0123\x7e\x5f\x264123", 0, false},
{"0000000\x00", 0},
{" \x0000000\x00", 0},
{" \x0000003\x00", 3},
{"00000000227\x00", 0227},
{"032033\x00 ", 032033},
{"320330\x00 ", 0320330},
{"0000660\x00 ", 0660},
{"\x00 0000660\x00 ", 0660},
{"0123456789abcdef", -1},
{"0123456789\x00abcdef", -1},
{"01234567\x0089abcdef", 01234567},
{"0123\x7e\x5f\x264123", -1},
}

for _, tt := range tests {
got, err := tarParseOctal([]byte(tt.in))
ok := err == nil
if ok != tt.ok {
if tt.ok {
t.Errorf("parseOctal(%q): got parsing failure, want success", tt.in)
} else {
t.Errorf("parseOctal(%q): got parsing success, want failure", tt.in)
}
}
got := tarParseOctal([]byte(tt.in))
if got != tt.want {
t.Errorf("parseOctal(%q): got %d, want %d", tt.in, got, tt.want)
}

0 comments on commit 77e3848

Please sign in to comment.