2012-12-12 69 views
8

當我嘗試解析大消息時,我收到此警告和錯誤。我知道這是默認限制64MB。我現在使用message.ParseFromIstream。是否有人知道訪問CodedInputStream對象來調用SetTotalBytesLimit函數?或以其他方式解決這個問題?如何更改Google protobuf中的緩衝區限制?

閱讀危險的大協議消息。如果消息結果爲 大於67108864字節,則解析將因安全性 原因而停止。要增加限制(或禁用這些警告),請參閱 CodedInputStream :: SetTotalBytesLimit() google/protobuf/io/coded_stream.h。

回答

8

正確的修復方法:您應該嘗試限制protobuf消息的大小。請參閱: https://developers.google.com/protocol-buffers/docs/techniques#streaming

的快速和骯髒的(讀不推薦)的方法: 在protobuf的庫源文件coded_stream.h,更改值的kDefaultTotalBytesLimitkDefaultTotalBytesWarningThreshold,重新編譯,並重新安裝。

+2

而不是建議管理你自己的protobuf代碼分支(唉),可以手動構建CodedInputStream並使用它。重新設計應用程序很可能是最佳選擇,但確實沒有理由維護自己的分支。 – Voo

+0

快速和骯髒的方法爲我工作。謝謝。 –

8

只需讀取錯誤已經告訴你有關函數的文檔,就已經回答了這個問題:

提示:如果你正在讀這篇文章,因爲你的程序是打印 警告有關危險的大型協議消息,您可能會對接下來要做的事情感到困惑。最好的選擇是改變你的設計,例如 ,那麼過大的消息是不必要的。例如,嘗試使用 設計文件格式由多個小消息組成,而不是單個大消息。如果這是不可行的,您將需要增加 限制。但是,有可能你的代碼永遠不會構造一個可以設置限制的CodedInputStream 。您可能通過調用諸如Message :: ParseFromString()之類的東西來解析 消息。在這個 的情況下,您需要將代碼更改爲ZeroCopyInputStream的某種排序 (例如ArrayInputStream),然後構造一個 CodedInputStream,然後調用 Message :: ParseFromCodedStream()。然後你可以調整 的限制。是的,這是更多的工作,但你正在做一些不尋常的事情。

Source

而且它可能照做的第一部分,並重新設計應用程序一個很好的主意。

+0

我目前的設計是這樣的。我有一個圖像消息,它有很多東西。除此之外,我還有ImageSet,它有一個重複的圖像。每個ImageSet都寫入一個文件,並且由於文件大小,我有幾個ImageSet。有沒有更好的方法來做到這一點? –

+1

不完全清楚你在做什麼,但是我個人認爲這樣做是爲了使ImageSet只包含對實際圖像的引用,這會產生相當小的消息。很顯然,每張圖片上的一條消息也不應該接近65MB的限制。您仍然可以將所有文件存儲在一個文件中,而無需額外的工作。雖然我不確定爲什麼你使用protobuf而不是數據庫,如果你只是將它存儲在本地FS中。 – Voo

+0

我的程序是一個科學應用程序,我正在分析圖像並將結果保存在文件中等。這就是爲什麼圖像消息變得非常大。 –

3

Here's a comment from the codegoogle/protobuf/io/coded_stream.h)爲那些想知道他們正在談論的安全原因的人設置消息限制。就我而言,我無法修改我的應用程序的工作方式,因此我必須更改此限制。

這個帖子已經很老了,但最近深入的學習已經得到了關注,圖書館咖啡館使用了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. 
相關問題