@@ -240,12 +240,21 @@ auto FixupReaderForFormat(int format) -> std::pair<uint64_t, FixupInfo>(*)(Binar |
240 | 240 | throw std::invalid_argument("Unknown chained pointer format: " + std::to_string(format)); |
241 | 241 | } |
242 | 242 |
|
| 243 | +// Returns the NUL-terminated string starting at `offset` within `symbolData`, or an |
| 244 | +// empty view if `offset` does not fall within `symbolData`. |
| 245 | +std::string_view SymbolNameAt(std::span<const char> symbolData, uint32_t offset) |
| 246 | +{ |
| 247 | + if (symbolData.size() <= offset) |
| 248 | + return std::string_view(); |
| 249 | + return std::string_view(&symbolData[offset], strnlen(&symbolData[offset], symbolData.size() - offset)); |
| 250 | +} |
| 251 | + |
243 | 252 | ImportEntry ReadChainedImport32(BinaryReader& reader, std::span<const char> symbolData) |
244 | 253 | { |
245 | 254 | dyld_chained_import import; |
246 | 255 | reader.Read(&import, sizeof(import)); |
247 | 256 | return { |
248 | | - std::string_view(&symbolData[import.name_offset]), |
| 257 | + SymbolNameAt(symbolData, import.name_offset), |
249 | 258 | 0, |
250 | 259 | import.lib_ordinal > 0xF0 ? static_cast<int8_t>(import.lib_ordinal) : static_cast<int32_t>(import.lib_ordinal), |
251 | 260 | (bool)import.weak_import, |
@@ -257,7 +266,7 @@ ImportEntry ReadChainedImportAddend32(BinaryReader& reader, std::span<const char |
257 | 266 | dyld_chained_import_addend import; |
258 | 267 | reader.Read(&import, sizeof(import)); |
259 | 268 | return { |
260 | | - std::string_view(&symbolData[import.name_offset]), |
| 269 | + SymbolNameAt(symbolData, import.name_offset), |
261 | 270 | static_cast<uint32_t>(import.addend), |
262 | 271 | import.lib_ordinal > 0xF0 ? static_cast<int8_t>(import.lib_ordinal) : static_cast<int32_t>(import.lib_ordinal), |
263 | 272 | (bool)import.weak_import, |
@@ -269,7 +278,7 @@ ImportEntry ReadChainedImportAddend64(BinaryReader& reader, std::span<const char |
269 | 278 | dyld_chained_import_addend64 import; |
270 | 279 | reader.Read(&import, sizeof(import)); |
271 | 280 | return { |
272 | | - std::string_view(&symbolData[import.name_offset]), |
| 281 | + SymbolNameAt(symbolData, import.name_offset), |
273 | 282 | import.addend, |
274 | 283 | import.lib_ordinal > 0xFFF0 ? static_cast<int16_t>(import.lib_ordinal) : static_cast<int32_t>(import.lib_ordinal), |
275 | 284 | (bool)import.weak_import, |
@@ -304,6 +313,8 @@ std::vector<ImportEntry> ChainedFixupProcessor::ProcessImports() const |
304 | 313 |
|
305 | 314 | auto header = ReadHeader(reader); |
306 | 315 |
|
| 316 | + if (header.symbols_offset >= m_fixupsSize) |
| 317 | + return imports; |
307 | 318 | uint64_t symbolDataSize = m_fixupsSize - header.symbols_offset; |
308 | 319 | m_symbolData.resize(symbolDataSize); |
309 | 320 | m_raw->Read(&m_symbolData[0], OffsetInFixups(header.symbols_offset), symbolDataSize); |
@@ -435,7 +446,7 @@ void ChainedFixupProcessor::ProcessChainsInSegment(const dyld_chained_starts_in_ |
435 | 446 |
|
436 | 447 | bool done = false; |
437 | 448 | while (!done) |
438 | | - { |
| 449 | + { |
439 | 450 | uint64_t position = reader.GetOffset(); |
440 | 451 | auto [raw, fixupInfo] = fixupReader(reader); |
441 | 452 |
|
|