Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions pkg/dicomio/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ var (
// the current buffer (or enough bytes left until the currently set limit)
// to complete the operation.
ErrorInsufficientBytesLeft = errors.New("not enough bytes left until buffer limit to complete this operation")
// ErrorLimitStackEmpty indicates that PopLimit was called on a reader with no
// limits on the stack.
ErrorLimitStackEmpty = errors.New("pop limit called on empty stack")
)

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

// PopLimit removes the most recent limit set, and restores the limit before
// that one.
func (r *Reader) PopLimit() {
func (r *Reader) PopLimit() error {
// TODO: return an error if trying to Pop the last limit off the slice
last := len(r.limitStack) - 1
if last < 0 {
return ErrorLimitStackEmpty
}

if r.bytesRead < r.limit && r.limit != LimitReadUntilEOF {
// didn't read all the way to the limit, so skip over what's left.
_ = r.Skip(r.limit - r.bytesRead)
}
// TODO: return an error if trying to Pop the last limit off the slice
last := len(r.limitStack) - 1
r.limit = r.limitStack[last]
r.limitStack = r.limitStack[:last]
return nil
}

func (r *Reader) IsLimitExhausted() bool {
Expand Down
21 changes: 16 additions & 5 deletions read.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,10 @@ func (r *reader) readHeader() ([]*Element, error) {
if err != nil {
return nil, err
}
defer r.rawReader.PopLimit()
defer func() {
// We can't really do anything if PopLimit fails here (it shouldn't)
_ = r.rawReader.PopLimit()
}()
for !r.rawReader.IsLimitExhausted() {
elem, err := r.readElement(nil, nil)
if err != nil {
Expand Down Expand Up @@ -624,7 +627,9 @@ func (r *reader) readSequence(t tag.Tag, vr string, vl uint32, d *Dataset) (Valu
// Append the Item element's dataset of elements to this Sequence's sequencesValue.
sequences.value = append(sequences.value, subElement.Value.(*SequenceItemValue))
}
r.rawReader.PopLimit()
if err := r.rawReader.PopLimit(); err != nil {
return nil, err
}
}

return &sequences, nil
Expand Down Expand Up @@ -667,7 +672,9 @@ func (r *reader) readSequenceItem(t tag.Tag, vr string, vl uint32, d *Dataset) (
sequenceItem.elements = append(sequenceItem.elements, subElem)
seqElements.Elements = append(seqElements.Elements, subElem)
}
r.rawReader.PopLimit()
if err := r.rawReader.PopLimit(); err != nil {
return nil, err
}
}

return &sequenceItem, nil
Expand Down Expand Up @@ -766,7 +773,9 @@ func (r *reader) readFloat(t tag.Tag, vr string, vl uint32) (Value, error) {
return nil, fmt.Errorf("error reading floating point element(%v) value: unsupported VR: %w", t, errorUnableToParseFloat)
}
}
r.rawReader.PopLimit()
if err := r.rawReader.PopLimit(); err != nil {
return nil, err
}
return retVal, nil
}

Expand Down Expand Up @@ -822,7 +831,9 @@ func (r *reader) readInt(t tag.Tag, vr string, vl uint32) (Value, error) {
return nil, fmt.Errorf("unable to parse integer type due to unknown VR %v", vr)
}
}
r.rawReader.PopLimit()
if err := r.rawReader.PopLimit(); err != nil {
return nil, err
}
return retVal, err
}

Expand Down