message.cc 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080
  1. // Copyright (c) 2012 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. #include "dbus/message.h"
  5. #include <string>
  6. #include "base/format_macros.h"
  7. #include "base/logging.h"
  8. #include "base/notreached.h"
  9. #include "base/numerics/safe_conversions.h"
  10. #include "base/strings/string_number_conversions.h"
  11. #include "base/strings/string_util.h"
  12. #include "base/strings/stringprintf.h"
  13. #include "dbus/object_path.h"
  14. #include "third_party/protobuf/src/google/protobuf/message_lite.h"
  15. namespace {
  16. // Appends the header name and the value to |output|, if the value is
  17. // not empty.
  18. void AppendStringHeader(const std::string& header_name,
  19. const std::string& header_value,
  20. std::string* output) {
  21. if (!header_value.empty()) {
  22. *output += header_name + ": " + header_value + "\n";
  23. }
  24. }
  25. // Appends the header name and the value to |output|, if the value is
  26. // nonzero.
  27. void AppendUint32Header(const std::string& header_name,
  28. uint32_t header_value,
  29. std::string* output) {
  30. if (header_value != 0) {
  31. *output += (header_name + ": " + base::NumberToString(header_value) + "\n");
  32. }
  33. }
  34. } // namespace
  35. namespace dbus {
  36. bool IsDBusTypeUnixFdSupported() {
  37. int major = 0, minor = 0, micro = 0;
  38. dbus_get_version(&major, &minor, &micro);
  39. return major >= 1 && minor >= 4;
  40. }
  41. Message::Message() : raw_message_(nullptr) {}
  42. Message::~Message() {
  43. if (raw_message_)
  44. dbus_message_unref(raw_message_);
  45. }
  46. void Message::Init(DBusMessage* raw_message) {
  47. DCHECK(!raw_message_);
  48. raw_message_ = raw_message;
  49. }
  50. Message::MessageType Message::GetMessageType() {
  51. if (!raw_message_)
  52. return MESSAGE_INVALID;
  53. const int type = dbus_message_get_type(raw_message_);
  54. return static_cast<Message::MessageType>(type);
  55. }
  56. std::string Message::GetMessageTypeAsString() {
  57. switch (GetMessageType()) {
  58. case MESSAGE_INVALID:
  59. return "MESSAGE_INVALID";
  60. case MESSAGE_METHOD_CALL:
  61. return "MESSAGE_METHOD_CALL";
  62. case MESSAGE_METHOD_RETURN:
  63. return "MESSAGE_METHOD_RETURN";
  64. case MESSAGE_SIGNAL:
  65. return "MESSAGE_SIGNAL";
  66. case MESSAGE_ERROR:
  67. return "MESSAGE_ERROR";
  68. }
  69. NOTREACHED();
  70. return std::string();
  71. }
  72. std::string Message::ToStringInternal(const std::string& indent,
  73. MessageReader* reader) {
  74. const char* kBrokenMessage = "[broken message]";
  75. std::string output;
  76. while (reader->HasMoreData()) {
  77. const DataType type = reader->GetDataType();
  78. switch (type) {
  79. case BYTE: {
  80. uint8_t value = 0;
  81. if (!reader->PopByte(&value))
  82. return kBrokenMessage;
  83. output += indent + "byte " + base::NumberToString(value) + "\n";
  84. break;
  85. }
  86. case BOOL: {
  87. bool value = false;
  88. if (!reader->PopBool(&value))
  89. return kBrokenMessage;
  90. output += indent + "bool " + (value ? "true" : "false") + "\n";
  91. break;
  92. }
  93. case INT16: {
  94. int16_t value = 0;
  95. if (!reader->PopInt16(&value))
  96. return kBrokenMessage;
  97. output += indent + "int16_t " + base::NumberToString(value) + "\n";
  98. break;
  99. }
  100. case UINT16: {
  101. uint16_t value = 0;
  102. if (!reader->PopUint16(&value))
  103. return kBrokenMessage;
  104. output += indent + "uint16_t " + base::NumberToString(value) + "\n";
  105. break;
  106. }
  107. case INT32: {
  108. int32_t value = 0;
  109. if (!reader->PopInt32(&value))
  110. return kBrokenMessage;
  111. output += indent + "int32_t " + base::NumberToString(value) + "\n";
  112. break;
  113. }
  114. case UINT32: {
  115. uint32_t value = 0;
  116. if (!reader->PopUint32(&value))
  117. return kBrokenMessage;
  118. output += indent + "uint32_t " + base::NumberToString(value) + "\n";
  119. break;
  120. }
  121. case INT64: {
  122. int64_t value = 0;
  123. if (!reader->PopInt64(&value))
  124. return kBrokenMessage;
  125. output += (indent + "int64_t " + base::NumberToString(value) + "\n");
  126. break;
  127. }
  128. case UINT64: {
  129. uint64_t value = 0;
  130. if (!reader->PopUint64(&value))
  131. return kBrokenMessage;
  132. output += (indent + "uint64_t " + base::NumberToString(value) + "\n");
  133. break;
  134. }
  135. case DOUBLE: {
  136. double value = 0;
  137. if (!reader->PopDouble(&value))
  138. return kBrokenMessage;
  139. output += indent + "double " + base::NumberToString(value) + "\n";
  140. break;
  141. }
  142. case STRING: {
  143. std::string value;
  144. if (!reader->PopString(&value))
  145. return kBrokenMessage;
  146. // Truncate if the string is longer than the limit.
  147. const size_t kTruncateLength = 100;
  148. if (value.size() < kTruncateLength) {
  149. output += indent + "string \"" + value + "\"\n";
  150. } else {
  151. std::string truncated;
  152. base::TruncateUTF8ToByteSize(value, kTruncateLength, &truncated);
  153. base::StringAppendF(&truncated, "... (%" PRIuS " bytes in total)",
  154. value.size());
  155. output += indent + "string \"" + truncated + "\"\n";
  156. }
  157. break;
  158. }
  159. case OBJECT_PATH: {
  160. ObjectPath value;
  161. if (!reader->PopObjectPath(&value))
  162. return kBrokenMessage;
  163. output += indent + "object_path \"" + value.value() + "\"\n";
  164. break;
  165. }
  166. case ARRAY: {
  167. MessageReader sub_reader(this);
  168. if (!reader->PopArray(&sub_reader))
  169. return kBrokenMessage;
  170. output += indent + "array [\n";
  171. output += ToStringInternal(indent + " ", &sub_reader);
  172. output += indent + "]\n";
  173. break;
  174. }
  175. case STRUCT: {
  176. MessageReader sub_reader(this);
  177. if (!reader->PopStruct(&sub_reader))
  178. return kBrokenMessage;
  179. output += indent + "struct {\n";
  180. output += ToStringInternal(indent + " ", &sub_reader);
  181. output += indent + "}\n";
  182. break;
  183. }
  184. case DICT_ENTRY: {
  185. MessageReader sub_reader(this);
  186. if (!reader->PopDictEntry(&sub_reader))
  187. return kBrokenMessage;
  188. output += indent + "dict entry {\n";
  189. output += ToStringInternal(indent + " ", &sub_reader);
  190. output += indent + "}\n";
  191. break;
  192. }
  193. case VARIANT: {
  194. MessageReader sub_reader(this);
  195. if (!reader->PopVariant(&sub_reader))
  196. return kBrokenMessage;
  197. output += indent + "variant ";
  198. output += ToStringInternal(indent + " ", &sub_reader);
  199. break;
  200. }
  201. case UNIX_FD: {
  202. CHECK(IsDBusTypeUnixFdSupported());
  203. base::ScopedFD file_descriptor;
  204. if (!reader->PopFileDescriptor(&file_descriptor))
  205. return kBrokenMessage;
  206. output +=
  207. indent + "fd#" + base::NumberToString(file_descriptor.get()) + "\n";
  208. break;
  209. }
  210. default:
  211. LOG(FATAL) << "Unknown type: " << type;
  212. }
  213. }
  214. return output;
  215. }
  216. // The returned string consists of message headers such as
  217. // destination if any, followed by a blank line, and the message
  218. // payload. For example, a MethodCall's ToString() will look like:
  219. //
  220. // destination: com.example.Service
  221. // path: /com/example/Object
  222. // interface: com.example.Interface
  223. // member: SomeMethod
  224. //
  225. // string \"payload\"
  226. // ...
  227. std::string Message::ToString() {
  228. if (!raw_message_)
  229. return std::string();
  230. // Generate headers first.
  231. std::string headers;
  232. AppendStringHeader("message_type", GetMessageTypeAsString(), &headers);
  233. AppendStringHeader("destination", GetDestination(), &headers);
  234. AppendStringHeader("path", GetPath().value(), &headers);
  235. AppendStringHeader("interface", GetInterface(), &headers);
  236. AppendStringHeader("member", GetMember(), &headers);
  237. AppendStringHeader("error_name", GetErrorName(), &headers);
  238. AppendStringHeader("sender", GetSender(), &headers);
  239. AppendStringHeader("signature", GetSignature(), &headers);
  240. AppendUint32Header("serial", GetSerial(), &headers);
  241. AppendUint32Header("reply_serial", GetReplySerial(), &headers);
  242. // Generate the payload.
  243. MessageReader reader(this);
  244. return headers + "\n" + ToStringInternal(std::string(), &reader);
  245. }
  246. bool Message::SetDestination(const std::string& destination) {
  247. if (!dbus_validate_bus_name(destination.c_str(), nullptr)) {
  248. LOG(ERROR) << "Invalid bus name: " << destination;
  249. return false;
  250. }
  251. return dbus_message_set_destination(raw_message_, destination.c_str());
  252. }
  253. bool Message::SetPath(const ObjectPath& path) {
  254. if (!path.IsValid()) {
  255. LOG(ERROR) << "Invalid path: " << path.value();
  256. return false;
  257. }
  258. return dbus_message_set_path(raw_message_, path.value().c_str());
  259. }
  260. bool Message::SetInterface(const std::string& interface) {
  261. if (!dbus_validate_interface(interface.c_str(), nullptr)) {
  262. LOG(ERROR) << "Invalid interface: " << interface;
  263. return false;
  264. }
  265. return dbus_message_set_interface(raw_message_, interface.c_str());
  266. }
  267. bool Message::SetMember(const std::string& member) {
  268. if (!dbus_validate_member(member.c_str(), nullptr)) {
  269. LOG(ERROR) << "Invalid member: " << member;
  270. return false;
  271. }
  272. return dbus_message_set_member(raw_message_, member.c_str());
  273. }
  274. bool Message::SetErrorName(const std::string& error_name) {
  275. if (!dbus_validate_error_name(error_name.c_str(), nullptr)) {
  276. LOG(ERROR) << "Invalid error name: " << error_name;
  277. return false;
  278. }
  279. return dbus_message_set_error_name(raw_message_, error_name.c_str());
  280. }
  281. bool Message::SetSender(const std::string& sender) {
  282. if (!dbus_validate_bus_name(sender.c_str(), nullptr)) {
  283. LOG(ERROR) << "Invalid bus name: " << sender;
  284. return false;
  285. }
  286. return dbus_message_set_sender(raw_message_, sender.c_str());
  287. }
  288. void Message::SetSerial(uint32_t serial) {
  289. dbus_message_set_serial(raw_message_, serial);
  290. }
  291. void Message::SetReplySerial(uint32_t reply_serial) {
  292. dbus_message_set_reply_serial(raw_message_, reply_serial);
  293. }
  294. std::string Message::GetDestination() {
  295. const char* destination = dbus_message_get_destination(raw_message_);
  296. return destination ? destination : "";
  297. }
  298. ObjectPath Message::GetPath() {
  299. const char* path = dbus_message_get_path(raw_message_);
  300. return ObjectPath(path ? path : "");
  301. }
  302. std::string Message::GetInterface() {
  303. const char* interface = dbus_message_get_interface(raw_message_);
  304. return interface ? interface : "";
  305. }
  306. std::string Message::GetMember() {
  307. const char* member = dbus_message_get_member(raw_message_);
  308. return member ? member : "";
  309. }
  310. std::string Message::GetErrorName() {
  311. const char* error_name = dbus_message_get_error_name(raw_message_);
  312. return error_name ? error_name : "";
  313. }
  314. std::string Message::GetSender() {
  315. const char* sender = dbus_message_get_sender(raw_message_);
  316. return sender ? sender : "";
  317. }
  318. std::string Message::GetSignature() {
  319. const char* signature = dbus_message_get_signature(raw_message_);
  320. return signature ? signature : "";
  321. }
  322. uint32_t Message::GetSerial() {
  323. return dbus_message_get_serial(raw_message_);
  324. }
  325. uint32_t Message::GetReplySerial() {
  326. return dbus_message_get_reply_serial(raw_message_);
  327. }
  328. //
  329. // MethodCall implementation.
  330. //
  331. MethodCall::MethodCall(const std::string& interface_name,
  332. const std::string& method_name) {
  333. Init(dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL));
  334. CHECK(SetInterface(interface_name));
  335. CHECK(SetMember(method_name));
  336. }
  337. MethodCall::MethodCall() = default;
  338. std::unique_ptr<MethodCall> MethodCall::FromRawMessage(
  339. DBusMessage* raw_message) {
  340. DCHECK_EQ(DBUS_MESSAGE_TYPE_METHOD_CALL, dbus_message_get_type(raw_message));
  341. std::unique_ptr<MethodCall> method_call(new MethodCall());
  342. method_call->Init(raw_message);
  343. return method_call;
  344. }
  345. //
  346. // Signal implementation.
  347. //
  348. Signal::Signal(const std::string& interface_name,
  349. const std::string& method_name) {
  350. Init(dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL));
  351. CHECK(SetInterface(interface_name));
  352. CHECK(SetMember(method_name));
  353. }
  354. Signal::Signal() = default;
  355. std::unique_ptr<Signal> Signal::FromRawMessage(DBusMessage* raw_message) {
  356. DCHECK_EQ(DBUS_MESSAGE_TYPE_SIGNAL, dbus_message_get_type(raw_message));
  357. std::unique_ptr<Signal> signal(new Signal());
  358. signal->Init(raw_message);
  359. return signal;
  360. }
  361. //
  362. // Response implementation.
  363. //
  364. Response::Response() = default;
  365. std::unique_ptr<Response> Response::FromRawMessage(DBusMessage* raw_message) {
  366. DCHECK_EQ(DBUS_MESSAGE_TYPE_METHOD_RETURN,
  367. dbus_message_get_type(raw_message));
  368. std::unique_ptr<Response> response(new Response());
  369. response->Init(raw_message);
  370. return response;
  371. }
  372. std::unique_ptr<Response> Response::FromMethodCall(MethodCall* method_call) {
  373. std::unique_ptr<Response> response(new Response());
  374. response->Init(dbus_message_new_method_return(method_call->raw_message()));
  375. return response;
  376. }
  377. std::unique_ptr<Response> Response::CreateEmpty() {
  378. std::unique_ptr<Response> response(new Response());
  379. response->Init(dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN));
  380. return response;
  381. }
  382. //
  383. // ErrorResponse implementation.
  384. //
  385. ErrorResponse::ErrorResponse() = default;
  386. std::unique_ptr<ErrorResponse> ErrorResponse::FromRawMessage(
  387. DBusMessage* raw_message) {
  388. DCHECK_EQ(DBUS_MESSAGE_TYPE_ERROR, dbus_message_get_type(raw_message));
  389. std::unique_ptr<ErrorResponse> response(new ErrorResponse());
  390. response->Init(raw_message);
  391. return response;
  392. }
  393. std::unique_ptr<ErrorResponse> ErrorResponse::FromMethodCall(
  394. MethodCall* method_call,
  395. const std::string& error_name,
  396. const std::string& error_message) {
  397. std::unique_ptr<ErrorResponse> response(new ErrorResponse());
  398. response->Init(dbus_message_new_error(
  399. method_call->raw_message(), error_name.c_str(), error_message.c_str()));
  400. return response;
  401. }
  402. //
  403. // MessageWriter implementation.
  404. //
  405. MessageWriter::MessageWriter(Message* message)
  406. : message_(message), container_is_open_(false) {
  407. memset(&raw_message_iter_, 0, sizeof(raw_message_iter_));
  408. if (message)
  409. dbus_message_iter_init_append(message_->raw_message(), &raw_message_iter_);
  410. }
  411. MessageWriter::~MessageWriter() = default;
  412. void MessageWriter::AppendByte(uint8_t value) {
  413. AppendBasic(DBUS_TYPE_BYTE, &value);
  414. }
  415. void MessageWriter::AppendBool(bool value) {
  416. // The size of dbus_bool_t and the size of bool are different. The
  417. // former is always 4 per dbus-types.h, whereas the latter is usually 1.
  418. // dbus_message_iter_append_basic() used in AppendBasic() expects four
  419. // bytes for DBUS_TYPE_BOOLEAN, so we must pass a dbus_bool_t, instead
  420. // of a bool, to AppendBasic().
  421. dbus_bool_t dbus_value = value ? 1 : 0;
  422. AppendBasic(DBUS_TYPE_BOOLEAN, &dbus_value);
  423. }
  424. void MessageWriter::AppendInt16(int16_t value) {
  425. AppendBasic(DBUS_TYPE_INT16, &value);
  426. }
  427. void MessageWriter::AppendUint16(uint16_t value) {
  428. AppendBasic(DBUS_TYPE_UINT16, &value);
  429. }
  430. void MessageWriter::AppendInt32(int32_t value) {
  431. AppendBasic(DBUS_TYPE_INT32, &value);
  432. }
  433. void MessageWriter::AppendUint32(uint32_t value) {
  434. AppendBasic(DBUS_TYPE_UINT32, &value);
  435. }
  436. void MessageWriter::AppendInt64(int64_t value) {
  437. AppendBasic(DBUS_TYPE_INT64, &value);
  438. }
  439. void MessageWriter::AppendUint64(uint64_t value) {
  440. AppendBasic(DBUS_TYPE_UINT64, &value);
  441. }
  442. void MessageWriter::AppendDouble(double value) {
  443. AppendBasic(DBUS_TYPE_DOUBLE, &value);
  444. }
  445. void MessageWriter::AppendString(base::StringPiece value) {
  446. // D-Bus Specification (0.19) says a string "must be valid UTF-8".
  447. CHECK(base::IsStringUTF8(value));
  448. const char* pointer = value.data() ? value.data() : "";
  449. AppendBasic(DBUS_TYPE_STRING, &pointer);
  450. // TODO(satorux): It may make sense to return an error here, as the
  451. // input string can be large. If needed, we could add something like
  452. // bool AppendStringWithErrorChecking().
  453. }
  454. void MessageWriter::AppendObjectPath(const ObjectPath& value) {
  455. CHECK(value.IsValid());
  456. const char* pointer = value.value().c_str();
  457. AppendBasic(DBUS_TYPE_OBJECT_PATH, &pointer);
  458. }
  459. // Ideally, client shouldn't need to supply the signature string, but
  460. // the underlying D-Bus library requires us to supply this before
  461. // appending contents to array and variant. It's technically possible
  462. // for us to design API that doesn't require the signature but it will
  463. // complicate the implementation so we decided to have the signature
  464. // parameter. Hopefully, variants are less used in request messages from
  465. // client side than response message from server side, so this should
  466. // not be a big issue.
  467. void MessageWriter::OpenArray(const std::string& signature,
  468. MessageWriter* writer) {
  469. DCHECK(!container_is_open_);
  470. const bool success = dbus_message_iter_open_container(
  471. &raw_message_iter_, DBUS_TYPE_ARRAY, signature.c_str(),
  472. &writer->raw_message_iter_);
  473. CHECK(success) << "Unable to allocate memory";
  474. container_is_open_ = true;
  475. }
  476. void MessageWriter::OpenVariant(const std::string& signature,
  477. MessageWriter* writer) {
  478. DCHECK(!container_is_open_);
  479. const bool success = dbus_message_iter_open_container(
  480. &raw_message_iter_, DBUS_TYPE_VARIANT, signature.c_str(),
  481. &writer->raw_message_iter_);
  482. CHECK(success) << "Unable to allocate memory";
  483. container_is_open_ = true;
  484. }
  485. void MessageWriter::OpenStruct(MessageWriter* writer) {
  486. DCHECK(!container_is_open_);
  487. const bool success =
  488. dbus_message_iter_open_container(&raw_message_iter_, DBUS_TYPE_STRUCT,
  489. nullptr, // Signature should be nullptr.
  490. &writer->raw_message_iter_);
  491. CHECK(success) << "Unable to allocate memory";
  492. container_is_open_ = true;
  493. }
  494. void MessageWriter::OpenDictEntry(MessageWriter* writer) {
  495. DCHECK(!container_is_open_);
  496. const bool success =
  497. dbus_message_iter_open_container(&raw_message_iter_, DBUS_TYPE_DICT_ENTRY,
  498. nullptr, // Signature should be nullptr.
  499. &writer->raw_message_iter_);
  500. CHECK(success) << "Unable to allocate memory";
  501. container_is_open_ = true;
  502. }
  503. void MessageWriter::CloseContainer(MessageWriter* writer) {
  504. DCHECK(container_is_open_);
  505. const bool success = dbus_message_iter_close_container(
  506. &raw_message_iter_, &writer->raw_message_iter_);
  507. CHECK(success) << "Unable to allocate memory";
  508. container_is_open_ = false;
  509. }
  510. void MessageWriter::AppendArrayOfBytes(const uint8_t* values, size_t length) {
  511. DCHECK(!container_is_open_);
  512. MessageWriter array_writer(message_);
  513. OpenArray("y", &array_writer);
  514. const bool success = dbus_message_iter_append_fixed_array(
  515. &(array_writer.raw_message_iter_), DBUS_TYPE_BYTE, &values,
  516. static_cast<int>(length));
  517. CHECK(success) << "Unable to allocate memory";
  518. CloseContainer(&array_writer);
  519. }
  520. void MessageWriter::AppendArrayOfInt32s(const int32_t* values, size_t length) {
  521. DCHECK(!container_is_open_);
  522. MessageWriter array_writer(message_);
  523. OpenArray("i", &array_writer);
  524. const bool success = dbus_message_iter_append_fixed_array(
  525. &(array_writer.raw_message_iter_), DBUS_TYPE_INT32, &values,
  526. static_cast<int>(length));
  527. CHECK(success) << "Unable to allocate memory";
  528. CloseContainer(&array_writer);
  529. }
  530. void MessageWriter::AppendArrayOfUint32s(const uint32_t* values,
  531. size_t length) {
  532. DCHECK(!container_is_open_);
  533. MessageWriter array_writer(message_);
  534. OpenArray("u", &array_writer);
  535. const bool success = dbus_message_iter_append_fixed_array(
  536. &(array_writer.raw_message_iter_), DBUS_TYPE_UINT32, &values,
  537. static_cast<int>(length));
  538. CHECK(success) << "Unable to allocate memory";
  539. CloseContainer(&array_writer);
  540. }
  541. void MessageWriter::AppendArrayOfDoubles(const double* values, size_t length) {
  542. DCHECK(!container_is_open_);
  543. MessageWriter array_writer(message_);
  544. OpenArray("d", &array_writer);
  545. const bool success = dbus_message_iter_append_fixed_array(
  546. &(array_writer.raw_message_iter_), DBUS_TYPE_DOUBLE, &values,
  547. static_cast<int>(length));
  548. CHECK(success) << "Unable to allocate memory";
  549. CloseContainer(&array_writer);
  550. }
  551. void MessageWriter::AppendArrayOfStrings(
  552. const std::vector<std::string>& strings) {
  553. DCHECK(!container_is_open_);
  554. MessageWriter array_writer(message_);
  555. OpenArray("s", &array_writer);
  556. for (size_t i = 0; i < strings.size(); ++i) {
  557. array_writer.AppendString(strings[i]);
  558. }
  559. CloseContainer(&array_writer);
  560. }
  561. void MessageWriter::AppendArrayOfObjectPaths(
  562. const std::vector<ObjectPath>& object_paths) {
  563. DCHECK(!container_is_open_);
  564. MessageWriter array_writer(message_);
  565. OpenArray("o", &array_writer);
  566. for (size_t i = 0; i < object_paths.size(); ++i) {
  567. array_writer.AppendObjectPath(object_paths[i]);
  568. }
  569. CloseContainer(&array_writer);
  570. }
  571. bool MessageWriter::AppendProtoAsArrayOfBytes(
  572. const google::protobuf::MessageLite& protobuf) {
  573. std::string serialized_proto;
  574. if (!protobuf.SerializeToString(&serialized_proto)) {
  575. LOG(ERROR) << "Unable to serialize supplied protocol buffer";
  576. return false;
  577. }
  578. AppendArrayOfBytes(reinterpret_cast<const uint8_t*>(serialized_proto.data()),
  579. serialized_proto.size());
  580. return true;
  581. }
  582. void MessageWriter::AppendVariantOfByte(uint8_t value) {
  583. AppendVariantOfBasic(DBUS_TYPE_BYTE, &value);
  584. }
  585. void MessageWriter::AppendVariantOfBool(bool value) {
  586. // See the comment at MessageWriter::AppendBool().
  587. dbus_bool_t dbus_value = value;
  588. AppendVariantOfBasic(DBUS_TYPE_BOOLEAN, &dbus_value);
  589. }
  590. void MessageWriter::AppendVariantOfInt16(int16_t value) {
  591. AppendVariantOfBasic(DBUS_TYPE_INT16, &value);
  592. }
  593. void MessageWriter::AppendVariantOfUint16(uint16_t value) {
  594. AppendVariantOfBasic(DBUS_TYPE_UINT16, &value);
  595. }
  596. void MessageWriter::AppendVariantOfInt32(int32_t value) {
  597. AppendVariantOfBasic(DBUS_TYPE_INT32, &value);
  598. }
  599. void MessageWriter::AppendVariantOfUint32(uint32_t value) {
  600. AppendVariantOfBasic(DBUS_TYPE_UINT32, &value);
  601. }
  602. void MessageWriter::AppendVariantOfInt64(int64_t value) {
  603. AppendVariantOfBasic(DBUS_TYPE_INT64, &value);
  604. }
  605. void MessageWriter::AppendVariantOfUint64(uint64_t value) {
  606. AppendVariantOfBasic(DBUS_TYPE_UINT64, &value);
  607. }
  608. void MessageWriter::AppendVariantOfDouble(double value) {
  609. AppendVariantOfBasic(DBUS_TYPE_DOUBLE, &value);
  610. }
  611. void MessageWriter::AppendVariantOfString(const std::string& value) {
  612. const char* pointer = value.c_str();
  613. AppendVariantOfBasic(DBUS_TYPE_STRING, &pointer);
  614. }
  615. void MessageWriter::AppendVariantOfObjectPath(const ObjectPath& value) {
  616. const char* pointer = value.value().c_str();
  617. AppendVariantOfBasic(DBUS_TYPE_OBJECT_PATH, &pointer);
  618. }
  619. void MessageWriter::AppendBasic(int dbus_type, const void* value) {
  620. DCHECK(!container_is_open_);
  621. const bool success =
  622. dbus_message_iter_append_basic(&raw_message_iter_, dbus_type, value);
  623. // dbus_message_iter_append_basic() fails only when there is not enough
  624. // memory. We don't return this error as there is nothing we can do when
  625. // it fails to allocate memory for a byte etc.
  626. CHECK(success) << "Unable to allocate memory";
  627. }
  628. void MessageWriter::AppendVariantOfBasic(int dbus_type, const void* value) {
  629. const std::string signature(1u, // length
  630. base::checked_cast<char>(dbus_type));
  631. MessageWriter variant_writer(message_);
  632. OpenVariant(signature, &variant_writer);
  633. variant_writer.AppendBasic(dbus_type, value);
  634. CloseContainer(&variant_writer);
  635. }
  636. void MessageWriter::AppendFileDescriptor(int value) {
  637. CHECK(IsDBusTypeUnixFdSupported());
  638. AppendBasic(DBUS_TYPE_UNIX_FD, &value); // This duplicates the FD.
  639. }
  640. //
  641. // MessageReader implementation.
  642. //
  643. MessageReader::MessageReader(Message* message) : message_(message) {
  644. memset(&raw_message_iter_, 0, sizeof(raw_message_iter_));
  645. if (message)
  646. dbus_message_iter_init(message_->raw_message(), &raw_message_iter_);
  647. }
  648. MessageReader::~MessageReader() = default;
  649. bool MessageReader::HasMoreData() {
  650. const int dbus_type = dbus_message_iter_get_arg_type(&raw_message_iter_);
  651. return dbus_type != DBUS_TYPE_INVALID;
  652. }
  653. bool MessageReader::PopByte(uint8_t* value) {
  654. return PopBasic(DBUS_TYPE_BYTE, value);
  655. }
  656. bool MessageReader::PopBool(bool* value) {
  657. // Like MessageWriter::AppendBool(), we should copy |value| to
  658. // dbus_bool_t, as dbus_message_iter_get_basic() used in PopBasic()
  659. // expects four bytes for DBUS_TYPE_BOOLEAN.
  660. dbus_bool_t dbus_value = FALSE;
  661. const bool success = PopBasic(DBUS_TYPE_BOOLEAN, &dbus_value);
  662. *value = static_cast<bool>(dbus_value);
  663. return success;
  664. }
  665. bool MessageReader::PopInt16(int16_t* value) {
  666. return PopBasic(DBUS_TYPE_INT16, value);
  667. }
  668. bool MessageReader::PopUint16(uint16_t* value) {
  669. return PopBasic(DBUS_TYPE_UINT16, value);
  670. }
  671. bool MessageReader::PopInt32(int32_t* value) {
  672. return PopBasic(DBUS_TYPE_INT32, value);
  673. }
  674. bool MessageReader::PopUint32(uint32_t* value) {
  675. return PopBasic(DBUS_TYPE_UINT32, value);
  676. }
  677. bool MessageReader::PopInt64(int64_t* value) {
  678. return PopBasic(DBUS_TYPE_INT64, value);
  679. }
  680. bool MessageReader::PopUint64(uint64_t* value) {
  681. return PopBasic(DBUS_TYPE_UINT64, value);
  682. }
  683. bool MessageReader::PopDouble(double* value) {
  684. return PopBasic(DBUS_TYPE_DOUBLE, value);
  685. }
  686. bool MessageReader::PopString(std::string* value) {
  687. char* tmp_value = nullptr;
  688. const bool success = PopBasic(DBUS_TYPE_STRING, &tmp_value);
  689. if (success)
  690. value->assign(tmp_value);
  691. return success;
  692. }
  693. bool MessageReader::PopObjectPath(ObjectPath* value) {
  694. char* tmp_value = nullptr;
  695. const bool success = PopBasic(DBUS_TYPE_OBJECT_PATH, &tmp_value);
  696. if (success)
  697. *value = ObjectPath(tmp_value);
  698. return success;
  699. }
  700. bool MessageReader::PopArray(MessageReader* sub_reader) {
  701. return PopContainer(DBUS_TYPE_ARRAY, sub_reader);
  702. }
  703. bool MessageReader::PopStruct(MessageReader* sub_reader) {
  704. return PopContainer(DBUS_TYPE_STRUCT, sub_reader);
  705. }
  706. bool MessageReader::PopDictEntry(MessageReader* sub_reader) {
  707. return PopContainer(DBUS_TYPE_DICT_ENTRY, sub_reader);
  708. }
  709. bool MessageReader::PopVariant(MessageReader* sub_reader) {
  710. return PopContainer(DBUS_TYPE_VARIANT, sub_reader);
  711. }
  712. bool MessageReader::PopArrayOfBytes(const uint8_t** bytes, size_t* length) {
  713. MessageReader array_reader(message_);
  714. if (!PopArray(&array_reader))
  715. return false;
  716. // An empty array is allowed.
  717. if (!array_reader.HasMoreData()) {
  718. *length = 0;
  719. *bytes = nullptr;
  720. return true;
  721. }
  722. if (!array_reader.CheckDataType(DBUS_TYPE_BYTE))
  723. return false;
  724. int int_length = 0;
  725. dbus_message_iter_get_fixed_array(&array_reader.raw_message_iter_, bytes,
  726. &int_length);
  727. *length = static_cast<size_t>(int_length);
  728. return true;
  729. }
  730. bool MessageReader::PopArrayOfInt32s(const int32_t** signed_ints,
  731. size_t* length) {
  732. MessageReader array_reader(message_);
  733. if (!PopArray(&array_reader))
  734. return false;
  735. // An empty array is allowed.
  736. if (!array_reader.HasMoreData()) {
  737. *length = 0;
  738. *signed_ints = nullptr;
  739. return true;
  740. }
  741. if (!array_reader.CheckDataType(DBUS_TYPE_INT32))
  742. return false;
  743. int int_length = 0;
  744. dbus_message_iter_get_fixed_array(&array_reader.raw_message_iter_,
  745. signed_ints, &int_length);
  746. *length = static_cast<size_t>(int_length);
  747. return true;
  748. }
  749. bool MessageReader::PopArrayOfUint32s(const uint32_t** unsigned_ints,
  750. size_t* length) {
  751. MessageReader array_reader(message_);
  752. if (!PopArray(&array_reader))
  753. return false;
  754. // An empty array is allowed.
  755. if (!array_reader.HasMoreData()) {
  756. *length = 0;
  757. *unsigned_ints = nullptr;
  758. return true;
  759. }
  760. if (!array_reader.CheckDataType(DBUS_TYPE_UINT32))
  761. return false;
  762. int int_length = 0;
  763. dbus_message_iter_get_fixed_array(&array_reader.raw_message_iter_,
  764. unsigned_ints, &int_length);
  765. *length = static_cast<size_t>(int_length);
  766. return true;
  767. }
  768. bool MessageReader::PopArrayOfDoubles(const double** doubles, size_t* length) {
  769. MessageReader array_reader(message_);
  770. if (!PopArray(&array_reader))
  771. return false;
  772. if (!array_reader.HasMoreData()) {
  773. *length = 0;
  774. *doubles = nullptr;
  775. return true;
  776. }
  777. if (!array_reader.CheckDataType(DBUS_TYPE_DOUBLE))
  778. return false;
  779. int int_length = 0;
  780. dbus_message_iter_get_fixed_array(&array_reader.raw_message_iter_, doubles,
  781. &int_length);
  782. *length = static_cast<size_t>(int_length);
  783. return true;
  784. }
  785. bool MessageReader::PopArrayOfStrings(std::vector<std::string>* strings) {
  786. strings->clear();
  787. MessageReader array_reader(message_);
  788. if (!PopArray(&array_reader))
  789. return false;
  790. while (array_reader.HasMoreData()) {
  791. std::string string;
  792. if (!array_reader.PopString(&string))
  793. return false;
  794. strings->push_back(string);
  795. }
  796. return true;
  797. }
  798. bool MessageReader::PopArrayOfObjectPaths(
  799. std::vector<ObjectPath>* object_paths) {
  800. object_paths->clear();
  801. MessageReader array_reader(message_);
  802. if (!PopArray(&array_reader))
  803. return false;
  804. while (array_reader.HasMoreData()) {
  805. ObjectPath object_path;
  806. if (!array_reader.PopObjectPath(&object_path))
  807. return false;
  808. object_paths->push_back(object_path);
  809. }
  810. return true;
  811. }
  812. bool MessageReader::PopArrayOfBytesAsProto(
  813. google::protobuf::MessageLite* protobuf) {
  814. DCHECK(protobuf);
  815. const char* serialized_buf = nullptr;
  816. size_t buf_size = 0;
  817. if (!PopArrayOfBytes(reinterpret_cast<const uint8_t**>(&serialized_buf),
  818. &buf_size)) {
  819. LOG(ERROR) << "Error reading array of bytes";
  820. return false;
  821. }
  822. if (!protobuf->ParseFromArray(serialized_buf, buf_size)) {
  823. LOG(ERROR) << "Failed to parse protocol buffer from array";
  824. return false;
  825. }
  826. return true;
  827. }
  828. bool MessageReader::PopVariantOfByte(uint8_t* value) {
  829. return PopVariantOfBasic(DBUS_TYPE_BYTE, value);
  830. }
  831. bool MessageReader::PopVariantOfBool(bool* value) {
  832. // See the comment at MessageReader::PopBool().
  833. dbus_bool_t dbus_value = FALSE;
  834. const bool success = PopVariantOfBasic(DBUS_TYPE_BOOLEAN, &dbus_value);
  835. *value = static_cast<bool>(dbus_value);
  836. return success;
  837. }
  838. bool MessageReader::PopVariantOfInt16(int16_t* value) {
  839. return PopVariantOfBasic(DBUS_TYPE_INT16, value);
  840. }
  841. bool MessageReader::PopVariantOfUint16(uint16_t* value) {
  842. return PopVariantOfBasic(DBUS_TYPE_UINT16, value);
  843. }
  844. bool MessageReader::PopVariantOfInt32(int32_t* value) {
  845. return PopVariantOfBasic(DBUS_TYPE_INT32, value);
  846. }
  847. bool MessageReader::PopVariantOfUint32(uint32_t* value) {
  848. return PopVariantOfBasic(DBUS_TYPE_UINT32, value);
  849. }
  850. bool MessageReader::PopVariantOfInt64(int64_t* value) {
  851. return PopVariantOfBasic(DBUS_TYPE_INT64, value);
  852. }
  853. bool MessageReader::PopVariantOfUint64(uint64_t* value) {
  854. return PopVariantOfBasic(DBUS_TYPE_UINT64, value);
  855. }
  856. bool MessageReader::PopVariantOfDouble(double* value) {
  857. return PopVariantOfBasic(DBUS_TYPE_DOUBLE, value);
  858. }
  859. bool MessageReader::PopVariantOfString(std::string* value) {
  860. char* tmp_value = nullptr;
  861. const bool success = PopVariantOfBasic(DBUS_TYPE_STRING, &tmp_value);
  862. if (success)
  863. value->assign(tmp_value);
  864. return success;
  865. }
  866. bool MessageReader::PopVariantOfObjectPath(ObjectPath* value) {
  867. char* tmp_value = nullptr;
  868. const bool success = PopVariantOfBasic(DBUS_TYPE_OBJECT_PATH, &tmp_value);
  869. if (success)
  870. *value = ObjectPath(tmp_value);
  871. return success;
  872. }
  873. Message::DataType MessageReader::GetDataType() {
  874. const int dbus_type = dbus_message_iter_get_arg_type(&raw_message_iter_);
  875. return static_cast<Message::DataType>(dbus_type);
  876. }
  877. std::string MessageReader::GetDataSignature() {
  878. std::string signature;
  879. char* raw_signature = dbus_message_iter_get_signature(&raw_message_iter_);
  880. if (raw_signature) {
  881. signature = raw_signature;
  882. dbus_free(raw_signature);
  883. }
  884. return signature;
  885. }
  886. bool MessageReader::CheckDataType(int dbus_type) {
  887. const int actual_type = dbus_message_iter_get_arg_type(&raw_message_iter_);
  888. if (actual_type != dbus_type) {
  889. VLOG(1) << "Type " << dbus_type << " is expected but got " << actual_type;
  890. return false;
  891. }
  892. return true;
  893. }
  894. bool MessageReader::PopBasic(int dbus_type, void* value) {
  895. if (!CheckDataType(dbus_type))
  896. return false;
  897. // dbus_message_iter_get_basic() here should always work, as we have
  898. // already checked the next item's data type in CheckDataType(). Note
  899. // that dbus_message_iter_get_basic() is a void function.
  900. dbus_message_iter_get_basic(&raw_message_iter_, value);
  901. DCHECK(value);
  902. dbus_message_iter_next(&raw_message_iter_);
  903. return true;
  904. }
  905. bool MessageReader::PopContainer(int dbus_type, MessageReader* sub_reader) {
  906. DCHECK_NE(this, sub_reader);
  907. if (!CheckDataType(dbus_type))
  908. return false;
  909. dbus_message_iter_recurse(&raw_message_iter_, &sub_reader->raw_message_iter_);
  910. dbus_message_iter_next(&raw_message_iter_);
  911. return true;
  912. }
  913. bool MessageReader::PopVariantOfBasic(int dbus_type, void* value) {
  914. MessageReader variant_reader(message_);
  915. if (!PopVariant(&variant_reader))
  916. return false;
  917. return variant_reader.PopBasic(dbus_type, value);
  918. }
  919. bool MessageReader::PopFileDescriptor(base::ScopedFD* value) {
  920. CHECK(IsDBusTypeUnixFdSupported());
  921. int fd = -1;
  922. const bool success = PopBasic(DBUS_TYPE_UNIX_FD, &fd);
  923. if (!success)
  924. return false;
  925. *value = base::ScopedFD(fd);
  926. return true;
  927. }
  928. } // namespace dbus