| OLD | NEW |
| (Empty) |
| 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/setup/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 // Performs the same task as FileStream::WriteSync(), but ensures that exactly | |
| 29 // |buffer_length| bytes are written. Unlike WriteSync(), a partial write may | |
| 30 // only occur as a result of end-of-file or fatal error. Returns the number of | |
| 31 // bytes written (buffer_length) or an error-code <= 0. | |
| 32 // | |
| 33 // TODO(lambroslambrou): Add this method to net::FileStream, with unit-tests. | |
| 34 // See http://crbug.com/232202. | |
| 35 int WriteUntilComplete(net::FileStream* out, | |
| 36 const char* buffer, int buffer_length) { | |
| 37 int written = 0; | |
| 38 while (written < buffer_length) { | |
| 39 int result = out->WriteSync(buffer + written, buffer_length - written); | |
| 40 if (result <= 0) { | |
| 41 return result; | |
| 42 } | |
| 43 DCHECK_LE(result, buffer_length - written); | |
| 44 written += result; | |
| 45 } | |
| 46 return written; | |
| 47 } | |
| 48 | |
| 49 } // namespace | |
| 50 | |
| 51 namespace remoting { | |
| 52 | |
| 53 NativeMessagingWriter::NativeMessagingWriter(base::PlatformFile handle) | |
| 54 : write_stream_(handle, base::PLATFORM_FILE_WRITE, NULL), | |
| 55 fail_(false) { | |
| 56 } | |
| 57 | |
| 58 NativeMessagingWriter::~NativeMessagingWriter() { | |
| 59 } | |
| 60 | |
| 61 bool NativeMessagingWriter::WriteMessage(const base::Value& message) { | |
| 62 if (fail_) { | |
| 63 LOG(ERROR) << "Stream marked as corrupt."; | |
| 64 return false; | |
| 65 } | |
| 66 | |
| 67 std::string message_json; | |
| 68 base::JSONWriter::Write(&message, &message_json); | |
| 69 | |
| 70 CHECK_LE(message_json.length(), kMaximumMessageSize); | |
| 71 | |
| 72 // Cast from size_t to the proper header type. The check above ensures this | |
| 73 // won't overflow. | |
| 74 MessageLengthType message_length = | |
| 75 static_cast<MessageLengthType>(message_json.length()); | |
| 76 | |
| 77 int result = WriteUntilComplete( | |
| 78 &write_stream_, reinterpret_cast<char*>(&message_length), | |
| 79 kMessageHeaderSize); | |
| 80 if (result != kMessageHeaderSize) { | |
| 81 LOG(ERROR) << "Failed to send message header, write returned " << result; | |
| 82 fail_ = true; | |
| 83 return false; | |
| 84 } | |
| 85 | |
| 86 // The length check above ensures that the cast won't overflow a signed | |
| 87 // 32-bit int. | |
| 88 int message_length_as_int = message_length; | |
| 89 | |
| 90 // CHECK needed since data() is undefined on an empty std::string. | |
| 91 CHECK(!message_json.empty()); | |
| 92 result = WriteUntilComplete(&write_stream_, message_json.data(), | |
| 93 message_length_as_int); | |
| 94 if (result != message_length_as_int) { | |
| 95 LOG(ERROR) << "Failed to send message body, write returned " << result; | |
| 96 fail_ = true; | |
| 97 return false; | |
| 98 } | |
| 99 | |
| 100 return true; | |
| 101 } | |
| 102 | |
| 103 } // namespace remoting | |
| OLD | NEW |