Как я могу узнать, не произошла ли десериализация в protobuf.net? - PullRequest
1 голос
/ 22 февраля 2012

У меня protobuf.net десериализовал недопустимые (случайные) байты в KeyValuePair (то есть не обнуляемый). Вместо (как и ожидалось) генерируемого исключения возвращалась пустая структура.

Поскольку эта структура по умолчанию может быть действительными данными, я не вижу способа определить, являются ли исходные данные действительными. Это ошибка, или мне не хватает способа?

(protobuf-net 2.0.0.480, 2011.12.11)

1 Ответ

1 голос
/ 22 февраля 2012

Обновление:

В v2 были сценарии, в которых он не обнаруживал это, а вместо этого заканчивал, как если бы он достиг конца потока - в частности, если «номер поля» после применения сдвигов был неположительным. Однако это , а не допустимо в потоке protobuf, и это будет исправлено в следующей сборке.


Это зависит от того, насколько случайным он был; p На самом деле, получить что-либо для выполнения без выдачи ошибки довольно впечатляюще - спецификация protobuf довольно специфична для компоновки, и обычно будет бросать большой исключение (возможно, упоминание «неожиданного типа провода» или аналогичного).

Подчеркивание: почти во всех случаях будет выброшено исключение. Если вы удаляете некоторые данные правильной спецификации, но с разными номерами полей, тогда они будут молча игнорировать неожиданные данные, и вы получите структуру с нулем. Если вам удастся получить данные правильной спецификации, но с правильными номерами полей и разметкой, вы получите мусор. Но это все равно, что сказать

если я случайно генерирую данные, которые по чистой случайности оказываются {"foo":"0"}, JavascriptSerializer не жалуется !!! ошибка !!!

Вы уверены Вы действительно десериализовали некоторые данные здесь? и что поток уже не был позицией EOF? Например, следующее не приведет к ошибке, поскольку вы не перемотали поток - вы эффективно десериализовали ноль байтов:

var ms = new MemoryStream();
ms.Write(randomBytes, 0, randomBytes.Length);
var obj = Serializer.Deserialize<Foo>(ms);

(и ноль байтов совершенно допустим для объекта protobuf)

Если вы хотите проверить поток на достоверность, вы можете использовать ProtoReader, просто пропуская (SkipField() или что-то подобное) каждое поле, пока ReadNextHeader() (или что-то еще) не вернет неположительное целое число.

...