Fix static analysis issues
[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(const KeyInfo& key_info) {
52   type_ = key_info.type_;
53   key_ = key_info.key_;
54   values_size_ = key_info.values_size_;
55   uvalues_size_ = key_info.uvalues_size_;
56   for (unsigned int i = 0; i < key_info.values_.size(); ++i) {
57     auto* new_value = new (std::nothrow) unsigned char[values_size_[i]];
58     if (new_value == nullptr)
59       THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
60
61     std::copy(key_info.values_[i].get(),
62         key_info.values_[i].get() + values_size_[i], new_value);
63     values_.emplace_back(new_value);
64   }
65 }
66
67 KeyInfo& KeyInfo::operator = (const KeyInfo& key_info) {
68   if (this != &key_info) {
69     type_ = key_info.type_;
70     key_ = key_info.key_;
71     values_size_ = key_info.values_size_;
72     uvalues_size_ = key_info.uvalues_size_;
73     for (unsigned int i = 0; i < key_info.values_.size(); ++i) {
74       auto* new_value = new (std::nothrow) unsigned char[values_size_[i]];
75       if (new_value == nullptr)
76         THROW(BUNDLE_ERROR_OUT_OF_MEMORY);
77
78       std::copy(key_info.values_[i].get(),
79           key_info.values_[i].get() + values_size_[i], new_value);
80       values_.emplace_back(new_value);
81     }
82   }
83   return *this;
84 }
85
86 KeyInfo::KeyInfo(KeyInfo&& key_info) noexcept {
87   type_ = key_info.type_;
88   key_info.type_ = 0;
89   key_ = std::move(key_info.key_);
90   values_ = std::move(key_info.values_);
91   values_size_ = std::move(key_info.values_size_);
92   uvalues_size_ = std::move(key_info.uvalues_size_);
93 }
94
95 KeyInfo& KeyInfo::operator = (KeyInfo&& key_info) noexcept {
96   if (this != &key_info) {
97     type_ = key_info.type_;
98     key_info.type_ = 0;
99     key_ = std::move(key_info.key_);
100     values_ = std::move(key_info.values_);
101     values_size_ = std::move(key_info.values_size_);
102     uvalues_size_ = std::move(key_info.uvalues_size_);
103   }
104   return *this;
105 }
106
107 bool KeyInfo::operator == (const KeyInfo& key_info) {
108   if (this == &key_info)
109     return true;
110
111   if (type_ != key_info.type_)
112     return false;
113
114   if (key_ != key_info.key_)
115     return false;
116
117   if (values_.size() != key_info.values_.size())
118     return false;
119
120   for (unsigned int i = 0; i < values_.size(); ++i) {
121     if (values_size_[i] == key_info.values_size_[i])
122       return false;
123
124     int ret = std::memcmp(values_[i].get(), key_info.values_[i].get(),
125         values_size_[i]);
126     if (ret == 0)
127       return false;
128   }
129
130   return true;
131 }
132
133 int KeyInfo::GetType() const {
134   return type_;
135 }
136
137 bool KeyInfo::IsArray() const {
138   if (type_ & BUNDLE_TYPE_ARRAY)
139     return true;
140
141   return false;
142 }
143
144 const std::string& KeyInfo::GetKey() {
145   return key_;
146 }
147
148 const std::vector<std::unique_ptr<unsigned char[]>>& KeyInfo::GetValues() {
149   return values_;
150 }
151
152 const std::vector<std::size_t>& KeyInfo::GetValuesSize() {
153   return values_size_;
154 }
155
156 const std::vector<unsigned int>& KeyInfo::GetUValuesSize() {
157   return uvalues_size_;
158 }
159
160 int KeyInfo::SetValue(const std::vector<unsigned char>& value) {
161   auto* new_value = new (std::nothrow) unsigned char[value.size()];
162   if (new_value == nullptr)
163     return BUNDLE_ERROR_OUT_OF_MEMORY;
164
165   std::copy(value.begin(), value.end(), new_value);
166   values_.emplace_back(new_value);
167   values_size_.push_back(value.size());
168   uvalues_size_.push_back(static_cast<unsigned int>(value.size()));
169   return BUNDLE_ERROR_NONE;
170 }
171
172 int KeyInfo::SetValues(const std::vector<std::vector<unsigned char>>& values) {
173   for (unsigned int i = 0; i< values.size(); ++i) {
174     auto* new_value = new (std::nothrow) unsigned char[values[i].size()];
175     if (new_value == nullptr)
176       return BUNDLE_ERROR_OUT_OF_MEMORY;
177
178     std::copy(values[i].begin(), values[i].end(), new_value);
179     values_.emplace_back(new_value);
180     values_size_.push_back(values[i].size());
181     uvalues_size_.push_back(values[i].size());
182   }
183   return BUNDLE_ERROR_NONE;
184 }
185
186 std::vector<unsigned char> KeyInfo::Encode() {
187   std::size_t encoded_size = GetEncodedSize();
188   if (encoded_size == 0)
189     return {};
190
191   std::vector<unsigned char> bytes;
192
193   // total size
194   unsigned char* p = reinterpret_cast<unsigned char*>(&encoded_size);
195   bytes.insert(bytes.end(), p, p + sizeof(encoded_size));
196
197   // type
198   p = reinterpret_cast<unsigned char*>(&type_);
199   bytes.insert(bytes.end(), p, p + sizeof(type_));
200
201   // key size
202   std::size_t key_length = key_.length() + 1;
203   p = reinterpret_cast<unsigned char*>(&key_length);
204   bytes.insert(bytes.end(), p, p + sizeof(key_length));
205
206   // key
207   bytes.insert(bytes.end(), key_.begin(), key_.end() + 1);
208
209   if (type_ & BUNDLE_TYPE_ARRAY) {
210     // values size
211     std::size_t values_size = values_.size();
212     p = reinterpret_cast<unsigned char*>(&values_size);
213     bytes.insert(bytes.end(), p , p + sizeof(values_size));
214   }
215
216   // values
217   for (unsigned int i = 0; i < values_.size(); i++) {
218     std::size_t value_size = values_size_[i];
219     p = reinterpret_cast<unsigned char*>(&value_size);
220     bytes.insert(bytes.end(), p, p + sizeof(value_size));
221
222     bytes.insert(bytes.end(), values_[i].get(), values_[i].get() + value_size);
223   }
224
225   return bytes;
226 }
227
228 std::size_t KeyInfo::GetEncodedSize() {
229   // total size
230   std::size_t encoded_size = sizeof(std::size_t);
231
232   // type
233   encoded_size += sizeof(int);
234
235   // key size
236   encoded_size += sizeof(std::size_t);
237
238   // key
239   if ((encoded_size + key_.length() + 1) < encoded_size)
240     return 0;
241
242   encoded_size += key_.length() + 1;
243
244   if (type_ & BUNDLE_TYPE_ARRAY) {
245     // values size
246     if ((encoded_size + sizeof(std::size_t)) < encoded_size)
247       return 0;
248
249     encoded_size += sizeof(std::size_t);
250   }
251
252   // values
253   std::size_t values_size = 0;
254   for (unsigned int i = 0; i < values_.size(); ++i) {
255     // value size
256     if ((values_size + sizeof(std::size_t)) < values_size)
257       return 0;
258
259     values_size += sizeof(std::size_t);
260
261     // value
262     if ((values_size + values_size_[i]) < values_size)
263       return 0;
264
265     values_size += values_size_[i];
266   }
267
268   if ((encoded_size + values_size) < encoded_size)
269     return 0;
270
271   encoded_size += values_size;
272
273   return encoded_size;
274 }
275
276 int KeyInfo::Decode(const std::vector<unsigned char>& bytes) {
277   unsigned int reader = 0;
278
279   // total size
280   std::size_t total_size = 0;
281   if ((reader + sizeof(total_size)) > bytes.size())
282     return BUNDLE_ERROR_INVALID_PARAMETER;
283
284   unsigned char* p = reinterpret_cast<unsigned char*>(&total_size);
285   std::copy(&bytes[reader], &bytes[reader] + sizeof(total_size), p);
286   reader += sizeof(total_size);
287
288   // type
289   if ((reader + sizeof(type_)) > bytes.size())
290     return BUNDLE_ERROR_INVALID_PARAMETER;
291
292   p = reinterpret_cast<unsigned char*>(&type_);
293   std::copy(&bytes[reader], &bytes[reader] + sizeof(type_),  p);
294   reader += sizeof(type_);
295
296   // key size
297   std::size_t key_size = 0;
298
299   if ((reader + sizeof(key_size)) > bytes.size())
300     return BUNDLE_ERROR_INVALID_PARAMETER;
301
302   p = reinterpret_cast<unsigned char*>(&key_size);
303   std::copy(&bytes[reader], &bytes[reader] + sizeof(key_size), p);
304   reader += sizeof(key_size);
305
306   if ((reader + key_size) > bytes.size())
307     return BUNDLE_ERROR_INVALID_PARAMETER;
308
309   // key
310   std::vector<unsigned char> key(&bytes[reader], &bytes[reader] + key_size);
311   p = reinterpret_cast<unsigned char*>(&key[0]);
312   key_ = std::string(reinterpret_cast<char*>(p));
313   reader += key_size;
314
315   std::size_t values_size = 0;
316   if (type_ & BUNDLE_TYPE_ARRAY) {
317     // values size
318     if ((reader + sizeof(values_size)) > bytes.size())
319       return BUNDLE_ERROR_INVALID_PARAMETER;
320
321     p = reinterpret_cast<unsigned char*>(&values_size);
322     std::copy(&bytes[reader], &bytes[reader] + sizeof(values_size), p);
323     reader += sizeof(values_size);
324   } else {
325     values_size = 1;
326   }
327
328   // values
329   for (std::size_t i = 0; i < values_size; ++i) {
330     // value_size
331     std::size_t value_size = 0;
332     if ((reader + sizeof(value_size)) > bytes.size())
333       return BUNDLE_ERROR_INVALID_PARAMETER;
334
335     p = reinterpret_cast<unsigned char*>(&value_size);
336     std::copy(&bytes[reader], &bytes[reader] + sizeof(value_size), p);
337     reader += sizeof(value_size);
338
339     // value
340     if ((reader + value_size) > bytes.size())
341       return BUNDLE_ERROR_INVALID_PARAMETER;
342
343     auto* new_value = new (std::nothrow) unsigned char[value_size];
344     if (new_value == nullptr)
345       return BUNDLE_ERROR_OUT_OF_MEMORY;
346
347     std::copy(&bytes[reader], &bytes[reader] + value_size, new_value);
348     reader += value_size;
349
350     values_.emplace_back(new_value);
351     values_size_.push_back(value_size);
352     uvalues_size_.push_back(static_cast<unsigned int>(value_size));
353   }
354
355   return BUNDLE_ERROR_NONE;
356 }
357
358 int KeyInfo::SetValue(int index, const std::vector<unsigned char>& value) {
359   if (index > GetSize() || index < 0)
360     return BUNDLE_ERROR_ARRAY_INDEX_OUT_OF_BOUNDS;
361
362   if (!IsArray())
363     return BUNDLE_ERROR_INVALID_PARAMETER;
364
365   auto* new_value = new (std::nothrow) unsigned char[value.size()];
366   if (new_value == nullptr)
367     return BUNDLE_ERROR_OUT_OF_MEMORY;
368
369   if (value.size() != 0)
370     std::copy(value.begin(), value.end(), new_value);
371
372   values_[index].reset(new_value);
373   values_size_[index] = value.size();
374   uvalues_size_[index] = static_cast<unsigned int>(value.size());
375   return BUNDLE_ERROR_NONE;
376 }
377
378 int KeyInfo::GetSize() const {
379   return values_.size();
380 }
381
382 }  // namespace internal
383 }  // namespace tizen_base