@@ -471,16 +471,17 @@ func LimitReader(r Reader, n int64) Reader { return &LimitedReader{R: r, N: n} }
471471type LimitedReader struct {
472472 R Reader // underlying reader
473473 N int64 // max bytes remaining
474- Err error // error to return when limit is exceeded; defaults to EOF if nil
474+ Err error // error to return when limit is exceeded
475475}
476476
477477func (l * LimitedReader ) Read (p []byte ) (n int , err error ) {
478- if len (p ) == 0 {
478+ // We use negative l.N values to signal that we've exceeded the limit and cached the result.
479+ const sentinelExceeded = - 1 // Probed and found more data available
480+ const sentinelExactMatch = - 2 // Probed and found EOF (exactly N bytes)
481+
482+ if len (p ) == 0 && l .N <= 0 {
479483 return 0 , nil
480484 }
481- // We use negative l.N values to signal that we've exceeded the limit and cached the result:
482- // -1 means more data is available
483- // -2 means hit EOF exactly
484485
485486 if l .N > 0 {
486487 if int64 (len (p )) > l .N {
@@ -491,11 +492,13 @@ func (l *LimitedReader) Read(p []byte) (n int, err error) {
491492 return
492493 }
493494
495+ // Sentinel
494496 if l .N < 0 {
495- if l .N == - 1 && l .Err != nil {
496- return 0 , l .Err // limit was exceeded
497+ if l .N == sentinelExceeded && l .Err != nil {
498+ return 0 , l .Err
497499 }
498- return 0 , EOF // stream was exactly N bytes, or already past limit
500+
501+ return 0 , EOF
499502 }
500503
501504 // At limit (N == 0) - need to determine if stream has more data
@@ -504,18 +507,17 @@ func (l *LimitedReader) Read(p []byte) (n int, err error) {
504507 return 0 , EOF
505508 }
506509
507- // Probe with one byte to distinguish two cases:
508- // - Stream had exactly N bytes -> return EOF
509- // - Stream has more than N bytes -> return custom error
510+ // Probe with one byte to distinguish two sentinels.
510511 // We can't tell without reading ahead. This probe permanently consumes
511512 // a byte from R, so we cache the result in N to avoid re-probing.
512513 var probe [1 ]byte
513514 probeN , probeErr := l .R .Read (probe [:])
514515 if probeN > 0 || probeErr != EOF {
515- l .N = - 1 // more data available, limit exceeded
516+ l .N = sentinelExceeded
516517 return 0 , l .Err
517518 }
518- l .N = - 2 // hit EOF, stream was exactly N bytes
519+
520+ l .N = sentinelExactMatch
519521 return 0 , EOF
520522}
521523
0 commit comments