From b1e3a0dca6ea0030e5ba2d28b9b2d8ff11b36fa8 Mon Sep 17 00:00:00 2001 From: Grant Paul Date: Fri, 7 Oct 2016 21:03:58 -0700 Subject: [PATCH] Allocate enough space for Unicode strings in binary property lists. Before, only half as much space as needed was allocated. --- Libraries/plist/CMakeLists.txt | 1 + Libraries/plist/Sources/Format/Binary.cpp | 32 ++++++++------ Libraries/plist/Tests/Format/test_Binary.cpp | 44 ++++++++++++++++++++ 3 files changed, 65 insertions(+), 12 deletions(-) create mode 100644 Libraries/plist/Tests/Format/test_Binary.cpp diff --git a/Libraries/plist/CMakeLists.txt b/Libraries/plist/CMakeLists.txt index 593b151a9..31b760af4 100644 --- a/Libraries/plist/CMakeLists.txt +++ b/Libraries/plist/CMakeLists.txt @@ -92,6 +92,7 @@ if (BUILD_TESTING) ADD_UNIT_GTEST(plist String Tests/test_String.cpp) ADD_UNIT_GTEST(plist Encoding Tests/Format/test_Encoding.cpp) ADD_UNIT_GTEST(plist ASCII Tests/Format/test_ASCII.cpp) + ADD_UNIT_GTEST(plist Binary Tests/Format/test_Binary.cpp) ADD_UNIT_GTEST(plist JSON Tests/Format/test_JSON.cpp) ADD_UNIT_GTEST(plist XML Tests/Format/test_XML.cpp) endif () diff --git a/Libraries/plist/Sources/Format/Binary.cpp b/Libraries/plist/Sources/Format/Binary.cpp index 8958de7d4..52f38577c 100644 --- a/Libraries/plist/Sources/Format/Binary.cpp +++ b/Libraries/plist/Sources/Format/Binary.cpp @@ -150,16 +150,18 @@ Create(void *opaque, ABPRecordType type, void *arg1, void *arg2, void *arg3) off_t offset = *reinterpret_cast (arg1); size_t nbytes = *reinterpret_cast (arg2); - std::vector bytes; + std::vector bytes; if (nbytes > 0) { - if (ReadSeek(opaque, offset, SEEK_SET) < 0) + if (ReadSeek(opaque, offset, SEEK_SET) < 0) { return nullptr; + } bytes.resize(nbytes); - size_t nread = ReadData(opaque, &bytes[0], nbytes); - if (nread < nbytes) + size_t nread = ReadData(opaque, bytes.data(), nbytes); + if (nread < nbytes) { return nullptr; + } } return Data::New(std::move(bytes)).release(); @@ -173,13 +175,16 @@ Create(void *opaque, ABPRecordType type, void *arg1, void *arg2, void *arg3) std::string string; if (nchars > 0) { - if (ReadSeek(opaque, offset, SEEK_SET) < 0) + if (ReadSeek(opaque, offset, SEEK_SET) < 0) { return nullptr; + } - string.resize(nchars); - size_t nread = ReadData(opaque, &string[0], sizeof(char) * nchars); - if (nread < nchars) + size_t nbytes = sizeof(char) * nchars; + string.resize(nbytes); + size_t nread = ReadData(opaque, &string[0], nbytes); + if (nread < nbytes) { return nullptr; + } } return String::New(std::move(string)).release(); @@ -192,13 +197,16 @@ Create(void *opaque, ABPRecordType type, void *arg1, void *arg2, void *arg3) std::vector buffer; if (nchars > 0) { - if (ReadSeek(opaque, offset, SEEK_SET) < 0) + if (ReadSeek(opaque, offset, SEEK_SET) < 0) { return nullptr; + } - buffer.resize(nchars); - size_t nread = ReadData(opaque, buffer.data(), sizeof(uint16_t) * nchars); - if (nread < nchars) + size_t nbytes = sizeof(uint16_t) * nchars; + buffer.resize(nbytes); + size_t nread = ReadData(opaque, buffer.data(), nbytes); + if (nread < nbytes) { return nullptr; + } } buffer = Encodings::Convert(buffer, Encoding::UTF16BE, Encoding::UTF8); diff --git a/Libraries/plist/Tests/Format/test_Binary.cpp b/Libraries/plist/Tests/Format/test_Binary.cpp new file mode 100644 index 000000000..460f0698a --- /dev/null +++ b/Libraries/plist/Tests/Format/test_Binary.cpp @@ -0,0 +1,44 @@ +/** + Copyright (c) 2015-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#include +#include +#include + +using plist::Format::Binary; +using plist::String; +using plist::Dictionary; + +TEST(Binary, UnicodeString) +{ + std::vector contents = { + 0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0x6f, 0x10, 0x18, 0xd8, + 0x3d, 0xde, 0x43, 0xd8, 0x3d, 0xde, 0x36, 0xd8, 0x3d, 0xde, 0x2e, 0xd8, + 0x3d, 0xde, 0x2d, 0xd8, 0x3d, 0xde, 0x26, 0xd8, 0x3d, 0xde, 0x10, 0xd8, + 0x3d, 0xde, 0x02, 0xd8, 0x3d, 0xde, 0x44, 0xd8, 0x3d, 0xde, 0x2e, 0xd8, + 0x3d, 0xde, 0x04, 0xd8, 0x3d, 0xde, 0x05, 0xd8, 0x3d, 0xde, 0x1b, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, + }; + + std::unique_ptr format = Binary::Identify(contents); + ASSERT_NE(format, nullptr); + + auto deserialize = Binary::Deserialize(contents, Binary::Create()); + ASSERT_NE(deserialize.first, nullptr); + + auto string = String::New("\U0001F643\U0001F636\U0001F62E\U0001F62D\U0001F626\U0001F610\U0001F602\U0001F644\U0001F62E\U0001F604\U0001F605\U0001F61B"); + EXPECT_TRUE(deserialize.first->equals(string.get())); + + auto serialize = Binary::Serialize(deserialize.first.get(), Binary::Create()); + ASSERT_NE(serialize.first, nullptr); + EXPECT_EQ(*serialize.first, contents); +} +