Home | History | Annotate | Download | only in native_messaging
      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