1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "remoting/host/native_messaging/native_messaging_writer.h" 6 7 #include <string> 8 9 #include "base/basictypes.h" 10 #include "base/json/json_writer.h" 11 12 namespace { 13 14 // 4-byte type used for the message header. 15 typedef uint32 MessageLengthType; 16 17 // Defined as an int, for passing to APIs that take an int, to avoid 18 // signed/unsigned warnings about implicit cast. 19 const int kMessageHeaderSize = sizeof(MessageLengthType); 20 21 // Limit the size of sent messages, since Chrome will not accept messages 22 // larger than 1MB, and this helps deal with the problem of integer overflow 23 // when passing sizes to net::FileStream APIs that take |int| parameters. 24 // This is defined as size_t (unsigned type) so it can be compared with the 25 // result of std::string::length() without compiler warnings. 26 const size_t kMaximumMessageSize = 1024 * 1024; 27 28 } // namespace 29 30 namespace remoting { 31 32 NativeMessagingWriter::NativeMessagingWriter(base::File file) 33 : write_stream_(file.Pass()), 34 fail_(false) { 35 } 36 37 NativeMessagingWriter::~NativeMessagingWriter() { 38 } 39 40 bool NativeMessagingWriter::WriteMessage(const base::Value& message) { 41 if (fail_) { 42 LOG(ERROR) << "Stream marked as corrupt."; 43 return false; 44 } 45 46 std::string message_json; 47 base::JSONWriter::Write(&message, &message_json); 48 49 CHECK_LE(message_json.length(), kMaximumMessageSize); 50 51 // Cast from size_t to the proper header type. The check above ensures this 52 // won't overflow. 53 MessageLengthType message_length = 54 static_cast<MessageLengthType>(message_json.length()); 55 56 int result = write_stream_.WriteAtCurrentPos( 57 reinterpret_cast<char*>(&message_length), kMessageHeaderSize); 58 if (result != kMessageHeaderSize) { 59 LOG(ERROR) << "Failed to send message header, write returned " << result; 60 fail_ = true; 61 return false; 62 } 63 64 // The length check above ensures that the cast won't overflow a signed 65 // 32-bit int. 66 int message_length_as_int = message_length; 67 68 // CHECK needed since data() is undefined on an empty std::string. 69 CHECK(!message_json.empty()); 70 result = write_stream_.WriteAtCurrentPos(message_json.data(), 71 message_length_as_int); 72 if (result != message_length_as_int) { 73 LOG(ERROR) << "Failed to send message body, write returned " << result; 74 fail_ = true; 75 return false; 76 } 77 78 return true; 79 } 80 81 } // namespace remoting 82