blob: 6efff0b2f05675a187346e57179afab7fbc4db0c (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
#include "stdafx.h"
#include "trayparser.h"
#include <libcommon/error.h>
#include <iterator>
#include <algorithm>
TrayParser::TrayParser(const std::vector<uint8_t> &blob)
{
if (blob.size() < sizeof(ICON_STREAMS_HEADER))
{
THROW_ERROR("Invalid icon streams header - truncated");
}
auto header = reinterpret_cast<const ICON_STREAMS_HEADER *>(&blob[0]);
if (header->HeaderSize != sizeof(ICON_STREAMS_HEADER))
{
THROW_ERROR("Invalid icon streams header - size mismatch");
}
memcpy(&m_header, header, sizeof(ICON_STREAMS_HEADER));
if (0 == header->NumberRecords)
{
return;
}
//
// At least one record.
//
if (blob.size() < sizeof(ICON_STREAMS_HEADER) + sizeof(ICON_STREAMS_RECORD))
{
THROW_ERROR("Invalid icon streams - truncated");
}
const auto lastValidRecordOffset = blob.size() - sizeof(ICON_STREAMS_RECORD);
if (header->OffsetFirstRecord < header->HeaderSize
|| header->OffsetFirstRecord > lastValidRecordOffset)
{
THROW_ERROR("Invalid icon streams header - record offset");
}
const auto estimatedSize = header->HeaderSize
+ (header->OffsetFirstRecord - header->HeaderSize)
+ (header->NumberRecords * sizeof(ICON_STREAMS_RECORD));
if (blob.size() != estimatedSize)
{
THROW_ERROR("Invalid icon streams - size mismatch");
}
//
// Size checks out.
//
m_records.reserve(header->NumberRecords);
auto begin = reinterpret_cast<const ICON_STREAMS_RECORD *>(&blob[0] + header->OffsetFirstRecord);
auto end = reinterpret_cast<const ICON_STREAMS_RECORD *>(&blob[0] + blob.size());
std::copy(begin, end, std::back_inserter(m_records));
}
const ICON_STREAMS_HEADER &TrayParser::getHeader() const
{
return m_header;
}
const std::vector<ICON_STREAMS_RECORD> &TrayParser::getRecords() const
{
return m_records;
}
|