File: ar_decoder.cpp

package info (click to toggle)
intel-compute-runtime 25.35.35096.9-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 79,324 kB
  • sloc: cpp: 926,243; lisp: 3,433; sh: 715; makefile: 162; python: 21
file content (71 lines) | stat: -rw-r--r-- 3,341 bytes parent folder | download | duplicates (4)
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
/*
 * Copyright (C) 2020 Intel Corporation
 *
 * SPDX-License-Identifier: MIT
 *
 */

#include "shared/source/device_binary_format/ar/ar_decoder.h"

#include <cstdint>

namespace NEO {
namespace Ar {

Ar decodeAr(const ArrayRef<const uint8_t> binary, std::string &outErrReason, std::string &outWarnings) {
    if (false == isAr(binary)) {
        outErrReason = "Not an AR archive - mismatched file signature";
        return {};
    }

    Ar ret;
    ret.magic = reinterpret_cast<const char *>(binary.begin());

    const uint8_t *decodePos = binary.begin() + arMagic.size();
    while (decodePos + sizeof(ArFileEntryHeader) <= binary.end()) {
        auto fileEntryHeader = reinterpret_cast<const ArFileEntryHeader *>(decodePos);
        auto fileEntryDataPos = decodePos + sizeof(ArFileEntryHeader);
        uint64_t fileSize = readDecimal<sizeof(fileEntryHeader->fileSizeInBytes)>(fileEntryHeader->fileSizeInBytes);
        if (fileSize + (fileEntryDataPos - binary.begin()) > binary.size()) {
            outErrReason = "Corrupt AR archive - out of bounds data of file entry with idenfitier '" + std::string(fileEntryHeader->identifier, sizeof(fileEntryHeader->identifier)) + "'";
            return {};
        }

        if (ConstStringRef::fromArray(fileEntryHeader->trailingMagic) != arFileEntryTrailingMagic) {
            outWarnings.append("File entry header with identifier '" + std::string(fileEntryHeader->identifier, sizeof(fileEntryHeader->identifier)) + "' has invalid header trailing string");
        }

        ArFileEntryHeaderAndData fileEntry = {};
        fileEntry.fileName = readUnpaddedString<sizeof(fileEntryHeader->identifier)>(fileEntryHeader->identifier);
        fileEntry.fullHeader = fileEntryHeader;
        fileEntry.fileData = ArrayRef<const uint8_t>(fileEntryDataPos, static_cast<size_t>(fileSize));

        if (fileEntry.fileName.empty()) {
            if (SpecialFileNames::longFileNamesFile == ConstStringRef(fileEntryHeader->identifier, 2U)) {
                fileEntry.fileName = SpecialFileNames::longFileNamesFile;
                ret.longFileNamesEntry = fileEntry;
            } else {
                outErrReason = "Corrupt AR archive - file entry does not have identifier : '" + std::string(fileEntryHeader->identifier, sizeof(fileEntryHeader->identifier)) + "'";
                return {};
            }
        } else {
            if (SpecialFileNames::longFileNamePrefix == fileEntry.fileName[0]) {
                auto longFileNamePos = readDecimal<sizeof(fileEntryHeader->identifier) - 1>(fileEntryHeader->identifier + 1);
                fileEntry.fileName = readLongFileName(ConstStringRef(reinterpret_cast<const char *>(ret.longFileNamesEntry.fileData.begin()), ret.longFileNamesEntry.fileData.size()), static_cast<size_t>(longFileNamePos));
                if (fileEntry.fileName.empty()) {
                    outErrReason = "Corrupt AR archive - long file name entry has broken identifier : '" + std::string(fileEntryHeader->identifier, sizeof(fileEntryHeader->identifier)) + "'";
                    return {};
                }
            }
            ret.files.push_back(fileEntry);
        }

        decodePos = fileEntryDataPos + fileSize;
        decodePos += fileSize & 1U; // implicit 2-byte alignment
    }
    return ret;
}

} // namespace Ar

} // namespace NEO