rippled
Loading...
Searching...
No Matches
Serializer.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <xrpl/basics/Buffer.h>
21#include <xrpl/basics/Slice.h>
22#include <xrpl/basics/base_uint.h>
23#include <xrpl/basics/contract.h>
24#include <xrpl/basics/safe_cast.h>
25#include <xrpl/beast/utility/instrumentation.h>
26#include <xrpl/protocol/HashPrefix.h>
27#include <xrpl/protocol/Serializer.h>
28#include <xrpl/protocol/digest.h>
29
30#include <boost/endian/conversion.hpp>
31
32#include <array>
33#include <cstddef>
34#include <cstdint>
35#include <cstring>
36#include <stdexcept>
37#include <string>
38#include <type_traits>
39
40namespace ripple {
41
42int
44{
45 int ret = mData.size();
46 mData.push_back(static_cast<unsigned char>(i >> 8));
47 mData.push_back(static_cast<unsigned char>(i & 0xff));
48 return ret;
49}
50
51int
53{
54 // This should never trigger; the size & type of a hash prefix are
55 // integral parts of the protocol and unlikely to ever change.
56 static_assert(
58
59 return add32(safe_cast<std::uint32_t>(p));
60}
61
62template <>
63int
64Serializer::addInteger(unsigned char i)
65{
66 return add8(i);
67}
68template <>
69int
71{
72 return add16(i);
73}
74template <>
75int
77{
78 return add32(i);
79}
80template <>
81int
83{
84 return add64(i);
85}
86
87int
89{
90 int ret = mData.size();
91 mData.insert(mData.end(), vector.begin(), vector.end());
92 return ret;
93}
94
95int
97{
98 int ret = mData.size();
100 return ret;
101}
102
103int
105{
106 int ret = mData.size();
107 mData.insert(mData.end(), s.begin(), s.end());
108 return ret;
109}
110
111int
112Serializer::addRaw(void const* ptr, int len)
113{
114 int ret = mData.size();
115 mData.insert(mData.end(), (char const*)ptr, ((char const*)ptr) + len);
116 return ret;
117}
118
119int
120Serializer::addFieldID(int type, int name)
121{
122 int ret = mData.size();
123 XRPL_ASSERT(
124 (type > 0) && (type < 256) && (name > 0) && (name < 256),
125 "ripple::Serializer::addFieldID : inputs inside range");
126
127 if (type < 16)
128 {
129 if (name < 16) // common type, common name
130 mData.push_back(static_cast<unsigned char>((type << 4) | name));
131 else
132 {
133 // common type, uncommon name
134 mData.push_back(static_cast<unsigned char>(type << 4));
135 mData.push_back(static_cast<unsigned char>(name));
136 }
137 }
138 else if (name < 16)
139 {
140 // uncommon type, common name
141 mData.push_back(static_cast<unsigned char>(name));
142 mData.push_back(static_cast<unsigned char>(type));
143 }
144 else
145 {
146 // uncommon type, uncommon name
147 mData.push_back(static_cast<unsigned char>(0));
148 mData.push_back(static_cast<unsigned char>(type));
149 mData.push_back(static_cast<unsigned char>(name));
150 }
151
152 return ret;
153}
154
155int
156Serializer::add8(unsigned char byte)
157{
158 int ret = mData.size();
159 mData.push_back(byte);
160 return ret;
161}
162
163bool
164Serializer::get8(int& byte, int offset) const
165{
166 if (offset >= mData.size())
167 return false;
168
169 byte = mData[offset];
170 return true;
171}
172
173bool
175{
176 if (bytes > mData.size())
177 return false;
178
179 mData.resize(mData.size() - bytes);
180 return true;
181}
182
185{
186 return sha512Half(makeSlice(mData));
187}
188
189int
191{
192 int ret = addEncoded(vector.size());
193 addRaw(vector);
194 XRPL_ASSERT(
195 mData.size() ==
196 (ret + vector.size() + encodeLengthLength(vector.size())),
197 "ripple::Serializer::addVL : size matches expected");
198 return ret;
199}
200
201int
203{
204 int ret = addEncoded(slice.size());
205 if (slice.size())
206 addRaw(slice.data(), slice.size());
207 return ret;
208}
209
210int
211Serializer::addVL(void const* ptr, int len)
212{
213 int ret = addEncoded(len);
214
215 if (len)
216 addRaw(ptr, len);
217
218 return ret;
219}
220
221int
223{
225 int numBytes = 0;
226
227 if (length <= 192)
228 {
229 bytes[0] = static_cast<unsigned char>(length);
230 numBytes = 1;
231 }
232 else if (length <= 12480)
233 {
234 length -= 193;
235 bytes[0] = 193 + static_cast<unsigned char>(length >> 8);
236 bytes[1] = static_cast<unsigned char>(length & 0xff);
237 numBytes = 2;
238 }
239 else if (length <= 918744)
240 {
241 length -= 12481;
242 bytes[0] = 241 + static_cast<unsigned char>(length >> 16);
243 bytes[1] = static_cast<unsigned char>((length >> 8) & 0xff);
244 bytes[2] = static_cast<unsigned char>(length & 0xff);
245 numBytes = 3;
246 }
247 else
248 Throw<std::overflow_error>("lenlen");
249
250 return addRaw(&bytes[0], numBytes);
251}
252
253int
255{
256 if (length < 0)
257 Throw<std::overflow_error>("len<0");
258
259 if (length <= 192)
260 return 1;
261
262 if (length <= 12480)
263 return 2;
264
265 if (length <= 918744)
266 return 3;
267
268 Throw<std::overflow_error>("len>918744");
269 return 0; // Silence compiler warning.
270}
271
272int
274{
275 if (b1 < 0)
276 Throw<std::overflow_error>("b1<0");
277
278 if (b1 <= 192)
279 return 1;
280
281 if (b1 <= 240)
282 return 2;
283
284 if (b1 <= 254)
285 return 3;
286
287 Throw<std::overflow_error>("b1>254");
288 return 0; // Silence compiler warning.
289}
290
291int
293{
294 if (b1 < 0)
295 Throw<std::overflow_error>("b1<0");
296
297 if (b1 > 254)
298 Throw<std::overflow_error>("b1>254");
299
300 return b1;
301}
302
303int
305{
306 if (b1 < 193)
307 Throw<std::overflow_error>("b1<193");
308
309 if (b1 > 240)
310 Throw<std::overflow_error>("b1>240");
311
312 return 193 + (b1 - 193) * 256 + b2;
313}
314
315int
316Serializer::decodeVLLength(int b1, int b2, int b3)
317{
318 if (b1 < 241)
319 Throw<std::overflow_error>("b1<241");
320
321 if (b1 > 254)
322 Throw<std::overflow_error>("b1>254");
323
324 return 12481 + (b1 - 241) * 65536 + b2 * 256 + b3;
325}
326
327//------------------------------------------------------------------------------
328
329SerialIter::SerialIter(void const* data, std::size_t size) noexcept
330 : p_(reinterpret_cast<std::uint8_t const*>(data)), remain_(size)
331{
332}
333
334void
336{
337 p_ -= used_;
338 remain_ += used_;
339 used_ = 0;
340}
341
342void
344{
345 if (remain_ < length)
346 Throw<std::runtime_error>("invalid SerialIter skip");
347 p_ += length;
348 used_ += length;
349 remain_ -= length;
350}
351
352unsigned char
354{
355 if (remain_ < 1)
356 Throw<std::runtime_error>("invalid SerialIter get8");
357 unsigned char t = *p_;
358 ++p_;
359 ++used_;
360 --remain_;
361 return t;
362}
363
366{
367 if (remain_ < 2)
368 Throw<std::runtime_error>("invalid SerialIter get16");
369 auto t = p_;
370 p_ += 2;
371 used_ += 2;
372 remain_ -= 2;
373 return (std::uint64_t(t[0]) << 8) + std::uint64_t(t[1]);
374}
375
378{
379 if (remain_ < 4)
380 Throw<std::runtime_error>("invalid SerialIter get32");
381 auto t = p_;
382 p_ += 4;
383 used_ += 4;
384 remain_ -= 4;
385 return (std::uint64_t(t[0]) << 24) + (std::uint64_t(t[1]) << 16) +
386 (std::uint64_t(t[2]) << 8) + std::uint64_t(t[3]);
387}
388
391{
392 if (remain_ < 8)
393 Throw<std::runtime_error>("invalid SerialIter get64");
394 auto t = p_;
395 p_ += 8;
396 used_ += 8;
397 remain_ -= 8;
398 return (std::uint64_t(t[0]) << 56) + (std::uint64_t(t[1]) << 48) +
399 (std::uint64_t(t[2]) << 40) + (std::uint64_t(t[3]) << 32) +
400 (std::uint64_t(t[4]) << 24) + (std::uint64_t(t[5]) << 16) +
401 (std::uint64_t(t[6]) << 8) + std::uint64_t(t[7]);
402}
403
406{
407 if (remain_ < 4)
408 Throw<std::runtime_error>("invalid SerialIter geti32");
409 auto t = p_;
410 p_ += 4;
411 used_ += 4;
412 remain_ -= 4;
413 return boost::endian::load_big_s32(t);
414}
415
418{
419 if (remain_ < 8)
420 Throw<std::runtime_error>("invalid SerialIter geti64");
421 auto t = p_;
422 p_ += 8;
423 used_ += 8;
424 remain_ -= 8;
425 return boost::endian::load_big_s64(t);
426}
427
428void
429SerialIter::getFieldID(int& type, int& name)
430{
431 type = get8();
432 name = type & 15;
433 type >>= 4;
434
435 if (type == 0)
436 {
437 // uncommon type
438 type = get8();
439 if (type < 16)
440 Throw<std::runtime_error>(
441 "gFID: uncommon type out of range " + std::to_string(type));
442 }
443
444 if (name == 0)
445 {
446 // uncommon name
447 name = get8();
448 if (name < 16)
449 Throw<std::runtime_error>(
450 "gFID: uncommon name out of range " + std::to_string(name));
451 }
452}
453
454// getRaw for blob or buffer
455template <class T>
456T
458{
459 static_assert(
461 if (remain_ < size)
462 Throw<std::runtime_error>("invalid SerialIter getRaw");
463 T result(size);
464 if (size != 0)
465 {
466 // It's normally safe to call memcpy with size set to 0 (see the
467 // C99 standard 7.21.1/2). However, here this could mean that
468 // result.data would be null, which would trigger undefined behavior.
469 std::memcpy(result.data(), p_, size);
470 p_ += size;
471 used_ += size;
472 remain_ -= size;
473 }
474 return result;
475}
476
477// VFALCO DEPRECATED Returns a copy
478Blob
480{
481 return getRawHelper<Blob>(size);
482}
483
484int
486{
487 int b1 = get8();
488 int datLen;
489 int lenLen = Serializer::decodeLengthLength(b1);
490 if (lenLen == 1)
491 {
492 datLen = Serializer::decodeVLLength(b1);
493 }
494 else if (lenLen == 2)
495 {
496 int b2 = get8();
497 datLen = Serializer::decodeVLLength(b1, b2);
498 }
499 else
500 {
501 XRPL_ASSERT(
502 lenLen == 3, "ripple::SerialIter::getVLDataLength : lenLen is 3");
503 int b2 = get8();
504 int b3 = get8();
505 datLen = Serializer::decodeVLLength(b1, b2, b3);
506 }
507 return datLen;
508}
509
510Slice
512{
513 if (bytes > remain_)
514 Throw<std::runtime_error>("invalid SerialIter getSlice");
515 Slice s(p_, bytes);
516 p_ += bytes;
517 used_ += bytes;
518 remain_ -= bytes;
519 return s;
520}
521
522// VFALCO DEPRECATED Returns a copy
523Blob
525{
526 return getRaw(getVLDataLength());
527}
528
529Buffer
531{
532 return getRawHelper<Buffer>(getVLDataLength());
533}
534
535} // namespace ripple
T begin(T... args)
Like std::vector<char> but better.
Definition: Buffer.h:35
std::size_t remain_
Definition: Serializer.h:350
SerialIter(void const *data, std::size_t size) noexcept
Definition: Serializer.cpp:329
Slice getSlice(std::size_t bytes)
Definition: Serializer.cpp:511
void skip(int num)
Definition: Serializer.cpp:343
std::int64_t geti64()
Definition: Serializer.cpp:417
std::uint8_t const * p_
Definition: Serializer.h:349
std::int32_t geti32()
Definition: Serializer.cpp:405
void getFieldID(int &type, int &name)
Definition: Serializer.cpp:429
T getRawHelper(int size)
Definition: Serializer.cpp:457
Blob getRaw(int size)
Definition: Serializer.cpp:479
void reset() noexcept
Definition: Serializer.cpp:335
std::size_t used_
Definition: Serializer.h:351
std::uint16_t get16()
Definition: Serializer.cpp:365
std::uint32_t get32()
Definition: Serializer.cpp:377
unsigned char get8()
Definition: Serializer.cpp:353
std::uint64_t get64()
Definition: Serializer.cpp:390
Blob::iterator begin()
Definition: Serializer.h:253
int addFieldID(int type, int name)
Definition: Serializer.cpp:120
Slice slice() const noexcept
Definition: Serializer.h:67
bool get8(int &, int offset) const
Definition: Serializer.cpp:164
uint256 getSHA512Half() const
Definition: Serializer.cpp:184
static int encodeLengthLength(int length)
Definition: Serializer.cpp:254
int addEncoded(int length)
Definition: Serializer.cpp:222
int addInteger(Integer)
int addRaw(Blob const &vector)
Definition: Serializer.cpp:88
int addVL(Blob const &vector)
Definition: Serializer.cpp:190
bool chop(int num)
Definition: Serializer.cpp:174
static int decodeLengthLength(int b1)
Definition: Serializer.cpp:273
int add16(std::uint16_t i)
Definition: Serializer.cpp:43
int add8(unsigned char i)
Definition: Serializer.cpp:156
Blob::iterator end()
Definition: Serializer.h:258
static int decodeVLLength(int b1)
Definition: Serializer.cpp:292
An immutable linear range of bytes.
Definition: Slice.h:46
const_iterator begin() const noexcept
Definition: Slice.h:149
const_iterator end() const noexcept
Definition: Slice.h:161
std::uint8_t const * data() const noexcept
Return a pointer to beginning of the storage.
Definition: Slice.h:98
std::size_t size() const noexcept
Returns the number of bytes in the storage.
Definition: Slice.h:81
T end(T... args)
T insert(T... args)
T is_same_v
T memcpy(T... args)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
std::enable_if_t< std::is_same< T, char >::value||std::is_same< T, unsigned char >::value, Slice > makeSlice(std::array< T, N > const &a)
Definition: Slice.h:244
HashPrefix
Prefix for hashing functions.
Definition: HashPrefix.h:55
sha512_half_hasher::result_type sha512Half(Args const &... args)
Returns the SHA512-Half of a series of objects.
Definition: digest.h:225
T push_back(T... args)
T resize(T... args)
T size(T... args)
T to_string(T... args)