11

大きなメッセージを解析しようとすると、この警告とエラーが発生します。デフォルトの制限である64MBよりも知っています。現在 message.ParseFromIstream を使用しています。CodedInputStream オブジェクトにアクセスして SetTotalBytesLimit 関数を呼び出す方法を知っている人はいますか? またはこの問題を解決する他の方法はありますか?

危険なほど大きなプロトコル メッセージを読み取っています。メッセージが 67108864 バイトを超えることが判明した場合、セキュリティ上の理由から解析が中止されます。制限を増やす (またはこれらの警告を無効にする) には、google/protobuf/io/coded_stream.h の CodedInputStream::SetTotalBytesLimit() を参照してください。

4

3 に答える 3

12

正しい修正: protobuf メッセージのサイズを制限するようにしてください。参照してください: https://developers.google.com/protocol-buffers/docs/techniques#streaming

手っ取り早い (読み取りはお勧めしません) 方法: protobuf ライブラリ ソースの coded_stream.h ファイルで、 と の値を変更しkDefaultTotalBytesLimitkDefaultTotalBytesWarningThreshold再コンパイルして、再インストールします。

于 2012-12-12T22:31:17.850 に答える
9

エラーがすでにあなたに伝えている関数のドキュメントを読むだけで、その質問に答えることができます:

ヒント: プログラムが危険なほど大きなプロトコル メッセージについて警告を出力しているためにこれを読んでいる場合は、次に何をすべきか混乱している可能性があります。最適なオプションは、過度に大きなメッセージが不要になるように設計を変更することです。たとえば、1 つの大きなメッセージではなく、多数の小さなメッセージで構成されるようにファイル形式を設計するようにしてください。これが実行不可能な場合は、制限を増やす必要があります。ただし、制限を設定できる CodedInputStream をコードが作成しない可能性があります。おそらく、Message::ParseFromString() などを呼び出してメッセージを解析します。この場合、代わりにある種の ZeroCopyInputStream (たとえば ArrayInputStream) を構築するようにコードを変更し、その周りに CodedInputStream を構築してから、代わりに Message::ParseFromCodedStream() を呼び出す必要があります。その後、制限を調整できます。はい、それはもっと仕事ですが、あなたは何か変わったことをしています.

ソース

また、アドバイスの最初の部分に従ってアプリケーションを再設計することは、おそらく本当に良い考えです。

于 2012-12-12T22:17:32.797 に答える
4

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.
于 2016-02-03T09:00:54.813 に答える