@@ -14,7 +14,7 @@ import (
14
14
15
15
// hasNUL reports whether the NUL character exists within s.
16
16
func hasNUL (s string ) bool {
17
- return strings .IndexByte (s , 0 ) >= 0
17
+ return strings .Contains (s , " \x00 " )
18
18
}
19
19
20
20
// isASCII reports whether the input is an ASCII C-style string.
@@ -201,10 +201,7 @@ func parsePAXTime(s string) (time.Time, error) {
201
201
const maxNanoSecondDigits = 9
202
202
203
203
// Split string into seconds and sub-seconds parts.
204
- ss , sn := s , ""
205
- if pos := strings .IndexByte (s , '.' ); pos >= 0 {
206
- ss , sn = s [:pos ], s [pos + 1 :]
207
- }
204
+ ss , sn , _ := strings .Cut (s , "." )
208
205
209
206
// Parse the seconds.
210
207
secs , err := strconv .ParseInt (ss , 10 , 64 )
@@ -254,48 +251,32 @@ func formatPAXTime(ts time.Time) (s string) {
254
251
// return the remainder as r.
255
252
func parsePAXRecord (s string ) (k , v , r string , err error ) {
256
253
// The size field ends at the first space.
257
- sp := strings .IndexByte (s , ' ' )
258
- if sp == - 1 {
254
+ nStr , rest , ok := strings .Cut (s , " " )
255
+ if ! ok {
259
256
return "" , "" , s , ErrHeader
260
257
}
261
258
262
259
// Parse the first token as a decimal integer.
263
- n , perr := strconv .ParseInt (s [: sp ] , 10 , 0 ) // Intentionally parse as native int
264
- if perr != nil || n < 5 || int64 (len (s )) < n {
260
+ n , perr := strconv .ParseInt (nStr , 10 , 0 ) // Intentionally parse as native int
261
+ if perr != nil || n < 5 || n > int64 (len (s )) {
265
262
return "" , "" , s , ErrHeader
266
263
}
267
-
268
- afterSpace := int64 (sp + 1 )
269
- beforeLastNewLine := n - 1
270
- // In some cases, "length" was perhaps padded/malformed, and
271
- // trying to index past where the space supposedly is goes past
272
- // the end of the actual record.
273
- // For example:
274
- // "0000000000000000000000000000000030 mtime=1432668921.098285006\n30 ctime=2147483649.15163319"
275
- // ^ ^
276
- // | |
277
- // | afterSpace=35
278
- // |
279
- // beforeLastNewLine=29
280
- // yet indexOf(firstSpace) MUST BE before endOfRecord.
281
- //
282
- // See https://golang.org/issues/40196.
283
- if afterSpace >= beforeLastNewLine {
264
+ n -= int64 (len (nStr ) + 1 ) // convert from index in s to index in rest
265
+ if n <= 0 {
284
266
return "" , "" , s , ErrHeader
285
267
}
286
268
287
269
// Extract everything between the space and the final newline.
288
- rec , nl , rem := s [ afterSpace : beforeLastNewLine ], s [ beforeLastNewLine :n ], s [n :]
270
+ rec , nl , rem := rest [: n - 1 ], rest [ n - 1 :n ], rest [n :]
289
271
if nl != "\n " {
290
272
return "" , "" , s , ErrHeader
291
273
}
292
274
293
275
// The first equals separates the key from the value.
294
- eq : = strings .IndexByte (rec , '=' )
295
- if eq == - 1 {
276
+ k , v , ok = strings .Cut (rec , "=" )
277
+ if ! ok {
296
278
return "" , "" , s , ErrHeader
297
279
}
298
- k , v = rec [:eq ], rec [eq + 1 :]
299
280
300
281
if ! validPAXRecord (k , v ) {
301
282
return "" , "" , s , ErrHeader
@@ -333,7 +314,7 @@ func formatPAXRecord(k, v string) (string, error) {
333
314
// for the PAX version of the USTAR string fields.
334
315
// The key must not contain an '=' character.
335
316
func validPAXRecord (k , v string ) bool {
336
- if k == "" || strings .IndexByte (k , '=' ) >= 0 {
317
+ if k == "" || strings .Contains (k , "=" ) {
337
318
return false
338
319
}
339
320
switch k {
0 commit comments