当我尝试解析一条大邮件时,我收到此警告并出现错误。我知道64MB是默认限制。我现在正在使用message.ParseFromIstream。有没有人知道访问CodedInputStream对象来调用SetTotalBytesLimit函数?或任何其他方式来解决这个问题?
读取危险的大型协议消息。如果消息结果 要大于67108864字节,将停止解析以确保安全性 原因。要增加限制(或禁用这些警告),请参阅 CodedInputStream :: SetTotalBytesLimit()in 谷歌/ protobuf的/ IO / coded_stream.h。
答案 0 :(得分:9)
只要阅读错误已经告诉过你的函数的文档,就会回答这个问题:
提示:如果您正在阅读此内容,因为您的程序正在打印 关于危险的大型协议消息的警告,你可能会感到困惑 关于下一步该怎么做。最好的选择是改变你的设计 不需要过大的消息。例如,尝试 设计文件格式由许多小消息而不是一个 单个大的。如果这是不可行的,你需要增加 限制。但是,您的代码可能永远不会构造一个 可以设置限制的CodedInputStream。你可能会解析 消息通过调用Message :: ParseFromString()之类的东西。在这 例如,您需要将代码更改为构造某种类型 的ZeroCopyInputStream(例如一个ArrayInputStream),构造一个 围绕那个CodedInputStream,然后调用 而是Message :: ParseFromCodedStream()。然后你可以调整 限制。是的,这是更多的工作,但你正在做一些不寻常的事情。
此外,遵循建议的第一部分并重新设计应用程序可能是一个非常好的主意。
答案 1 :(得分:9)
正确修复:您应该尝试限制protobuf消息的大小。请参阅: https://developers.google.com/protocol-buffers/docs/techniques#streaming
快速而肮脏(不推荐阅读)的方法:
在protobuf库源的coded_stream.h文件中,更改kDefaultTotalBytesLimit
和kDefaultTotalBytesWarningThreshold
的值,重新编译并重新安装。
答案 2 :(得分:4)
Here's a comment from the code(google/protobuf/io/coded_stream.h
)为那些想知道他们正在谈论的安全原因的人设置了信息限制。在我的情况下,我无法修改我的应用程序的工作方式,因此我必须更改此限制。
这个帖子已经很老了,但是最近深度学习引起了人们的注意,图书馆Caffe使用了Protobuf,所以也许更多的人会偶然发现这一点。我必须使用Caffe进行神经网络的操作,即使批量最小,整个网络也会占用大量内存。
// Total Bytes Limit -----------------------------------------------
// To prevent malicious users from sending excessively large messages
// and causing integer overflows or memory exhaustion, CodedInputStream
// imposes a hard limit on the total number of bytes it will read.
// Sets the maximum number of bytes that this CodedInputStream will read
// before refusing to continue. To prevent integer overflows in the
// protocol buffers implementation, as well as to prevent servers from
// allocating enormous amounts of memory to hold parsed messages, the
// maximum message length should be limited to the shortest length that
// will not harm usability. The theoretical shortest message that could
// cause integer overflows is 512MB. The default limit is 64MB. Apps
// should set shorter limits if possible. If warning_threshold is not -1,
// a warning will be printed to stderr after warning_threshold bytes are
// read. For backwards compatibility all negative values get squashed to -1,
// as other negative values might have special internal meanings.
// An error will always be printed to stderr if the limit is reached.
//
// This is unrelated to PushLimit()/PopLimit().
//
// Hint: If you are reading this because your program is printing a
// warning about dangerously large protocol messages, you may be
// confused about what to do next. The best option is to change your
// design such that excessively large messages are not necessary.
// For example, try to design file formats to consist of many small
// messages rather than a single large one. If this is infeasible,
// you will need to increase the limit. Chances are, though, that
// your code never constructs a CodedInputStream on which the limit
// can be set. You probably parse messages by calling things like
// Message::ParseFromString(). In this case, you will need to change
// your code to instead construct some sort of ZeroCopyInputStream
// (e.g. an ArrayInputStream), construct a CodedInputStream around
// that, then call Message::ParseFromCodedStream() instead. Then
// you can adjust the limit. Yes, it's more work, but you're doing
// something unusual.