summaryrefslogtreecommitdiffhomepage
path: root/windows/nsis-plugins/src/tray/trayparser.cpp
diff options
context:
space:
mode:
authorOdd Stranne <odd@mullvad.net>2018-12-05 11:53:09 +0100
committerOdd Stranne <odd@mullvad.net>2018-12-05 11:53:09 +0100
commitaecaaa2a5652bf787e8000eaeea5b820456122ee (patch)
tree513739b9d5d2f06f72e311665a54a9d19e0cfb31 /windows/nsis-plugins/src/tray/trayparser.cpp
parent39678f83206d92905cb401643d7b78a06131c398 (diff)
parent941ebe599354844f01b3bc1efb2fe236fbbb3e30 (diff)
downloadmullvadvpn-aecaaa2a5652bf787e8000eaeea5b820456122ee.tar.xz
mullvadvpn-aecaaa2a5652bf787e8000eaeea5b820456122ee.zip
Merge branch 'win-promote-tray'
Diffstat (limited to 'windows/nsis-plugins/src/tray/trayparser.cpp')
-rw-r--r--windows/nsis-plugins/src/tray/trayparser.cpp73
1 files changed, 73 insertions, 0 deletions
diff --git a/windows/nsis-plugins/src/tray/trayparser.cpp b/windows/nsis-plugins/src/tray/trayparser.cpp
new file mode 100644
index 0000000000..4ff3573c81
--- /dev/null
+++ b/windows/nsis-plugins/src/tray/trayparser.cpp
@@ -0,0 +1,73 @@
+#include "stdafx.h"
+#include "trayparser.h"
+#include <stdexcept>
+#include <algorithm>
+
+TrayParser::TrayParser(const std::vector<uint8_t> &blob)
+{
+ if (blob.size() < sizeof(ICON_STREAMS_HEADER))
+ {
+ throw std::runtime_error("Invalid icon streams header - truncated");
+ }
+
+ auto header = reinterpret_cast<const ICON_STREAMS_HEADER *>(&blob[0]);
+
+ if (header->HeaderSize != sizeof(ICON_STREAMS_HEADER))
+ {
+ throw std::runtime_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 std::runtime_error("Invalid icon streams - truncated");
+ }
+
+ const auto lastValidRecordOffset = blob.size() - sizeof(ICON_STREAMS_RECORD);
+
+ if (header->OffsetFirstRecord < header->HeaderSize
+ || header->OffsetFirstRecord > lastValidRecordOffset)
+ {
+ throw std::runtime_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 std::runtime_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;
+}