diff options
| author | Odd Stranne <odd@mullvad.net> | 2018-12-04 11:58:47 +0100 |
|---|---|---|
| committer | Odd Stranne <odd@mullvad.net> | 2018-12-05 11:35:01 +0100 |
| commit | 6ce570405e255e0ea9f0f761a73110037fa52603 (patch) | |
| tree | 1a2fdc2aa095347259c665e7d784911f77774b34 /windows/nsis-plugins/src/tray/trayparser.cpp | |
| parent | 33c47d606e344fa91a3c6ddad67d5564f6ba16b5 (diff) | |
| download | mullvadvpn-6ce570405e255e0ea9f0f761a73110037fa52603.tar.xz mullvadvpn-6ce570405e255e0ea9f0f761a73110037fa52603.zip | |
Add NSIS plugin for installing tray icon
Diffstat (limited to 'windows/nsis-plugins/src/tray/trayparser.cpp')
| -rw-r--r-- | windows/nsis-plugins/src/tray/trayparser.cpp | 73 |
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; +} |
