Skip to content

Commit c80d382

Browse files
feat: Return error when popping last limit in reader
- Updated `PopLimit` in `pkg/dicomio/reader.go` to return an error when attempting to pop from an empty stack, preventing a panic. - Added `ErrorLimitStackEmpty` to exported errors. - Moved stack check to the beginning of `PopLimit` to avoid skipping bytes if the operation is invalid. - Updated call sites in `read.go` to handle or ignore the returned error appropriately.
1 parent 6357e3e commit c80d382

2 files changed

Lines changed: 27 additions & 8 deletions

File tree

pkg/dicomio/reader.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ var (
1818
// the current buffer (or enough bytes left until the currently set limit)
1919
// to complete the operation.
2020
ErrorInsufficientBytesLeft = errors.New("not enough bytes left until buffer limit to complete this operation")
21+
// ErrorLimitStackEmpty indicates that PopLimit was called on a reader with no
22+
// limits on the stack.
23+
ErrorLimitStackEmpty = errors.New("pop limit called on empty stack")
2124
)
2225

2326
// LimitReadUntilEOF is a special dicomio.Reader limit indicating that there is no hard limit and the
@@ -176,15 +179,20 @@ func (r *Reader) PushLimit(n int64) error {
176179

177180
// PopLimit removes the most recent limit set, and restores the limit before
178181
// that one.
179-
func (r *Reader) PopLimit() {
182+
func (r *Reader) PopLimit() error {
183+
// TODO: return an error if trying to Pop the last limit off the slice
184+
last := len(r.limitStack) - 1
185+
if last < 0 {
186+
return ErrorLimitStackEmpty
187+
}
188+
180189
if r.bytesRead < r.limit && r.limit != LimitReadUntilEOF {
181190
// didn't read all the way to the limit, so skip over what's left.
182191
_ = r.Skip(r.limit - r.bytesRead)
183192
}
184-
// TODO: return an error if trying to Pop the last limit off the slice
185-
last := len(r.limitStack) - 1
186193
r.limit = r.limitStack[last]
187194
r.limitStack = r.limitStack[:last]
195+
return nil
188196
}
189197

190198
func (r *Reader) IsLimitExhausted() bool {

read.go

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,10 @@ func (r *reader) readHeader() ([]*Element, error) {
234234
if err != nil {
235235
return nil, err
236236
}
237-
defer r.rawReader.PopLimit()
237+
defer func() {
238+
// We can't really do anything if PopLimit fails here (it shouldn't)
239+
_ = r.rawReader.PopLimit()
240+
}()
238241
for !r.rawReader.IsLimitExhausted() {
239242
elem, err := r.readElement(nil, nil)
240243
if err != nil {
@@ -624,7 +627,9 @@ func (r *reader) readSequence(t tag.Tag, vr string, vl uint32, d *Dataset) (Valu
624627
// Append the Item element's dataset of elements to this Sequence's sequencesValue.
625628
sequences.value = append(sequences.value, subElement.Value.(*SequenceItemValue))
626629
}
627-
r.rawReader.PopLimit()
630+
if err := r.rawReader.PopLimit(); err != nil {
631+
return nil, err
632+
}
628633
}
629634

630635
return &sequences, nil
@@ -667,7 +672,9 @@ func (r *reader) readSequenceItem(t tag.Tag, vr string, vl uint32, d *Dataset) (
667672
sequenceItem.elements = append(sequenceItem.elements, subElem)
668673
seqElements.Elements = append(seqElements.Elements, subElem)
669674
}
670-
r.rawReader.PopLimit()
675+
if err := r.rawReader.PopLimit(); err != nil {
676+
return nil, err
677+
}
671678
}
672679

673680
return &sequenceItem, nil
@@ -766,7 +773,9 @@ func (r *reader) readFloat(t tag.Tag, vr string, vl uint32) (Value, error) {
766773
return nil, fmt.Errorf("error reading floating point element(%v) value: unsupported VR: %w", t, errorUnableToParseFloat)
767774
}
768775
}
769-
r.rawReader.PopLimit()
776+
if err := r.rawReader.PopLimit(); err != nil {
777+
return nil, err
778+
}
770779
return retVal, nil
771780
}
772781

@@ -822,7 +831,9 @@ func (r *reader) readInt(t tag.Tag, vr string, vl uint32) (Value, error) {
822831
return nil, fmt.Errorf("unable to parse integer type due to unknown VR %v", vr)
823832
}
824833
}
825-
r.rawReader.PopLimit()
834+
if err := r.rawReader.PopLimit(); err != nil {
835+
return nil, err
836+
}
826837
return retVal, err
827838
}
828839

0 commit comments

Comments
 (0)