@@ -314,6 +314,10 @@ restore: // should be faster than a defer
314
314
return false
315
315
}
316
316
317
+ // 'b' and 'B' are not present here because of the way we check for byte size
318
+ // units below. If they were present, then suffixes like 'Bb', 'bb', etc. would
319
+ // be considered valid byte sizes. Also, only integer numbers are accepted as
320
+ // valid bytesizes in bytes, so we handle bytes with special cases instead.
317
321
var byteSizes = [256 ]bool {'k' : true , 'K' : true , 'm' : true , 'M' : true , 'g' : true , 'G' : true , 't' : true , 'T' : true , 'p' : true , 'P' : true }
318
322
319
323
// Only moves the head forward if it successfully matches a duration
@@ -339,6 +343,22 @@ func (r *replacer) advanceBytesize(c1 byte) (matched bool) {
339
343
return false
340
344
}
341
345
346
+ func (r * replacer ) advanceSpacedBytesize (canBeBytes bool ) (matched bool ) {
347
+ // Get the next character after the space
348
+ c1 , hasNext := r .advance ()
349
+ if ! hasNext {
350
+ return false
351
+ }
352
+ if canBeBytes && (c1 == 'b' || c1 == 'B' ) && r .peekNextIsBoundary () {
353
+ return true
354
+ }
355
+ if r .advanceBytesize (c1 ) {
356
+ return true
357
+ }
358
+ r .backtrack ()
359
+ return false
360
+ }
361
+
342
362
func (r * replacer ) advance () (c byte , advanced bool ) {
343
363
if r .head >= len (r .source ) {
344
364
return 0 , false
@@ -394,6 +414,14 @@ func (r *replacer) handleHexOrUnit(hasMinusPrefix bool, n1, l1 uint, c1 byte) (e
394
414
c1 = r .peekFirstNonInt ()
395
415
}
396
416
417
+ // Special case, this might be a byte size
418
+ if (c1 == 'b' || c1 == 'B' ) && r .peekNextIsBoundary () {
419
+ // We do not subsume a minus sign - byte sizes are unlikely to be
420
+ // negative, it's more likely this is a dash as a part of a range
421
+ r .emit (hasMinusPrefix , placeholderBytesize )
422
+ return true
423
+ }
424
+
397
425
// Maybe we are at the start of a hex string, either something like
398
426
// "[0-9]+[a-f]", "[0-9]+[A-F]", or "0x". We support both lower and upper
399
427
// case letters, but to avoid false positives, we want hex replacements to
@@ -489,6 +517,14 @@ func (r *replacer) handleNumberWithDecimal(hasMinusPrefix bool, n1 uint, l1 uint
489
517
return r .handlePotentialUnitWithDecimal (hasMinusPrefix , b2 )
490
518
}
491
519
520
+ // This can be a byte size with a space, e.g. "3.14 GiB"
521
+ if b2 == ' ' && r .advanceSpacedBytesize (false ) {
522
+ // We do not subsume a minus sign - byte sizes are unlikely to be
523
+ // negative, it's more likely this is a dash as a part of a range
524
+ r .emit (hasMinusPrefix , placeholderBytesize )
525
+ return true
526
+ }
527
+
492
528
// We have a decimal number followed by a non-dot boundary, so this is not
493
529
// an IP or a version number or anything like that.
494
530
if b2 != '.' {
@@ -633,6 +669,11 @@ func (r *replacer) handleNumberStart(hasMinusPrefix bool) (endsWithBoundary bool
633
669
case n1 <= maxYear && l1 <= 4 && (b1 == '-' || b1 == '/' ):
634
670
return r .handleSaneTimestamp (hasMinusPrefix , n1 , b1 )
635
671
672
+ // This might be a byte size with a space, e.g. "2 b", "3 GiB"
673
+ case b1 == ' ' && r .advanceSpacedBytesize (true ):
674
+ r .emit (hasMinusPrefix , placeholderBytesize )
675
+ return true
676
+
636
677
// Weird RFC822 dates like "02 Jan 06 15:04 MST"
637
678
case n1 <= 31 && l1 <= 2 && b1 == ' ' :
638
679
if r .advanceMonthName () && r .advanceChar (' ' ) && r .advanceYear () && r .advanceChar (' ' ) && r .advanceTime (true ) && r .advanceStringOrNumericTimeZone (false ) {
0 commit comments