From: Joe Tsai Date: Wed, 9 Aug 2017 18:08:55 +0000 (-0700) Subject: archive/tar: ensure input fits in octal field X-Git-Tag: go1.10beta1~1654 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=310ba828289f8c4924bc0f319b72e151f5f079f7;p=gostls13.git archive/tar: ensure input fits in octal field The prior logic would over-write the NUL-terminator if the octal value was long enough. In order to prevent this, we add a fitsInOctal function that does the proper check. The relevant USTAR specification about NUL-terminator is: <<< Each numeric field is terminated by one or more or NUL characters. >>> Change-Id: I6fbc6e8fe71168727eea201925d0fe08d43116ac Reviewed-on: https://go-review.googlesource.com/54432 Reviewed-by: Ian Lance Taylor --- diff --git a/src/archive/tar/strconv.go b/src/archive/tar/strconv.go index 3a635834ff..7629c43c65 100644 --- a/src/archive/tar/strconv.go +++ b/src/archive/tar/strconv.go @@ -124,8 +124,14 @@ func (p *parser) parseNumeric(b []byte) int64 { return p.parseOctal(b) } -// Write x into b, as binary (GNUtar/star extension). +// formatNumeric encodes x into b using base-8 (octal) encoding if possible. +// Otherwise it will attempt to use base-256 (binary) encoding. func (f *formatter) formatNumeric(b []byte, x int64) { + if fitsInOctal(len(b), x) { + f.formatOctal(b, x) + return + } + if fitsInBase256(len(b), x) { for i := len(b) - 1; i >= 0; i-- { b[i] = byte(x) @@ -166,6 +172,13 @@ func (f *formatter) formatOctal(b []byte, x int64) { f.formatString(b, s) } +// fitsInOctal reports whether the integer x fits in a field n-bytes long +// using octal encoding with the appropriate NUL terminator. +func fitsInOctal(n int, x int64) bool { + octBits := uint(n-1) * 3 + return x >= 0 && (n >= 22 || x < 1<