Merge "Fix SetValue check condition" into tizen
[platform/core/base/bundle.git] / src / key-info-internal.cc
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <cstring>
18
19 #include "include/bundle.h"
20
21 #include "exception-internal.h"
22 #include "key-info-internal.h"
23
24 namespace tizen_base {
25 namespace internal {
26
27 KeyInfo::KeyInfo(int type, std::string key,
28     std::vector<unsigned char> value)
29   : type_(type),
30     key_(std::move(key)) {
31   int ret = SetValue(value);
32   if (ret != BUNDLE_ERROR_NONE)
33     THROW(ret);
34 }
35
36 KeyInfo::KeyInfo(int type, std::string key,
37     std::vector<std::vector<unsigned char>> values)
38   : type_(type),
39     key_(std::move(key)) {
40   int ret = SetValues(values);
41   if (ret != BUNDLE_ERROR_NONE)
42     THROW(ret);
43 }
44
45 KeyInfo::KeyInfo(std::vector<unsigned char> encoded_bytes) {
46   int ret = Decode(encoded_bytes);
47   if (ret != BUNDLE_ERROR_NONE)
48     THROW(ret);
49 }
50
51 KeyInfo::~KeyInfo() = default;
52
53 KeyInfo::KeyInfo(const KeyInfo& key_info) {
54   type_ = key_info.type_;
55   key_ = key_info.key_;
56   values_size_ = key_info.values_size_;
57   uvalues_size_ = key_info.uvalues_size_;
58   for (unsigned int i = 0; i < key_info.values_.size(); ++i) {
59     auto* new_value = new (std::nothrow) unsigned char[values_size_[i]];
60     if (new_value == nullptr)
61       THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
62
63     std::copy(key_info.values_[i].get(),
64         key_info.values_[i].get() + values_size_[i], new_value);
65     values_.emplace_back(new_value);
66   }
67 }
68
69 KeyInfo& KeyInfo::operator = (const KeyInfo& key_info) {
70   if (this != &key_info) {
71     type_ = key_info.type_;
72     key_ = key_info.key_;
73     values_size_ = key_info.values_size_;
74     uvalues_size_ = key_info.uvalues_size_;
75     for (unsigned int i = 0; i < key_info.values_.size(); ++i) {
76       auto* new_value = new (std::nothrow) unsigned char[values_size_[i]];
77       if (new_value == nullptr)
78         THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
79
80       std::copy(key_info.values_[i].get(),
81           key_info.values_[i].get() + values_size_[i], new_value);
82       values_.emplace_back(new_value);
83     }
84   }
85   return *this;
86 }
87
88 KeyInfo::KeyInfo(KeyInfo&& key_info) noexcept {
89   type_ = key_info.type_;
90   key_info.type_ = 0;
91   key_ = std::move(key_info.key_);
92   values_ = std::move(key_info.values_);
93   values_size_ = std::move(key_info.values_size_);
94   uvalues_size_ = std::move(key_info.uvalues_size_);
95 }
96
97 KeyInfo& KeyInfo::operator = (KeyInfo&& key_info) noexcept {
98   if (this != &key_info) {
99     type_ = key_info.type_;
100     key_info.type_ = 0;
101     key_ = std::move(key_info.key_);
102     values_ = std::move(key_info.values_);
103     values_size_ = std::move(key_info.values_size_);
104     uvalues_size_ = std::move(key_info.uvalues_size_);
105   }
106   return *this;
107 }
108
109 bool KeyInfo::operator == (const KeyInfo& key_info) {
110   if (this == &key_info)
111     return true;
112
113   if (type_ != key_info.type_)
114     return false;
115
116   if (key_ != key_info.key_)
117     return false;
118
119   if (values_.size() != key_info.values_.size())
120     return false;
121
122   for (unsigned int i = 0; i < values_.size(); ++i) {
123     if (values_size_[i] == key_info.values_size_[i])
124       return false;
125
126     int ret = std::memcmp(values_[i].get(), key_info.values_[i].get(),
127         values_size_[i]);
128     if (ret == 0)
129       return false;
130   }
131
132   return true;
133 }
134
135 int KeyInfo::GetType() const {
136   return type_;
137 }
138
139 bool KeyInfo::IsArray() const {
140   if (type_ & BUNDLE_TYPE_ARRAY)
141     return true;
142
143   return false;
144 }
145
146 const std::string& KeyInfo::GetKey() {
147   return key_;
148 }
149
150 const std::vector<std::unique_ptr<unsigned char[]>>& KeyInfo::GetValues() {
151   return values_;
152 }
153
154 const std::vector<std::size_t>& KeyInfo::GetValuesSize() {
155   return values_size_;
156 }
157
158 const std::vector<unsigned int>& KeyInfo::GetUValuesSize() {
159   return uvalues_size_;
160 }
161
162 int KeyInfo::SetValue(const std::vector<unsigned char>& value) {
163   auto* new_value = new (std::nothrow) unsigned char[value.size()];
164   if (new_value == nullptr)
165     return BUNDLE_ERROR_OUT_OF_MEMORY;
166
167   std::copy(value.begin(), value.end(), new_value);
168   values_.emplace_back(new_value);
169   values_size_.push_back(value.size());
170   uvalues_size_.push_back(static_cast<unsigned int>(value.size()));
171   return BUNDLE_ERROR_NONE;
172 }
173
174 int KeyInfo::SetValues(const std::vector<std::vector<unsigned char>>& values) {
175   for (unsigned int i = 0; i< values.size(); ++i) {
176     auto* new_value = new (std::nothrow) unsigned char[values[i].size()];
177     if (new_value == nullptr)
178       return BUNDLE_ERROR_OUT_OF_MEMORY;
179
180     std::copy(values[i].begin(), values[i].end(), new_value);
181     values_.emplace_back(new_value);
182     values_size_.push_back(values[i].size());
183     uvalues_size_.push_back(values[i].size());
184   }
185   return BUNDLE_ERROR_NONE;
186 }
187
188 std::vector<unsigned char> KeyInfo::Encode() {
189   std::size_t encoded_size = GetEncodedSize();
190   if (encoded_size == 0)
191     return {};
192
193   std::vector<unsigned char> bytes;
194
195   // total size
196   unsigned char* p = reinterpret_cast<unsigned char*>(&encoded_size);
197   std::copy(p, p + sizeof(encoded_size), std::back_inserter(bytes));
198
199   // type
200   p = reinterpret_cast<unsigned char*>(&type_);
201   std::copy(p, p + sizeof(type_), std::back_inserter(bytes));
202
203   // key size
204   std::size_t key_length = key_.length() + 1;
205   p = reinterpret_cast<unsigned char*>(&key_length);
206   std::copy(p, p + sizeof(key_length), std::back_inserter(bytes));
207
208   // key
209   std::copy(key_.begin(), key_.end() + 1, std::back_inserter(bytes));
210
211   if (type_ & BUNDLE_TYPE_ARRAY) {
212     // values size
213     std::size_t values_size = values_.size();
214     p = reinterpret_cast<unsigned char*>(&values_size);
215     std::copy(p , p + sizeof(values_size), std::back_inserter(bytes));
216   }
217
218   // values
219   for (unsigned int i = 0; i < values_.size(); i++) {
220     std::size_t value_size = values_size_[i];
221     p = reinterpret_cast<unsigned char*>(&value_size);
222     std::copy(p, p + sizeof(value_size), std::back_inserter(bytes));
223
224     std::copy(values_[i].get(), values_[i].get() + value_size,
225         std::back_inserter(bytes));
226   }
227
228   return bytes;
229 }
230
231 std::size_t KeyInfo::GetEncodedSize() {
232   // total size
233   std::size_t encoded_size = sizeof(std::size_t);
234
235   // type
236   encoded_size += sizeof(int);
237
238   // key size
239   encoded_size += sizeof(std::size_t);
240
241   // key
242   if ((encoded_size + key_.length() + 1) < encoded_size)
243     return 0;
244
245   encoded_size += key_.length() + 1;
246
247   if (type_ & BUNDLE_TYPE_ARRAY) {
248     // values size
249     if ((encoded_size + sizeof(std::size_t)) < encoded_size)
250       return 0;
251
252     encoded_size += sizeof(std::size_t);
253   }
254
255   // values
256   std::size_t values_size = 0;
257   for (unsigned int i = 0; i < values_.size(); ++i) {
258     // value size
259     if ((values_size + sizeof(std::size_t)) < values_size)
260       return 0;
261
262     values_size += sizeof(std::size_t);
263
264     // value
265     if ((values_size + values_size_[i]) < values_size)
266       return 0;
267
268     values_size += values_size_[i];
269   }
270
271   if ((encoded_size + values_size) < encoded_size)
272     return 0;
273
274   encoded_size += values_size;
275
276   return encoded_size;
277 }
278
279 int KeyInfo::Decode(const std::vector<unsigned char>& bytes) {
280   unsigned int reader = 0;
281
282   // total size
283   std::size_t total_size = 0;
284   if ((reader + sizeof(total_size)) > bytes.size())
285     return BUNDLE_ERROR_INVALID_PARAMETER;
286
287   unsigned char* p = reinterpret_cast<unsigned char*>(&total_size);
288   std::copy(&bytes[reader], &bytes[reader] + sizeof(total_size), p);
289   reader += sizeof(total_size);
290
291   // type
292   if ((reader + sizeof(type_)) > bytes.size())
293     return BUNDLE_ERROR_INVALID_PARAMETER;
294
295   p = reinterpret_cast<unsigned char*>(&type_);
296   std::copy(&bytes[reader], &bytes[reader] + sizeof(type_),  p);
297   reader += sizeof(type_);
298
299   // key size
300   std::size_t key_size = 0;
301
302   if ((reader + sizeof(key_size)) > bytes.size())
303     return BUNDLE_ERROR_INVALID_PARAMETER;
304
305   p = reinterpret_cast<unsigned char*>(&key_size);
306   std::copy(&bytes[reader], &bytes[reader] + sizeof(key_size), p);
307   reader += sizeof(key_size);
308
309   if ((reader + key_size) > bytes.size())
310     return BUNDLE_ERROR_INVALID_PARAMETER;
311
312   // key
313   std::vector<unsigned char> key(&bytes[reader], &bytes[reader] + key_size);
314   p = reinterpret_cast<unsigned char*>(&key[0]);
315   key_ = std::string(reinterpret_cast<char*>(p));
316   reader += key_size;
317
318   std::size_t values_size = 0;
319   if (type_ & BUNDLE_TYPE_ARRAY) {
320     // values size
321     if ((reader + sizeof(values_size)) > bytes.size())
322       return BUNDLE_ERROR_INVALID_PARAMETER;
323
324     p = reinterpret_cast<unsigned char*>(&values_size);
325     std::copy(&bytes[reader], &bytes[reader] + sizeof(values_size), p);
326     reader += sizeof(values_size);
327   } else {
328     values_size = 1;
329   }
330
331   // values
332   for (std::size_t i = 0; i < values_size; ++i) {
333     // value_size
334     std::size_t value_size = 0;
335     if ((reader + sizeof(value_size)) > bytes.size())
336       return BUNDLE_ERROR_INVALID_PARAMETER;
337
338     p = reinterpret_cast<unsigned char*>(&value_size);
339     std::copy(&bytes[reader], &bytes[reader] + sizeof(value_size), p);
340     reader += sizeof(value_size);
341
342     // value
343     if ((reader + value_size) > bytes.size())
344       return BUNDLE_ERROR_INVALID_PARAMETER;
345
346     auto* new_value = new (std::nothrow) unsigned char[value_size];
347     if (new_value == nullptr)
348       return BUNDLE_ERROR_OUT_OF_MEMORY;
349
350     std::copy(&bytes[reader], &bytes[reader] + value_size, new_value);
351     reader += value_size;
352
353     values_.emplace_back(new_value);
354     values_size_.push_back(value_size);
355     uvalues_size_.push_back(static_cast<unsigned int>(value_size));
356   }
357
358   return BUNDLE_ERROR_NONE;
359 }
360
361 int KeyInfo::SetValue(int index, const std::vector<unsigned char>& value) {
362   if (index > GetSize() || index < 0)
363     return BUNDLE_ERROR_ARRAY_INDEX_OUT_OF_BOUNDS;
364
365   if (!IsArray())
366     return BUNDLE_ERROR_INVALID_PARAMETER;
367
368   auto* new_value = new (std::nothrow) unsigned char[value.size()];
369   if (new_value == nullptr)
370     return BUNDLE_ERROR_OUT_OF_MEMORY;
371
372   if (value.size() != 0)
373     std::copy(value.begin(), value.end(), new_value);
374
375   values_[index].reset(new_value);
376   values_size_[index] = value.size();
377   uvalues_size_[index] = static_cast<unsigned int>(value.size());
378   return BUNDLE_ERROR_NONE;
379 }
380
381 int KeyInfo::GetSize() const {
382   return values_.size();
383 }
384
385 }  // namespace internal
386 }  // namespace tizen_base