I've got an Image as Stream coming in and I'm trying to convert the incoming Image from whatever it maybe (even if it already is a PNG) to a PNG.
I'm doing this as part of sanitizing the image as it comes from a source I do not trust. By converting it I'm trying to get rid of any code that might have been injected into the image before I store it and return it to a frontend client at a later date.
I'm trying to do this in memory and to my knowledge it should be done like this:
Image image = Image.FromStream(stream, false, true);
using (MemoryStream ms = new MemoryStream())
{
image.Save(ms, ImageFormat.Png);
return ValidateImage(path, ms);
};
What ive noticed however is that doing it in the above way has a different result from storing the image to disk and then reading it again after ive converted it.
Image image = Image.FromStream(stream, false, true);
using (MemoryStream ms = new MemoryStream())
{
image.Save(ms, ImageFormat.Png);
File.WriteAllBytes(path, ms.ToArray());
};
using (FileStream fs = new FileStream(path, FileMode.Open))
{
return ValidateImage(path, fs);
};
My ValidateImage method at some point does this:
byte[] bytes;
using (MemoryStream ms = new MemoryStream())
{
contentStream.CopyTo(ms);
bytes = ms.ToArray();
}
if(Validate(bytes)){
}
public override bool Validate(byte[] data)
{
ImageFormat _format = new ImageFormat(new Guid("{b96b3caf-0728-11d3-9d7b-0000f81ef32e}"))
try
{
// Try to open the image
Image img;
using (Stream ms = new MemoryStream(data))
{
img = Image.FromStream(ms);
}
// Check if the format matches the expected format
return img.RawFormat.Equals(_format);
}
catch (Exception)
{
// Return false on exception
return false;
}
}
The above Validate() returns false because the RawFormat does not equal _format when I do the conversion solely in memory. It returns true when I write the file to disk and then read it in again and I'm wondering why and was hoping to find a sage who could enlighten me and help me to do the conversion solely in memory properly.
Thank you in advance
You are disposing Stream ms
in Validate()
before you are done with img
. You must keep ms
alive while img
is alive.
You also should reset the current position of MemoryStream ms
in the outer code after writing the image to it, so that ValidateImage()
sees it.