1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
|
From d8029ceb202fda8160855c07081dc51aae1ec1ad Mon Sep 17 00:00:00 2001
From: Vincent Batts <vbatts@redhat.com>
Date: Wed, 23 Sep 2015 15:50:23 -0400
Subject: [PATCH 5/5] vendor: update tar-split to v0.9.10
This addresses handling of non-utf8 file names, namely iso-8859-1.
https://github.com/docker/docker/issues/16516
Reported-by: @kwk
Signed-off-by: Vincent Batts <vbatts@redhat.com>
---
hack/vendor.sh | 2 +-
.../vbatts/tar-split/archive/tar/common.go | 28 ++++++++++++++--
.../vbatts/tar-split/archive/tar/reader.go | 15 ++++++++-
.../vbatts/tar-split/archive/tar/writer.go | 2 +-
.../vbatts/tar-split/tar/asm/assemble.go | 4 +--
.../vbatts/tar-split/tar/asm/disassemble.go | 11 +++---
.../vbatts/tar-split/tar/storage/entry.go | 39 ++++++++++++++++++++++
.../vbatts/tar-split/tar/storage/packer.go | 13 ++++++--
8 files changed, 101 insertions(+), 13 deletions(-)
diff --git a/hack/vendor.sh b/hack/vendor.sh
index 68772ef..52ba6ef 100755
--- a/hack/vendor.sh
+++ b/hack/vendor.sh
@@ -36,7 +36,7 @@ clone git github.com/hashicorp/consul v0.5.2
# get graph and distribution packages
clone git github.com/docker/distribution ec87e9b6971d831f0eff752ddb54fb64693e51cd # docker/1.8 branch
-clone git github.com/vbatts/tar-split v0.9.6
+clone git github.com/vbatts/tar-split v0.9.10
clone git github.com/docker/notary 8e8122eb5528f621afcd4e2854c47302f17392f7
clone git github.com/endophage/gotuf a592b03b28b02bb29bb5878308fb1abed63383b5
diff --git a/vendor/src/github.com/vbatts/tar-split/archive/tar/common.go b/vendor/src/github.com/vbatts/tar-split/archive/tar/common.go
index e363aa7..c31df06 100644
--- a/vendor/src/github.com/vbatts/tar-split/archive/tar/common.go
+++ b/vendor/src/github.com/vbatts/tar-split/archive/tar/common.go
@@ -139,8 +139,8 @@ func (fi headerFileInfo) Mode() (mode os.FileMode) {
}
switch fi.h.Typeflag {
- case TypeLink, TypeSymlink:
- // hard link, symbolic link
+ case TypeSymlink:
+ // symbolic link
mode |= os.ModeSymlink
case TypeChar:
// character device node
@@ -249,6 +249,30 @@ func FileInfoHeader(fi os.FileInfo, link string) (*Header, error) {
if fm&os.ModeSticky != 0 {
h.Mode |= c_ISVTX
}
+ // If possible, populate additional fields from OS-specific
+ // FileInfo fields.
+ if sys, ok := fi.Sys().(*Header); ok {
+ // This FileInfo came from a Header (not the OS). Use the
+ // original Header to populate all remaining fields.
+ h.Uid = sys.Uid
+ h.Gid = sys.Gid
+ h.Uname = sys.Uname
+ h.Gname = sys.Gname
+ h.AccessTime = sys.AccessTime
+ h.ChangeTime = sys.ChangeTime
+ if sys.Xattrs != nil {
+ h.Xattrs = make(map[string]string)
+ for k, v := range sys.Xattrs {
+ h.Xattrs[k] = v
+ }
+ }
+ if sys.Typeflag == TypeLink {
+ // hard link
+ h.Typeflag = TypeLink
+ h.Size = 0
+ h.Linkname = sys.Linkname
+ }
+ }
if sysStat != nil {
return h, sysStat(fi, h)
}
diff --git a/vendor/src/github.com/vbatts/tar-split/archive/tar/reader.go b/vendor/src/github.com/vbatts/tar-split/archive/tar/reader.go
index c72e002..4168ea2 100644
--- a/vendor/src/github.com/vbatts/tar-split/archive/tar/reader.go
+++ b/vendor/src/github.com/vbatts/tar-split/archive/tar/reader.go
@@ -138,7 +138,13 @@ func (tr *Reader) Next() (*Header, error) {
// We actually read the whole file,
// but this skips alignment padding
tr.skipUnread()
+ if tr.err != nil {
+ return nil, tr.err
+ }
hdr = tr.readHeader()
+ if hdr == nil {
+ return nil, tr.err
+ }
mergePAX(hdr, headers)
// Check for a PAX format sparse file
@@ -397,7 +403,7 @@ func parsePAX(r io.Reader) (map[string]string, error) {
}
// Parse the first token as a decimal integer.
n, err := strconv.ParseInt(string(buf[:sp]), 10, 0)
- if err != nil {
+ if err != nil || n < 5 || int64(len(buf)) < n {
return nil, ErrHeader
}
// Extract everything between the decimal and the n -1 on the
@@ -553,6 +559,10 @@ func (tr *Reader) readHeader() *Header {
hdr.Uid = int(tr.octal(s.next(8)))
hdr.Gid = int(tr.octal(s.next(8)))
hdr.Size = tr.octal(s.next(12))
+ if hdr.Size < 0 {
+ tr.err = ErrHeader
+ return nil
+ }
hdr.ModTime = time.Unix(tr.octal(s.next(12)), 0)
s.next(8) // chksum
hdr.Typeflag = s.next(1)[0]
@@ -895,6 +905,9 @@ func (sfr *sparseFileReader) Read(b []byte) (n int, err error) {
// Otherwise, we're at the end of the file
return 0, io.EOF
}
+ if sfr.tot < sfr.sp[0].offset {
+ return 0, io.ErrUnexpectedEOF
+ }
if sfr.pos < sfr.sp[0].offset {
// We're in a hole
n = sfr.readHole(b, sfr.sp[0].offset)
diff --git a/vendor/src/github.com/vbatts/tar-split/archive/tar/writer.go b/vendor/src/github.com/vbatts/tar-split/archive/tar/writer.go
index dafb2ca..9dbc01a 100644
--- a/vendor/src/github.com/vbatts/tar-split/archive/tar/writer.go
+++ b/vendor/src/github.com/vbatts/tar-split/archive/tar/writer.go
@@ -355,7 +355,7 @@ func paxHeader(msg string) string {
// hdr.Size bytes are written after WriteHeader.
func (tw *Writer) Write(b []byte) (n int, err error) {
if tw.closed {
- err = ErrWriteTooLong
+ err = ErrWriteAfterClose
return
}
overwrite := false
diff --git a/vendor/src/github.com/vbatts/tar-split/tar/asm/assemble.go b/vendor/src/github.com/vbatts/tar-split/tar/asm/assemble.go
index 74317cb..83d6426 100644
--- a/vendor/src/github.com/vbatts/tar-split/tar/asm/assemble.go
+++ b/vendor/src/github.com/vbatts/tar-split/tar/asm/assemble.go
@@ -39,7 +39,7 @@ func NewOutputTarStream(fg storage.FileGetter, up storage.Unpacker) io.ReadClose
if entry.Size == 0 {
continue
}
- fh, err := fg.Get(entry.Name)
+ fh, err := fg.Get(entry.GetName())
if err != nil {
pw.CloseWithError(err)
return
@@ -56,7 +56,7 @@ func NewOutputTarStream(fg storage.FileGetter, up storage.Unpacker) io.ReadClose
// but since it's coming through the PipeReader, the context of
// _which_ file would be lost...
fh.Close()
- pw.CloseWithError(fmt.Errorf("file integrity checksum failed for %q", entry.Name))
+ pw.CloseWithError(fmt.Errorf("file integrity checksum failed for %q", entry.GetName()))
return
}
fh.Close()
diff --git a/vendor/src/github.com/vbatts/tar-split/tar/asm/disassemble.go b/vendor/src/github.com/vbatts/tar-split/tar/asm/disassemble.go
index 7986890..54ef23a 100644
--- a/vendor/src/github.com/vbatts/tar-split/tar/asm/disassemble.go
+++ b/vendor/src/github.com/vbatts/tar-split/tar/asm/disassemble.go
@@ -92,13 +92,16 @@ func NewInputTarStream(r io.Reader, p storage.Packer, fp storage.FilePutter) (io
}
}
- // File entries added, regardless of size
- _, err = p.AddEntry(storage.Entry{
+ entry := storage.Entry{
Type: storage.FileType,
- Name: hdr.Name,
Size: hdr.Size,
Payload: csum,
- })
+ }
+ // For proper marshalling of non-utf8 characters
+ entry.SetName(hdr.Name)
+
+ // File entries added, regardless of size
+ _, err = p.AddEntry(entry)
if err != nil {
pW.CloseWithError(err)
return
diff --git a/vendor/src/github.com/vbatts/tar-split/tar/storage/entry.go b/vendor/src/github.com/vbatts/tar-split/tar/storage/entry.go
index 38fe7ba..c91e7ea 100644
--- a/vendor/src/github.com/vbatts/tar-split/tar/storage/entry.go
+++ b/vendor/src/github.com/vbatts/tar-split/tar/storage/entry.go
@@ -1,5 +1,7 @@
package storage
+import "unicode/utf8"
+
// Entries is for sorting by Position
type Entries []Entry
@@ -33,7 +35,44 @@ const (
type Entry struct {
Type Type `json:"type"`
Name string `json:"name,omitempty"`
+ NameRaw []byte `json:"name_raw,omitempty"`
Size int64 `json:"size,omitempty"`
Payload []byte `json:"payload"` // SegmentType stores payload here; FileType stores crc64 checksum here;
Position int `json:"position"`
}
+
+// SetName will check name for valid UTF-8 string, and set the appropriate
+// field. See https://github.com/vbatts/tar-split/issues/17
+func (e *Entry) SetName(name string) {
+ if utf8.ValidString(name) {
+ e.Name = name
+ } else {
+ e.NameRaw = []byte(name)
+ }
+}
+
+// SetNameBytes will check name for valid UTF-8 string, and set the appropriate
+// field
+func (e *Entry) SetNameBytes(name []byte) {
+ if utf8.Valid(name) {
+ e.Name = string(name)
+ } else {
+ e.NameRaw = name
+ }
+}
+
+// GetName returns the string for the entry's name, regardless of the field stored in
+func (e *Entry) GetName() string {
+ if len(e.NameRaw) > 0 {
+ return string(e.NameRaw)
+ }
+ return e.Name
+}
+
+// GetNameBytes returns the bytes for the entry's name, regardless of the field stored in
+func (e *Entry) GetNameBytes() []byte {
+ if len(e.NameRaw) > 0 {
+ return e.NameRaw
+ }
+ return []byte(e.Name)
+}
diff --git a/vendor/src/github.com/vbatts/tar-split/tar/storage/packer.go b/vendor/src/github.com/vbatts/tar-split/tar/storage/packer.go
index a02a19a..0c9d99b 100644
--- a/vendor/src/github.com/vbatts/tar-split/tar/storage/packer.go
+++ b/vendor/src/github.com/vbatts/tar-split/tar/storage/packer.go
@@ -6,6 +6,7 @@ import (
"errors"
"io"
"path/filepath"
+ "unicode/utf8"
)
// ErrDuplicatePath occurs when a tar archive has more than one entry for the
@@ -61,7 +62,7 @@ func (jup *jsonUnpacker) Next() (*Entry, error) {
// check for dup name
if e.Type == FileType {
- cName := filepath.Clean(e.Name)
+ cName := filepath.Clean(e.GetName())
if _, ok := jup.seen[cName]; ok {
return nil, ErrDuplicatePath
}
@@ -93,9 +94,17 @@ type jsonPacker struct {
type seenNames map[string]struct{}
func (jp *jsonPacker) AddEntry(e Entry) (int, error) {
+ // if Name is not valid utf8, switch it to raw first.
+ if e.Name != "" {
+ if !utf8.ValidString(e.Name) {
+ e.NameRaw = []byte(e.Name)
+ e.Name = ""
+ }
+ }
+
// check early for dup name
if e.Type == FileType {
- cName := filepath.Clean(e.Name)
+ cName := filepath.Clean(e.GetName())
if _, ok := jp.seen[cName]; ok {
return -1, ErrDuplicatePath
}
--
2.4.3
|