xref: /src/contrib/llvm-project/llvm/lib/BinaryFormat/MsgPackReader.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
1d8e91e46SDimitry Andric //===- MsgPackReader.cpp - Simple MsgPack reader ----------------*- C++ -*-===//
2d8e91e46SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6d8e91e46SDimitry Andric //
7d8e91e46SDimitry Andric //===----------------------------------------------------------------------===//
8d8e91e46SDimitry Andric ///
9d8e91e46SDimitry Andric ///  \file
10d8e91e46SDimitry Andric ///  This file implements a MessagePack reader.
11d8e91e46SDimitry Andric ///
12d8e91e46SDimitry Andric //===----------------------------------------------------------------------===//
13d8e91e46SDimitry Andric 
14d8e91e46SDimitry Andric #include "llvm/BinaryFormat/MsgPackReader.h"
15d8e91e46SDimitry Andric #include "llvm/BinaryFormat/MsgPack.h"
16d8e91e46SDimitry Andric #include "llvm/Support/Endian.h"
17344a3780SDimitry Andric #include "llvm/Support/MathExtras.h"
18d8e91e46SDimitry Andric 
19d8e91e46SDimitry Andric using namespace llvm;
20d8e91e46SDimitry Andric using namespace llvm::support;
21d8e91e46SDimitry Andric using namespace msgpack;
22d8e91e46SDimitry Andric 
Reader(MemoryBufferRef InputBuffer)23d8e91e46SDimitry Andric Reader::Reader(MemoryBufferRef InputBuffer)
24d8e91e46SDimitry Andric     : InputBuffer(InputBuffer), Current(InputBuffer.getBufferStart()),
25d8e91e46SDimitry Andric       End(InputBuffer.getBufferEnd()) {}
26d8e91e46SDimitry Andric 
Reader(StringRef Input)27d8e91e46SDimitry Andric Reader::Reader(StringRef Input) : Reader({Input, "MsgPack"}) {}
28d8e91e46SDimitry Andric 
read(Object & Obj)29d8e91e46SDimitry Andric Expected<bool> Reader::read(Object &Obj) {
30d8e91e46SDimitry Andric   if (Current == End)
31d8e91e46SDimitry Andric     return false;
32d8e91e46SDimitry Andric 
33d8e91e46SDimitry Andric   uint8_t FB = static_cast<uint8_t>(*Current++);
34d8e91e46SDimitry Andric 
35d8e91e46SDimitry Andric   switch (FB) {
36d8e91e46SDimitry Andric   case FirstByte::Nil:
37d8e91e46SDimitry Andric     Obj.Kind = Type::Nil;
38d8e91e46SDimitry Andric     return true;
39d8e91e46SDimitry Andric   case FirstByte::True:
40d8e91e46SDimitry Andric     Obj.Kind = Type::Boolean;
41d8e91e46SDimitry Andric     Obj.Bool = true;
42d8e91e46SDimitry Andric     return true;
43d8e91e46SDimitry Andric   case FirstByte::False:
44d8e91e46SDimitry Andric     Obj.Kind = Type::Boolean;
45d8e91e46SDimitry Andric     Obj.Bool = false;
46d8e91e46SDimitry Andric     return true;
47d8e91e46SDimitry Andric   case FirstByte::Int8:
48d8e91e46SDimitry Andric     Obj.Kind = Type::Int;
49d8e91e46SDimitry Andric     return readInt<int8_t>(Obj);
50d8e91e46SDimitry Andric   case FirstByte::Int16:
51d8e91e46SDimitry Andric     Obj.Kind = Type::Int;
52d8e91e46SDimitry Andric     return readInt<int16_t>(Obj);
53d8e91e46SDimitry Andric   case FirstByte::Int32:
54d8e91e46SDimitry Andric     Obj.Kind = Type::Int;
55d8e91e46SDimitry Andric     return readInt<int32_t>(Obj);
56d8e91e46SDimitry Andric   case FirstByte::Int64:
57d8e91e46SDimitry Andric     Obj.Kind = Type::Int;
58d8e91e46SDimitry Andric     return readInt<int64_t>(Obj);
59d8e91e46SDimitry Andric   case FirstByte::UInt8:
60d8e91e46SDimitry Andric     Obj.Kind = Type::UInt;
61d8e91e46SDimitry Andric     return readUInt<uint8_t>(Obj);
62d8e91e46SDimitry Andric   case FirstByte::UInt16:
63d8e91e46SDimitry Andric     Obj.Kind = Type::UInt;
64d8e91e46SDimitry Andric     return readUInt<uint16_t>(Obj);
65d8e91e46SDimitry Andric   case FirstByte::UInt32:
66d8e91e46SDimitry Andric     Obj.Kind = Type::UInt;
67d8e91e46SDimitry Andric     return readUInt<uint32_t>(Obj);
68d8e91e46SDimitry Andric   case FirstByte::UInt64:
69d8e91e46SDimitry Andric     Obj.Kind = Type::UInt;
70d8e91e46SDimitry Andric     return readUInt<uint64_t>(Obj);
71d8e91e46SDimitry Andric   case FirstByte::Float32:
72d8e91e46SDimitry Andric     Obj.Kind = Type::Float;
73d8e91e46SDimitry Andric     if (sizeof(float) > remainingSpace())
74d8e91e46SDimitry Andric       return make_error<StringError>(
75d8e91e46SDimitry Andric           "Invalid Float32 with insufficient payload",
76d8e91e46SDimitry Andric           std::make_error_code(std::errc::invalid_argument));
777fa27ce4SDimitry Andric     Obj.Float =
787fa27ce4SDimitry Andric         llvm::bit_cast<float>(endian::read<uint32_t, Endianness>(Current));
79d8e91e46SDimitry Andric     Current += sizeof(float);
80d8e91e46SDimitry Andric     return true;
81d8e91e46SDimitry Andric   case FirstByte::Float64:
82d8e91e46SDimitry Andric     Obj.Kind = Type::Float;
83d8e91e46SDimitry Andric     if (sizeof(double) > remainingSpace())
84d8e91e46SDimitry Andric       return make_error<StringError>(
85d8e91e46SDimitry Andric           "Invalid Float64 with insufficient payload",
86d8e91e46SDimitry Andric           std::make_error_code(std::errc::invalid_argument));
877fa27ce4SDimitry Andric     Obj.Float =
887fa27ce4SDimitry Andric         llvm::bit_cast<double>(endian::read<uint64_t, Endianness>(Current));
89d8e91e46SDimitry Andric     Current += sizeof(double);
90d8e91e46SDimitry Andric     return true;
91d8e91e46SDimitry Andric   case FirstByte::Str8:
92d8e91e46SDimitry Andric     Obj.Kind = Type::String;
93d8e91e46SDimitry Andric     return readRaw<uint8_t>(Obj);
94d8e91e46SDimitry Andric   case FirstByte::Str16:
95d8e91e46SDimitry Andric     Obj.Kind = Type::String;
96d8e91e46SDimitry Andric     return readRaw<uint16_t>(Obj);
97d8e91e46SDimitry Andric   case FirstByte::Str32:
98d8e91e46SDimitry Andric     Obj.Kind = Type::String;
99d8e91e46SDimitry Andric     return readRaw<uint32_t>(Obj);
100d8e91e46SDimitry Andric   case FirstByte::Bin8:
101d8e91e46SDimitry Andric     Obj.Kind = Type::Binary;
102d8e91e46SDimitry Andric     return readRaw<uint8_t>(Obj);
103d8e91e46SDimitry Andric   case FirstByte::Bin16:
104d8e91e46SDimitry Andric     Obj.Kind = Type::Binary;
105d8e91e46SDimitry Andric     return readRaw<uint16_t>(Obj);
106d8e91e46SDimitry Andric   case FirstByte::Bin32:
107d8e91e46SDimitry Andric     Obj.Kind = Type::Binary;
108d8e91e46SDimitry Andric     return readRaw<uint32_t>(Obj);
109d8e91e46SDimitry Andric   case FirstByte::Array16:
110d8e91e46SDimitry Andric     Obj.Kind = Type::Array;
111d8e91e46SDimitry Andric     return readLength<uint16_t>(Obj);
112d8e91e46SDimitry Andric   case FirstByte::Array32:
113d8e91e46SDimitry Andric     Obj.Kind = Type::Array;
114d8e91e46SDimitry Andric     return readLength<uint32_t>(Obj);
115d8e91e46SDimitry Andric   case FirstByte::Map16:
116d8e91e46SDimitry Andric     Obj.Kind = Type::Map;
117d8e91e46SDimitry Andric     return readLength<uint16_t>(Obj);
118d8e91e46SDimitry Andric   case FirstByte::Map32:
119d8e91e46SDimitry Andric     Obj.Kind = Type::Map;
120d8e91e46SDimitry Andric     return readLength<uint32_t>(Obj);
121d8e91e46SDimitry Andric   case FirstByte::FixExt1:
122d8e91e46SDimitry Andric     Obj.Kind = Type::Extension;
123d8e91e46SDimitry Andric     return createExt(Obj, FixLen::Ext1);
124d8e91e46SDimitry Andric   case FirstByte::FixExt2:
125d8e91e46SDimitry Andric     Obj.Kind = Type::Extension;
126d8e91e46SDimitry Andric     return createExt(Obj, FixLen::Ext2);
127d8e91e46SDimitry Andric   case FirstByte::FixExt4:
128d8e91e46SDimitry Andric     Obj.Kind = Type::Extension;
129d8e91e46SDimitry Andric     return createExt(Obj, FixLen::Ext4);
130d8e91e46SDimitry Andric   case FirstByte::FixExt8:
131d8e91e46SDimitry Andric     Obj.Kind = Type::Extension;
132d8e91e46SDimitry Andric     return createExt(Obj, FixLen::Ext8);
133d8e91e46SDimitry Andric   case FirstByte::FixExt16:
134d8e91e46SDimitry Andric     Obj.Kind = Type::Extension;
135d8e91e46SDimitry Andric     return createExt(Obj, FixLen::Ext16);
136d8e91e46SDimitry Andric   case FirstByte::Ext8:
137d8e91e46SDimitry Andric     Obj.Kind = Type::Extension;
138d8e91e46SDimitry Andric     return readExt<uint8_t>(Obj);
139d8e91e46SDimitry Andric   case FirstByte::Ext16:
140d8e91e46SDimitry Andric     Obj.Kind = Type::Extension;
141d8e91e46SDimitry Andric     return readExt<uint16_t>(Obj);
142d8e91e46SDimitry Andric   case FirstByte::Ext32:
143d8e91e46SDimitry Andric     Obj.Kind = Type::Extension;
144d8e91e46SDimitry Andric     return readExt<uint32_t>(Obj);
145d8e91e46SDimitry Andric   }
146d8e91e46SDimitry Andric 
147d8e91e46SDimitry Andric   if ((FB & FixBitsMask::NegativeInt) == FixBits::NegativeInt) {
148d8e91e46SDimitry Andric     Obj.Kind = Type::Int;
149d8e91e46SDimitry Andric     int8_t I;
150d8e91e46SDimitry Andric     static_assert(sizeof(I) == sizeof(FB), "Unexpected type sizes");
151d8e91e46SDimitry Andric     memcpy(&I, &FB, sizeof(FB));
152d8e91e46SDimitry Andric     Obj.Int = I;
153d8e91e46SDimitry Andric     return true;
154d8e91e46SDimitry Andric   }
155d8e91e46SDimitry Andric 
156d8e91e46SDimitry Andric   if ((FB & FixBitsMask::PositiveInt) == FixBits::PositiveInt) {
157d8e91e46SDimitry Andric     Obj.Kind = Type::UInt;
158d8e91e46SDimitry Andric     Obj.UInt = FB;
159d8e91e46SDimitry Andric     return true;
160d8e91e46SDimitry Andric   }
161d8e91e46SDimitry Andric 
162d8e91e46SDimitry Andric   if ((FB & FixBitsMask::String) == FixBits::String) {
163d8e91e46SDimitry Andric     Obj.Kind = Type::String;
164d8e91e46SDimitry Andric     uint8_t Size = FB & ~FixBitsMask::String;
165d8e91e46SDimitry Andric     return createRaw(Obj, Size);
166d8e91e46SDimitry Andric   }
167d8e91e46SDimitry Andric 
168d8e91e46SDimitry Andric   if ((FB & FixBitsMask::Array) == FixBits::Array) {
169d8e91e46SDimitry Andric     Obj.Kind = Type::Array;
170d8e91e46SDimitry Andric     Obj.Length = FB & ~FixBitsMask::Array;
171d8e91e46SDimitry Andric     return true;
172d8e91e46SDimitry Andric   }
173d8e91e46SDimitry Andric 
174d8e91e46SDimitry Andric   if ((FB & FixBitsMask::Map) == FixBits::Map) {
175d8e91e46SDimitry Andric     Obj.Kind = Type::Map;
176d8e91e46SDimitry Andric     Obj.Length = FB & ~FixBitsMask::Map;
177d8e91e46SDimitry Andric     return true;
178d8e91e46SDimitry Andric   }
179d8e91e46SDimitry Andric 
180d8e91e46SDimitry Andric   return make_error<StringError>(
181d8e91e46SDimitry Andric       "Invalid first byte", std::make_error_code(std::errc::invalid_argument));
182d8e91e46SDimitry Andric }
183d8e91e46SDimitry Andric 
readRaw(Object & Obj)184d8e91e46SDimitry Andric template <class T> Expected<bool> Reader::readRaw(Object &Obj) {
185d8e91e46SDimitry Andric   if (sizeof(T) > remainingSpace())
186d8e91e46SDimitry Andric     return make_error<StringError>(
187d8e91e46SDimitry Andric         "Invalid Raw with insufficient payload",
188d8e91e46SDimitry Andric         std::make_error_code(std::errc::invalid_argument));
189d8e91e46SDimitry Andric   T Size = endian::read<T, Endianness>(Current);
190d8e91e46SDimitry Andric   Current += sizeof(T);
191d8e91e46SDimitry Andric   return createRaw(Obj, Size);
192d8e91e46SDimitry Andric }
193d8e91e46SDimitry Andric 
readInt(Object & Obj)194d8e91e46SDimitry Andric template <class T> Expected<bool> Reader::readInt(Object &Obj) {
195d8e91e46SDimitry Andric   if (sizeof(T) > remainingSpace())
196d8e91e46SDimitry Andric     return make_error<StringError>(
197d8e91e46SDimitry Andric         "Invalid Int with insufficient payload",
198d8e91e46SDimitry Andric         std::make_error_code(std::errc::invalid_argument));
199d8e91e46SDimitry Andric   Obj.Int = static_cast<int64_t>(endian::read<T, Endianness>(Current));
200d8e91e46SDimitry Andric   Current += sizeof(T);
201d8e91e46SDimitry Andric   return true;
202d8e91e46SDimitry Andric }
203d8e91e46SDimitry Andric 
readUInt(Object & Obj)204d8e91e46SDimitry Andric template <class T> Expected<bool> Reader::readUInt(Object &Obj) {
205d8e91e46SDimitry Andric   if (sizeof(T) > remainingSpace())
206d8e91e46SDimitry Andric     return make_error<StringError>(
207d8e91e46SDimitry Andric         "Invalid Int with insufficient payload",
208d8e91e46SDimitry Andric         std::make_error_code(std::errc::invalid_argument));
209d8e91e46SDimitry Andric   Obj.UInt = static_cast<uint64_t>(endian::read<T, Endianness>(Current));
210d8e91e46SDimitry Andric   Current += sizeof(T);
211d8e91e46SDimitry Andric   return true;
212d8e91e46SDimitry Andric }
213d8e91e46SDimitry Andric 
readLength(Object & Obj)214d8e91e46SDimitry Andric template <class T> Expected<bool> Reader::readLength(Object &Obj) {
215d8e91e46SDimitry Andric   if (sizeof(T) > remainingSpace())
216d8e91e46SDimitry Andric     return make_error<StringError>(
217d8e91e46SDimitry Andric         "Invalid Map/Array with invalid length",
218d8e91e46SDimitry Andric         std::make_error_code(std::errc::invalid_argument));
219d8e91e46SDimitry Andric   Obj.Length = static_cast<size_t>(endian::read<T, Endianness>(Current));
220d8e91e46SDimitry Andric   Current += sizeof(T);
221d8e91e46SDimitry Andric   return true;
222d8e91e46SDimitry Andric }
223d8e91e46SDimitry Andric 
readExt(Object & Obj)224d8e91e46SDimitry Andric template <class T> Expected<bool> Reader::readExt(Object &Obj) {
225d8e91e46SDimitry Andric   if (sizeof(T) > remainingSpace())
226d8e91e46SDimitry Andric     return make_error<StringError>(
227d8e91e46SDimitry Andric         "Invalid Ext with invalid length",
228d8e91e46SDimitry Andric         std::make_error_code(std::errc::invalid_argument));
229d8e91e46SDimitry Andric   T Size = endian::read<T, Endianness>(Current);
230d8e91e46SDimitry Andric   Current += sizeof(T);
231d8e91e46SDimitry Andric   return createExt(Obj, Size);
232d8e91e46SDimitry Andric }
233d8e91e46SDimitry Andric 
createRaw(Object & Obj,uint32_t Size)234d8e91e46SDimitry Andric Expected<bool> Reader::createRaw(Object &Obj, uint32_t Size) {
235d8e91e46SDimitry Andric   if (Size > remainingSpace())
236d8e91e46SDimitry Andric     return make_error<StringError>(
237d8e91e46SDimitry Andric         "Invalid Raw with insufficient payload",
238d8e91e46SDimitry Andric         std::make_error_code(std::errc::invalid_argument));
239d8e91e46SDimitry Andric   Obj.Raw = StringRef(Current, Size);
240d8e91e46SDimitry Andric   Current += Size;
241d8e91e46SDimitry Andric   return true;
242d8e91e46SDimitry Andric }
243d8e91e46SDimitry Andric 
createExt(Object & Obj,uint32_t Size)244d8e91e46SDimitry Andric Expected<bool> Reader::createExt(Object &Obj, uint32_t Size) {
245d8e91e46SDimitry Andric   if (Current == End)
246d8e91e46SDimitry Andric     return make_error<StringError>(
247d8e91e46SDimitry Andric         "Invalid Ext with no type",
248d8e91e46SDimitry Andric         std::make_error_code(std::errc::invalid_argument));
249d8e91e46SDimitry Andric   Obj.Extension.Type = *Current++;
250d8e91e46SDimitry Andric   if (Size > remainingSpace())
251d8e91e46SDimitry Andric     return make_error<StringError>(
252d8e91e46SDimitry Andric         "Invalid Ext with insufficient payload",
253d8e91e46SDimitry Andric         std::make_error_code(std::errc::invalid_argument));
254d8e91e46SDimitry Andric   Obj.Extension.Bytes = StringRef(Current, Size);
255d8e91e46SDimitry Andric   Current += Size;
256d8e91e46SDimitry Andric   return true;
257d8e91e46SDimitry Andric }
258