File size: 1,789 Bytes
a706ef6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
#include <cstdint>
#include <iostream>
#include <vector>

#include "avro/Decoder.hh"
#include "avro/Reader.hh"
#include "avro/Stream.hh"
#include "avro/buffer/Buffer.hh"

namespace {

avro::InputBuffer makeBuffer(const std::vector<uint8_t> &bytes) {
    avro::OutputBuffer output;
    output.writeTo(reinterpret_cast<const char *>(bytes.data()), bytes.size());
    return output.extractData();
}

void decodeLegacy(const char *label, const std::vector<uint8_t> &bytes) {
    avro::Reader reader(makeBuffer(bytes));
    int64_t value = 0;
    reader.readValue(value);
    std::cout << label << ": legacy Reader decoded " << value << '\n';
}

void decodeModern(const char *label, const std::vector<uint8_t> &bytes) {
    auto input = avro::memoryInputStream(bytes.data(), bytes.size());
    auto decoder = avro::binaryDecoder();
    decoder->init(*input);

    try {
        const int64_t value = decoder->decodeLong();
        std::cout << label << ": modern BinaryDecoder decoded " << value << '\n';
    } catch (const std::exception &error) {
        std::cout << label << ": modern BinaryDecoder rejected input: "
                  << error.what() << '\n';
    }
}

} // namespace

int main() {
    const std::vector<uint8_t> control = {0x02}; // zig-zag encoding of 1

    // Eleven continuation bytes advance shift through 0, 7, ... 63, 70.
    // The legacy Reader performs uint64_t(...) << shift before checking any
    // upper bound, while the modern decoder rejects shift >= 64.
    const std::vector<uint8_t> trigger = {
        0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
        0x81, 0x81, 0x81, 0x81, 0x00,
    };

    decodeLegacy("control", control);
    decodeModern("control", control);
    decodeModern("trigger", trigger);
    decodeLegacy("trigger", trigger);
    return 0;
}