Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Safely access data in MemoryStream

Assume that I have a MemoryStream and function that operates on bytes.

Current code is something like this:

void caller()
{
    MemoryStream ms = // not important
    func(ms.GetBuffer(), 0, (int)ms.Length);
}

void func(byte[] buffer, int offset, int length)
{
    // not important
}

I can not change func but I would like to minimize possibility of changing stream data from within the func.

How could / should I rewrite the code to be sure that stream data won't be changed?

Or this can't be done?

EDIT:

I am sorry, I didn't mention that a I would like to not make copies of data.

like image 250
Bobrovsky Avatar asked Dec 18 '25 10:12

Bobrovsky


2 Answers

Call .ToArray.

func(ms.GetBuffer().ToArray(), 0, (int)ms.Length);

From MSDN (emphasis mine):

Note that the buffer contains allocated bytes which might be unused. For example, if the string "test" is written into the MemoryStream object, the length of the buffer returned from GetBuffer is 256, not 4, with 252 bytes unused. To obtain only the data in the buffer, use the ToArray method; however, ToArray creates a copy of the data in memory.


Ideally you would change func to take an IEnumerable<byte>. Once a method has the array, you're trusting they won't modify the data if you don't want them to. If the contract was to provide IEnumerable<byte>, the implementer would have to decide if they need a copy to edit or not.

like image 156
Austin Salonen Avatar answered Dec 20 '25 23:12

Austin Salonen


If you can't make a copy (ToArray as suggested in other answers) and can't change signature of the func function the only thing left is try to validate that function did not change the data.

You may compute some sort of hash before/after call and check if it is the same. It will not guarantee that func did not changed the underlying data (due to hash collisions), but at least will give you good chance to know if it happened. May be useful for non-production code...

The real solution is to either provide copy of the data to untrusted code OR pass some wrapper interface/object that does not allow data changes (requires signature changes/rewrite for func).

like image 34
Alexei Levenkov Avatar answered Dec 20 '25 22:12

Alexei Levenkov