66package transport
77
88import (
9+ "errors"
910 "fmt"
1011 "io"
1112 "math"
@@ -318,10 +319,10 @@ func eofOK(err error) error {
318319func (it * iterator ) nextProtoHdr (loghdr string ) (int , uint64 , error ) {
319320 n , err := it .Read (it .hbuf [:sizeProtoHdr ])
320321 if n < sizeProtoHdr {
321- if err == nil {
322- err = fmt . Errorf ( "sbr3 %s: failed to receive proto hdr (n=%d)" , loghdr , n )
322+ if err == nil || errors . Is ( err , io . EOF ) {
323+ err = io . ErrUnexpectedEOF
323324 }
324- return 0 , 0 , err
325+ return 0 , 0 , fmt . Errorf ( "sbr3 %s: failed to receive proto hdr (n=%d): %w" , loghdr , n , err )
325326 }
326327 // extract and validate hlen
327328 return extProtoHdr (it .hbuf , loghdr )
@@ -349,7 +350,10 @@ func (it *iterator) nextObj(loghdr string, hlen int) (*objReader, error) {
349350 }
350351 }
351352 if n < hlen {
352- return nil , fmt .Errorf ("sbr4 %s: failed to receive obj hdr (%d < %d)" , loghdr , n , hlen )
353+ if err == nil || errors .Is (err , io .EOF ) {
354+ err = io .ErrUnexpectedEOF
355+ }
356+ return nil , fmt .Errorf ("sbr4 %s: failed to receive obj hdr (%d < %d): %w" , loghdr , n , hlen , err )
353357 }
354358 }
355359 hdr := ExtObjHeader (it .hbuf , hlen )
@@ -371,23 +375,34 @@ func (obj *objReader) Read(b []byte) (n int, err error) {
371375 return obj .readPDU (b )
372376 }
373377 debug .Assert (obj .Size () >= 0 )
378+
374379 rem := obj .Size () - obj .off
375- if rem < int64 (len (b )) {
380+ if rem < int64 (len (b )) && rem >= 0 {
376381 b = b [:int (rem )]
377382 }
383+
378384 n , err = obj .body .Read (b )
379385 obj .off += int64 (n ) // NOTE: `GORACE` complaining here can be safely ignored
386+
380387 switch err {
381388 case nil :
382389 if obj .off >= obj .Size () {
390+ // ok (w/ EOF to the caller)
383391 err = io .EOF
384392 }
385393 case io .EOF :
394+ // premature EOF: expected size not reached
386395 if obj .off != obj .Size () {
387- err = fmt .Errorf ("sbr6 %s: premature eof %d != %s, err %w" , obj .loghdr , obj .off , obj , err )
396+ err = fmt .Errorf ("sbr6 %s: premature eof %d != %s: %w" , obj .loghdr , obj .off , obj , io . ErrUnexpectedEOF )
388397 }
389398 default :
390- err = fmt .Errorf ("sbr7 %s: off %d, obj %s, err %w" , obj .loghdr , obj .off , obj , err )
399+ // we haven't consumed the header-specified size
400+ if obj .off < obj .Size () {
401+ err = fmt .Errorf ("sbr7 %s: off %d, obj %s, cause: %v: %w" , obj .loghdr , obj .off , obj , err , io .ErrUnexpectedEOF )
402+ } else {
403+ // read the full payload; just annotate
404+ err = fmt .Errorf ("sbr7 %s: off %d, obj %s, err %w" , obj .loghdr , obj .off , obj , err )
405+ }
391406 }
392407 return n , err
393408}
@@ -433,7 +448,7 @@ func (obj *objReader) readPDU(b []byte) (n int, err error) {
433448 if obj .IsUnsized () {
434449 obj .hdr .ObjAttrs .Size = obj .off
435450 } else if obj .Size () != obj .off {
436- err = fmt .Errorf ("sbr9 %s: off %d != %s" , obj .loghdr , obj .off , obj )
451+ err = fmt .Errorf ("sbr9 %s: off %d != %s: %w " , obj .loghdr , obj .off , obj , io . ErrUnexpectedEOF )
437452 nlog .Warningln (err )
438453 }
439454 } else {
0 commit comments