Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incomplete data returned from StreamByteBuffer #1313

Closed
jovinson-ms opened this issue Jan 22, 2022 · 6 comments · Fixed by #1315
Closed

Incomplete data returned from StreamByteBuffer #1313

jovinson-ms opened this issue Jan 22, 2022 · 6 comments · Fixed by #1315
Labels

Comments

@jovinson-ms
Copy link
Contributor

Describe the bug

Summary: stream reading in StreamByteBuffer is incomplete.
When a DicomFile is created from a Stream, by default large tags will be saved as a StreamByteBuffer, so that the data can be retrieved on demand but not block other operations. When the bytes are requested from the StreamByteBuffer, the Data accessor and GetByteRange both make a single call to Stream.Read. However, the underlying Stream is not guaranteed to have all of the requested bytes available, and so what can be returned is a byte array with only part of the requested data.

This came to light in the context of an Azure Storage LazyLoadingReadOnlyStream, which buffers 4MB by default. The returned byte array for a pixel data element > 4MB will have 4MB of data and the rest of the array will be null values.

As this issue makes clear, this is expected behavior for all Streams, and so the consumer should check the return value of calls to Stream.Read until no more bytes are returned. The same logic is already implemented in the CopyToStream* methods.

To Reproduce
Here's a code sample that uses a toy buffered stream to simulate the buffering behavior, and gets StreamByteBuffer.Data with the existing logic (which results in incomplete data) versus updated logic (which results in complete data).

Expected behavior
I expect StreamByteBuffer.Data to return the entire requested range of bytes. There should be no concerns about blocking since this is an on-demand retrieval.

Environment
Fellow Oak DICOM version: (5.0.2)
OS: (Windows 10 x64)
Platform: (all)

@gofal gofal added bug and removed new labels Jan 23, 2022
@gofal
Copy link
Contributor

gofal commented Jan 23, 2022

Thats a very good point, Thanks for showing up this issue and also for presenting the solution.
So the solution is simple: the StreamByteBuffer.Data getter needs to have that do-while loop. In case hte underlying stream always has the data, this will only execute the body of this loop once, so it is not worse that until now. But in case the underlying stream does buffering, this solves the issue.

Do you want to make a PR for that?

@jovinson-ms
Copy link
Contributor Author

Sure, I'll get one up.

@jovinson-ms
Copy link
Contributor Author

When should I expect this fix to be released? Looking forward to pulling the changes.

@gofal
Copy link
Contributor

gofal commented Feb 8, 2022

usually there is a release every few months.
There are no special actions assigned with a release. We take the code from development branch, create nuget-packag from that and publish it on nuget. There is quite some administrative internal work, like updating some readmes, update api-doc, etc.
So if you want to have the bugfix in your product, then you can take the code from here as it is. Or do you require the nuget-package from nuget.org for some certain reason?

@jovinson-ms
Copy link
Contributor Author

Thanks, @gofal - we currently consume the nuget package as part of https://github.com/microsoft/dicom-server. That's the main way we prefer to consume the code for a few different reasons, but we'll look into building based on a pinned commit.

I don't intend to pester the maintainers for small fixes / bugs but I thought this was a pretty important fix since it causes data to be missing in a request. We do have a workaround using ReadAll, so we should be ok for now.

@gofal
Copy link
Contributor

gofal commented Feb 9, 2022

Sure, I see. This bugfix will justify a release. I will plan to do an update until next week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants