Fix wrong implementation about encoding & decoding bundle raw 58/240258/3
authorHwankyu Jhun <h.jhun@samsung.com>
Wed, 5 Aug 2020 01:30:24 +0000 (10:30 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Wed, 5 Aug 2020 02:32:57 +0000 (11:32 +0900)
bundle_encode_raw() must not use g_base64_encode().
This patch removes calling g_base64_encode() from bundle_encode_raw().

Change-Id: Iddedfb6a566e4b1d41052ec2e322c5312d2a0a52
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
include/bundle_cpp.h
src/bundle-internal.cc
src/bundle-internal.h
src/bundle_cpp.cc
src/stub.cc
unit_tests/src/test_bundle.cc
unit_tests/src/test_bundle_cpp.cc

index 241fa98..6db29e4 100644 (file)
@@ -139,7 +139,7 @@ class EXPORT_API Bundle final {
    * @since_tizen 5.5
    * @param[in] raw The object for BundleRaw
    */
-  explicit Bundle(BundleRaw raw);
+  explicit Bundle(BundleRaw raw, bool base64 = true);
 
   /**
    * @brief Constructor.
@@ -282,9 +282,10 @@ class EXPORT_API Bundle final {
   /**
    * @brief Converts this object to BundleRaw type.
    * @since_tizen 5.5
+   * @param[in] base64 @c true, the BundleRaw will be encoded using base64-encoding.
    * @return The object of BundleRaw
   */
-  BundleRaw ToRaw();
+  BundleRaw ToRaw(bool base64 = true);
 
   /**
    * @brief Gets the count of keys.
index 9c7b2ee..2298412 100644 (file)
@@ -142,27 +142,18 @@ int Bundle::GetType(const std::string& key) {
 }
 
 unsigned char* Bundle::Encode() {
-  std::vector<unsigned char> bytes;
-  for (const auto& key_info : list_) {
-    auto encoded_bytes = key_info->Encode();
-    bytes.insert(bytes.end(), encoded_bytes.begin(), encoded_bytes.end());
+  int size = 0;
+  unsigned char* raw;
+  try {
+    raw = EncodeRaw(&size);
+  } catch (Exception& e) {
+    THROW(e.GetErrorCode());
   }
 
-  char* checksum = static_cast<char*>(
-      g_compute_checksum_for_string(G_CHECKSUM_MD5,
-        reinterpret_cast<gchar*>(&bytes[0]),
-        static_cast<gssize>(bytes.size())));
-  if (checksum == nullptr)
-    THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
-
-  std::unique_ptr<char, decltype(std::free)*> ptr(checksum, std::free);
-  unsigned char* p = reinterpret_cast<unsigned char*>(checksum);
-  bytes.insert(bytes.begin(), p, p + CHECKSUM_LENGTH);
-
+  std::unique_ptr<unsigned char, decltype(std::free)*> raw_ptr(raw, std::free);
   char* encoded_data = reinterpret_cast<char*>(
-      g_base64_encode(
-        reinterpret_cast<guchar*>(&bytes[0]),
-        reinterpret_cast<gsize>(bytes.size())));
+      g_base64_encode(reinterpret_cast<guchar*>(raw),
+        static_cast<gsize>(size)));
   if (encoded_data == nullptr)
     THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
 
@@ -182,11 +173,44 @@ int Bundle::Decode(unsigned char* raw, int size) {
   if (d_len_raw < CHECKSUM_LENGTH)
     return BUNDLE_ERROR_OUT_OF_MEMORY;
 
+  return DecodeRaw(d_str, d_len_raw);
+}
+
+unsigned char* Bundle::EncodeRaw(int* size) {
+  std::vector<unsigned char> bytes;
+  for (const auto& key_info : list_) {
+    auto encoded_bytes = key_info->Encode();
+    bytes.insert(bytes.end(), encoded_bytes.begin(), encoded_bytes.end());
+  }
+
+  char* checksum = static_cast<char*>(
+      g_compute_checksum_for_string(G_CHECKSUM_MD5,
+        reinterpret_cast<gchar*>(&bytes[0]),
+        static_cast<gssize>(bytes.size())));
+  if (checksum == nullptr)
+    THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
+
+  std::unique_ptr<char, decltype(std::free)*> ptr(checksum, std::free);
+  unsigned char* p = reinterpret_cast<unsigned char*>(checksum);
+  bytes.insert(bytes.begin(), p, p + CHECKSUM_LENGTH);
+
+  unsigned char* raw = static_cast<unsigned char*>(malloc(bytes.size()));
+  if (raw == nullptr)
+    THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
+
+  std::copy(bytes.begin(), bytes.end(), raw);
+  *size = static_cast<int>(bytes.size());
+  return raw;
+}
+
+int Bundle::DecodeRaw(unsigned char* raw, int size) {
   char* extract_checksum = new (std::nothrow) char[CHECKSUM_LENGTH + 1];
   if (extract_checksum == nullptr)
     return BUNDLE_ERROR_OUT_OF_MEMORY;
 
   std::unique_ptr<char[]> extract_ptr(extract_checksum);
+  unsigned char* d_str = raw;
+  unsigned int d_len_raw = size;
   strncpy(extract_checksum, reinterpret_cast<char*>(d_str), CHECKSUM_LENGTH);
   extract_checksum[CHECKSUM_LENGTH] = '\0';
 
index c79fed4..73f55d0 100644 (file)
@@ -70,6 +70,8 @@ class Bundle {
   int GetType(const std::string& key);
 
   unsigned char* Encode();
+  unsigned char* EncodeRaw(int* size);
+  int DecodeRaw(unsigned char* raw, int size);
   const std::map<std::string, std::shared_ptr<KeyInfo>>& GetMap();
   std::vector<std::string> Export();
 
index f23f4d6..341dfce 100644 (file)
@@ -38,9 +38,12 @@ Bundle::Bundle()
     throw std::bad_alloc();
 }
 
-Bundle::Bundle(BundleRaw raw)
+Bundle::Bundle(BundleRaw raw, bool base64)
   : impl_(new Impl(this)) {
-  impl_->handle_ = bundle_decode(raw.first.get(), raw.second);
+  if (base64)
+    impl_->handle_ = bundle_decode(raw.first.get(), raw.second);
+  else
+    impl_->handle_ = bundle_decode_raw(raw.first.get(), raw.second);
   if (impl_->handle_ == nullptr)
     throw std::bad_alloc();
 }
@@ -257,10 +260,14 @@ std::vector<unsigned char> Bundle::GetByte(const std::string& key) const {
   return std::vector<unsigned char>(bytes, bytes + size);
 }
 
-Bundle::BundleRaw Bundle::ToRaw() {
+Bundle::BundleRaw Bundle::ToRaw(bool base64) {
   bundle_raw* raw = nullptr;
   int len = 0;
-  int ret = bundle_encode(impl_->handle_, &raw, &len);
+  int ret;
+  if (base64)
+    ret = bundle_encode(impl_->handle_, &raw, &len);
+  else
+    ret = bundle_encode_raw(impl_->handle_, &raw, &len);
   if (raw == nullptr) {
     LOGE("Fail to encode data (%d)", ret);
     throw std::bad_alloc();
index 3efcf95..7bf991a 100644 (file)
@@ -350,12 +350,40 @@ extern "C" EXPORT_API bundle* bundle_decode(const bundle_raw* r,
 
 extern "C" EXPORT_API int bundle_encode_raw(bundle* b, bundle_raw** r,
     int* len) {
-  return bundle_encode(b, r, len);
+  if (b == nullptr || r == nullptr || len == nullptr)
+    return BUNDLE_ERROR_INVALID_PARAMETER;
+
+  auto* h = reinterpret_cast<Bundle*>(b);
+  try {
+    *r = reinterpret_cast<bundle_raw*>(h->EncodeRaw(len));
+  } catch (Exception& e) {
+    return e.GetErrorCode();
+  }
+  return BUNDLE_ERROR_NONE;
 }
 
 extern "C" EXPORT_API bundle* bundle_decode_raw(const bundle_raw* r,
     const int data_size) {
-  return bundle_decode(r, data_size);
+  if (r == nullptr) {
+    set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
+    return nullptr;
+  }
+
+  bundle* b = bundle_create();
+  if (b == nullptr)
+    return nullptr;
+
+  auto* h = reinterpret_cast<Bundle*>(b);
+  auto* raw = const_cast<bundle_raw*>(r);
+  int ret = h->DecodeRaw(static_cast<unsigned char*>(raw), data_size);
+  if (ret != BUNDLE_ERROR_NONE) {
+    bundle_free(b);
+    set_last_result(ret);
+    return nullptr;
+  }
+
+  set_last_result(BUNDLE_ERROR_NONE);
+  return b;
 }
 
 extern "C" EXPORT_API int bundle_get_type(bundle* b, const char* key) {
index 6bde750..9473c91 100644 (file)
@@ -660,7 +660,7 @@ TEST_F(BundleTest, bundle_encode_raw_P) {
   ASSERT_NE(raw, nullptr);
   ASSERT_NE(len, 0);
 
-  bundle* decoded_b = bundle_decode(raw, len);
+  bundle* decoded_b = bundle_decode_raw(raw, len);
   std::unique_ptr<bundle, decltype(bundle_free)*> b_ptr(decoded_b, bundle_free);
   ASSERT_EQ(get_last_result(), BUNDLE_ERROR_NONE);
   ASSERT_NE(decoded_b, nullptr);
index 97ee62b..46fca50 100644 (file)
@@ -81,8 +81,12 @@ TEST(Bundle, ToRaw) {
   Bundle bundle;
   bundle.Add("TestKey", "TestVal");
 
-  auto r = bundle.ToRaw();
-  Bundle b2(std::move(r));
+  auto base64_r = bundle.ToRaw();
+  Bundle b2(std::move(base64_r));
+  EXPECT_EQ(bundle.GetString("TestKey"), "TestVal");
+
+  auto r = bundle.ToRaw(false);
+  Bundle b3(std::move(r), false);
   EXPECT_EQ(bundle.GetString("TestKey"), "TestVal");
 }