如何改变谷歌的protobuf的缓冲区限制?(How to change the buffer li

2019-07-05 02:25发布

当我尝试解析一个大消息,我后来得到这个警告和错误。 我知道的比64MB这是默认的限制。 我现在用的message.ParseFromIstream。 是否有任何人知道以访问CodedInputStream对象调用SetTotalBytesLimit功能? 或任何其他方式来解决这个问题?

读取危险大协议消息。 如果消息被证明是大于67108864个字节,解析将暂停出于安全原因。 为了增加限制(或禁用这些警告),请参阅CodedInputStream :: SetTotalBytesLimit()在谷歌/ protobuf的/ IO / coded_stream.h。

Answer 1:

正确的解决办法:你应该尽量限制你的protobuf消息的大小。 请参阅: https://developers.google.com/protocol-buffers/docs/techniques#streaming

快速和肮脏的(读不推荐)的方法:在protobuf的库源文件coded_stream.h,改变的值kDefaultTotalBytesLimitkDefaultTotalBytesWarningThreshold ,重新编译,并重新安装。



Answer 2:

只需读取错误已经告诉你有关函数的文档,就已经回答了这个问题:

提示:如果你正在读这篇文章,因为你的程序打印有关危险大的协议报文的警告,你可能会感到困惑下一步该怎么做。 最好的办法是改变设计,使得过大的消息是没有必要的。 例如,尝试设计文件格式,由许多小的消息,而不是一个单一的大单。 如果这是不可行的,则需要增加限制。 机会是,虽然,你的代码永远不会建在其上限值可设置一个CodedInputStream。 你可能通过调用之类的消息:: ParseFromString解析消息()。 在这种情况下,你需要改变你的代码,改为构建某种ZeroCopyInputStream的(例如ArrayInputStream),构建一个CodedInputStream解决这个问题,然后调用消息:: ParseFromCodedStream()代替。 然后,你可以调整的极限。 是的,它更多的工作,但你正在做一些不寻常的。

资源

此外,它可能是照做的第一部分,并重新设计应用程序一个很好的主意。



Answer 3:

下面是从代码中的注释 ( 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.


文章来源: How to change the buffer limit in Google's protobuf?