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 12namespace { 13 14// 4-byte type used for the message header. 15typedef 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. 19const 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. 26const size_t kMaximumMessageSize = 1024 * 1024; 27 28} // namespace 29 30namespace remoting { 31 32NativeMessagingWriter::NativeMessagingWriter(base::File file) 33 : write_stream_(file.Pass()), 34 fail_(false) { 35} 36 37NativeMessagingWriter::~NativeMessagingWriter() { 38} 39 40bool 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