lsqpack 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +19 -0
  3. data/Gemfile.lock +82 -0
  4. data/LICENSE +21 -0
  5. data/README.md +36 -0
  6. data/Rakefile +19 -0
  7. data/Steepfile +6 -0
  8. data/ext/lsqpack/extconf.rb +18 -0
  9. data/ext/lsqpack/lsqpack.c +426 -0
  10. data/ext/lsqpack/lsqpack.h +6 -0
  11. data/lib/lsqpack/version.rb +5 -0
  12. data/lib/lsqpack.rb +30 -0
  13. data/ls-qpack/.appveyor.yml +14 -0
  14. data/ls-qpack/.cirrus.yml +6 -0
  15. data/ls-qpack/.travis.yml +32 -0
  16. data/ls-qpack/CMakeLists.txt +66 -0
  17. data/ls-qpack/LICENSE +21 -0
  18. data/ls-qpack/README.md +65 -0
  19. data/ls-qpack/bin/CMakeLists.txt +21 -0
  20. data/ls-qpack/bin/encode-int.c +87 -0
  21. data/ls-qpack/bin/fuzz-decode.c +247 -0
  22. data/ls-qpack/bin/interop-decode.c +433 -0
  23. data/ls-qpack/bin/interop-encode.c +554 -0
  24. data/ls-qpack/deps/xxhash/xxhash.c +941 -0
  25. data/ls-qpack/deps/xxhash/xxhash.h +160 -0
  26. data/ls-qpack/fuzz/decode/a/README +3 -0
  27. data/ls-qpack/fuzz/decode/a/preamble +0 -0
  28. data/ls-qpack/fuzz/decode/a/test-cases/id_000000,sig_06,src_000390,op_havoc,rep_4 +0 -0
  29. data/ls-qpack/fuzz/decode/a/test-cases/id_000000,sig_06,src_000579,op_flip1,pos_14 +0 -0
  30. data/ls-qpack/fuzz/decode/a/test-cases/id_000000,src_000000,op_flip2,pos_12 +0 -0
  31. data/ls-qpack/fuzz/decode/a/test-cases/id_000001,sig_11,src_000579,op_havoc,rep_4 +0 -0
  32. data/ls-qpack/fuzz/decode/a/test-cases/id_000002,sig_11,src_000481,op_int16,pos_15,val_-1 +0 -0
  33. data/ls-qpack/fuzz/decode/a/test-cases/id_000002,src_000000,op_havoc,rep_8 +0 -0
  34. data/ls-qpack/fuzz/decode/a/test-cases/id_000006,src_000285,op_flip2,pos_14 +0 -0
  35. data/ls-qpack/fuzz/decode/a/test-cases/id_000008,src_000285,op_flip2,pos_20 +0 -0
  36. data/ls-qpack/fuzz/decode/a/test-cases/id_000010,src_000306,op_flip2,pos_75 +0 -0
  37. data/ls-qpack/fuzz/decode/a/test-cases/id_000011,src_000344,op_havoc,rep_2 +0 -0
  38. data/ls-qpack/fuzz/decode/a/test-cases/id_000014,src_000366,op_flip2,pos_28 +0 -0
  39. data/ls-qpack/fuzz/decode/b/README +1 -0
  40. data/ls-qpack/fuzz/decode/b/preamble +0 -0
  41. data/ls-qpack/fuzz/decode/b/test-cases/seed +0 -0
  42. data/ls-qpack/fuzz/decode/c/setup.sh +3 -0
  43. data/ls-qpack/fuzz/decode/c/test-cases/fb-req.qif.proxygen.out.256.100.0-chopped +0 -0
  44. data/ls-qpack/fuzz/decode/d/preamble +0 -0
  45. data/ls-qpack/fuzz/decode/d/setup.sh +3 -0
  46. data/ls-qpack/fuzz/decode/d/test-cases/fb-resp.minhq.256.128.0.ack +0 -0
  47. data/ls-qpack/fuzz/input/256.100.1/fb-req.out.256.100.1 +0 -0
  48. data/ls-qpack/fuzz/input/256.100.1/fb-resp.out.256.100.1 +0 -0
  49. data/ls-qpack/fuzz/input/256.100.1/netbsd.out.256.100.1 +0 -0
  50. data/ls-qpack/huff-tables.h +136247 -0
  51. data/ls-qpack/lsqpack.c +5547 -0
  52. data/ls-qpack/lsqpack.h +768 -0
  53. data/ls-qpack/test/CMakeLists.txt +76 -0
  54. data/ls-qpack/test/lsqpack-test.h +43 -0
  55. data/ls-qpack/test/qifs/fb-req.qif +4917 -0
  56. data/ls-qpack/test/qifs/fb-resp.qif +5982 -0
  57. data/ls-qpack/test/qifs/long-codes.qif +5984 -0
  58. data/ls-qpack/test/qifs/netbsd.qif +235 -0
  59. data/ls-qpack/test/run-qif.pl +97 -0
  60. data/ls-qpack/test/run-scenario.sh +68 -0
  61. data/ls-qpack/test/scenarios/0.95-reset.sce +10 -0
  62. data/ls-qpack/test/scenarios/cancel-stream.sce +22 -0
  63. data/ls-qpack/test/scenarios/drain-2.sce +37 -0
  64. data/ls-qpack/test/scenarios/drain.sce +37 -0
  65. data/ls-qpack/test/scenarios/end-dst-2.sce +14 -0
  66. data/ls-qpack/test/scenarios/end-dst.sce +14 -0
  67. data/ls-qpack/test/scenarios/incl-name.sce +13 -0
  68. data/ls-qpack/test/scenarios/multi-byte-int-dyn-ref-1.sce +110 -0
  69. data/ls-qpack/test/scenarios/multi-byte-int-dyn-ref-2.sce +161 -0
  70. data/ls-qpack/test/scenarios/post-base-1.sce +10 -0
  71. data/ls-qpack/test/scenarios/post-base-2.sce +13 -0
  72. data/ls-qpack/test/scenarios/post-base-nr.sce +10 -0
  73. data/ls-qpack/test/scenarios/set-max-cap.sce +15 -0
  74. data/ls-qpack/test/test_enc_str.c +139 -0
  75. data/ls-qpack/test/test_get_stx_id.c +144 -0
  76. data/ls-qpack/test/test_huff_dec.c +399 -0
  77. data/ls-qpack/test/test_int.c +220 -0
  78. data/ls-qpack/test/test_qpack.c +856 -0
  79. data/ls-qpack/test/test_read_enc_stream.c +256 -0
  80. data/ls-qpack/tools/har2qif.pl +139 -0
  81. data/ls-qpack/tools/randomize-cookies.pl +41 -0
  82. data/ls-qpack/tools/sort-qif.pl +31 -0
  83. data/ls-qpack/wincompat/getopt.c +758 -0
  84. data/ls-qpack/wincompat/getopt.h +131 -0
  85. data/ls-qpack/wincompat/getopt1.c +188 -0
  86. data/ls-qpack/wincompat/sys/queue.h +859 -0
  87. data/lsqpack.gemspec +39 -0
  88. data/sig/lsqpack.rbs +29 -0
  89. metadata +135 -0
@@ -0,0 +1,6 @@
1
+ freebsd_instance:
2
+ image: freebsd-12-1-release-amd64
3
+
4
+ task:
5
+ install_script: pkg install -y cmake bash perl5
6
+ script: cmake -DLSQPACK_TESTS=ON . && make && make test
@@ -0,0 +1,32 @@
1
+ language: c
2
+ sudo: false
3
+ addons:
4
+ apt:
5
+ matrix:
6
+ include:
7
+ - name: Linux (gcc-8)
8
+ os: linux
9
+ dist: xenial
10
+ compiler: gcc-8
11
+ addons:
12
+ apt:
13
+ sources:
14
+ - ubuntu-toolchain-r-test
15
+ packages: g++-8
16
+ - name: Linux (clang)
17
+ os: linux
18
+ dist: xenial
19
+ compiler: clang
20
+ - name: macOS (xcode)
21
+ os: osx
22
+ - name: macOS (xcode 10.1)
23
+ os: osx
24
+ image: xcode10.1
25
+ before_install:
26
+ - $CC --version
27
+ - cmake --version
28
+ before_script:
29
+ - cmake -DLSQPACK_TESTS=ON .
30
+ script:
31
+ - make
32
+ - make test
@@ -0,0 +1,66 @@
1
+ # The following variable can be defined on the command line:
2
+ #
3
+ # BUILD_SHARED_LIBS
4
+ #
5
+ # The following environment variables will be taken into account when running
6
+ # cmake for the first time:
7
+ #
8
+ # CFLAGS
9
+ # LDFLAGS
10
+
11
+ cmake_minimum_required(VERSION 3.1)
12
+ project(ls-qpack LANGUAGES C)
13
+
14
+ option(LSQPACK_TESTS "Build tests")
15
+ option(LSQPACK_BIN "Build binaries" ON)
16
+ option(LSQPACK_XXH "Include XXH" ON)
17
+
18
+ # Use `cmake -DBUILD_SHARED_LIBS=OFF` to build a static library.
19
+ add_library(ls-qpack "")
20
+ target_include_directories(ls-qpack PUBLIC .)
21
+ target_sources(ls-qpack PRIVATE lsqpack.c)
22
+
23
+ target_include_directories(ls-qpack PRIVATE deps/xxhash/)
24
+ if(LSQPACK_XXH)
25
+ target_sources(ls-qpack PRIVATE deps/xxhash/xxhash.c)
26
+ endif()
27
+
28
+ if(MSVC)
29
+ target_include_directories(ls-qpack PUBLIC wincompat)
30
+ endif()
31
+
32
+ if(MSVC)
33
+ target_compile_options(ls-qpack PRIVATE
34
+ /Wall
35
+ /wd4100 # unreffed parameter
36
+ /wd4200 # zero-sized array
37
+ # Apparently this C99 construct is not supported properly by VS:
38
+ # https://stackoverflow.com/questions/1064930/struct-initializer-typedef-with-visual-studio
39
+ /wd4204 # non-constant aggregate initializer
40
+ /wd4255 # no function prototype (getopt)
41
+ /wd4820 # padding
42
+ /wd4668 # undefined macro
43
+ /wd4710 # not inlined by default
44
+ /wd4996 # unsafe function
45
+ )
46
+ else()
47
+ target_compile_options(ls-qpack PRIVATE
48
+ -Wall
49
+ -Wextra
50
+ -Wno-unused-parameter
51
+ -fno-omit-frame-pointer
52
+ )
53
+ endif()
54
+
55
+ IF (CMAKE_BUILD_TYPE STREQUAL MinSizeRel)
56
+ SET(CMAKE_C_FLAGS "${CMAKE_C_CFLAGS} -DLS_QPACK_USE_LARGE_TABLES=0")
57
+ ENDIF()
58
+
59
+ if(LSQPACK_TESTS)
60
+ enable_testing()
61
+ add_subdirectory(test)
62
+ endif()
63
+
64
+ if(LSQPACK_BIN)
65
+ add_subdirectory(bin)
66
+ endif()
data/ls-qpack/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 - 2020 LiteSpeed Tech
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,65 @@
1
+ [![Build Status](https://travis-ci.org/litespeedtech/ls-qpack.svg?branch=master)](https://travis-ci.org/litespeedtech/ls-qpack)
2
+ [![Build status](https://ci.appveyor.com/api/projects/status/kat31lt42ds0rmom?svg=true)](https://ci.appveyor.com/project/litespeedtech/ls-qpack)
3
+ [![Build Status](https://api.cirrus-ci.com/github/litespeedtech/ls-qpack.svg)](https://cirrus-ci.com/github/litespeedtech/ls-qpack)
4
+
5
+ # ls-qpack
6
+ QPACK compression library for use with HTTP/3
7
+
8
+ ## Introduction
9
+
10
+ QPACK is the compression mechanism used by
11
+ [HTTP/3](https://en.wikipedia.org/wiki/HTTP/3) to compress HTTP headers.
12
+ It is in the process of being standardazed by the QUIC Working Group. The
13
+ [QPACK Internet-Draft](https://tools.ietf.org/html/draft-ietf-quic-qpack-11)
14
+ is has been stable for some time and we don't expect functional changes to
15
+ it before the final RFC is released.
16
+
17
+ ## Functionality
18
+
19
+ ls-qpack is a full-featured, tested, and fast QPACK library. The QPACK encoder
20
+ produces excellent compression results based on an innovative mnemonic technique
21
+ (to be described in a future article). It boasts the fastest Huffman
22
+ [encoder](https://blog.litespeedtech.com/2019/10/03/fast-huffman-encoder/) and
23
+ [decoder](https://blog.litespeedtech.com/2019/09/16/fast-huffman-decoder/).
24
+
25
+ The library is production quality. It is used in
26
+ [OpenLiteSpeed](https://openlitespeed.org/),
27
+ LiteSpeed [Web Server](https://www.litespeedtech.com/products#lsws),
28
+ and LiteSpeed [Web ADC](https://www.litespeedtech.com/products#wadc).
29
+
30
+ The library is robust:
31
+ 1. The encoder does not assume anything about usual HTTP headers such as `Server`
32
+ or `User-Agent`. Instead, it uses its mnemonic compression technique to
33
+ achieve good compression results for any input.
34
+ 1. The decoder uses modulo arithmetic to track dynamic table insertions. This is
35
+ in contrast to all other QPACK implementations, which use an integer counter,
36
+ meaning that at some point, the decoder will break.
37
+ 1. The decoder processes input in streaming fashion. The caller does not have to
38
+ buffer the contents of HTTP/3 `HEADERS` frame. Instead, the decoder can be
39
+ supplied input byte-by-byte.
40
+
41
+ ## Other Languages
42
+
43
+ The ls-qpack library is implemented in vanilla C99. It makes it a good candidate
44
+ for wrapping into a library for a higher-level language. As of this writing, we
45
+ know of the following wrappers:
46
+ - Go: [ls-qpack-go](https://github.com/mpiraux/ls-qpack-go)
47
+ - Python: [pylsqpack](https://github.com/aiortc/pylsqpack)
48
+ - TypeScript: [quicker](https://github.com/rmarx/quicker/tree/draft-20/lib/ls-qpack)
49
+
50
+ ## Versioning
51
+
52
+ Before the QPACK RFC is released, the three parts of the version are:
53
+ - MAJOR: set to zero;
54
+ - MINOR: set to the number of QPACK Internet-Draft the lirbary supports; and
55
+ - PATCH: set to the patch number
56
+
57
+ Once the RFC is released, MARJO will be set to 1 and the version will follow
58
+ the usual MAJOR.MINOR.PATCH pattern.
59
+
60
+ ## API
61
+
62
+ The API is documented in the header file, [lsqpack.h](lsqpack.h).
63
+ One example how it is used in real code can be seen in
64
+ [lsquic](https://github.com/litespeedtech/lsquic), a QUIC and HTTP/3 library
65
+ developed by LiteSpeed Technologies.
@@ -0,0 +1,21 @@
1
+ function(lsqpack_add_executable TARGET)
2
+ add_executable(${TARGET} "")
3
+ target_link_libraries(${TARGET} PRIVATE ls-qpack)
4
+
5
+ target_sources(${TARGET} PRIVATE ${TARGET}.c)
6
+
7
+ if(MSVC)
8
+ target_include_directories(${TARGET} PRIVATE ../wincompat)
9
+ target_sources(${TARGET} PRIVATE
10
+ ../wincompat/getopt.c
11
+ ../wincompat/getopt1.c
12
+ )
13
+ else()
14
+ target_link_libraries(${TARGET} PRIVATE m)
15
+ endif()
16
+ endfunction()
17
+
18
+ lsqpack_add_executable(interop-encode)
19
+ lsqpack_add_executable(interop-decode)
20
+ lsqpack_add_executable(encode-int)
21
+ lsqpack_add_executable(fuzz-decode)
@@ -0,0 +1,87 @@
1
+ /* encode-int: encode an integer into HPACK varint. */
2
+
3
+ #include <assert.h>
4
+ #include <stdio.h>
5
+ #include <stdlib.h>
6
+ #include <stdint.h>
7
+
8
+
9
+ static unsigned char *
10
+ enc_int (unsigned char *dst, unsigned char *const end, uint64_t value,
11
+ unsigned prefix_bits)
12
+ {
13
+ unsigned char *const dst_orig = dst;
14
+
15
+ /* This function assumes that at least one byte is available */
16
+ assert(dst < end);
17
+ if (value < (1u << prefix_bits) - 1)
18
+ *dst++ |= value;
19
+ else
20
+ {
21
+ *dst++ |= (1 << prefix_bits) - 1;
22
+ value -= (1 << prefix_bits) - 1;
23
+ while (value >= 128)
24
+ {
25
+ if (dst < end)
26
+ {
27
+ *dst++ = 0x80 | (unsigned char) value;
28
+ value >>= 7;
29
+ }
30
+ else
31
+ return dst_orig;
32
+ }
33
+ if (dst < end)
34
+ *dst++ = (unsigned char) value;
35
+ else
36
+ return dst_orig;
37
+ }
38
+ return dst;
39
+ }
40
+
41
+ static unsigned
42
+ lsqpack_val2len (uint64_t value, unsigned prefix_bits)
43
+ {
44
+ uint64_t mask = (1ULL << prefix_bits) - 1;
45
+ return 1
46
+ + (value >= mask )
47
+ + (value >= ((1ULL << 7) + mask))
48
+ + (value >= ((1ULL << 14) + mask))
49
+ + (value >= ((1ULL << 21) + mask))
50
+ + (value >= ((1ULL << 28) + mask))
51
+ + (value >= ((1ULL << 35) + mask))
52
+ + (value >= ((1ULL << 42) + mask))
53
+ + (value >= ((1ULL << 49) + mask))
54
+ + (value >= ((1ULL << 56) + mask))
55
+ + (value >= ((1ULL << 63) + mask))
56
+ ;
57
+ }
58
+
59
+ int
60
+ main (int argc, char **argv)
61
+ {
62
+ unsigned long long val;
63
+ unsigned char *p;
64
+ unsigned prefix_bits;
65
+ unsigned char buf[20];
66
+
67
+ if (argc != 3)
68
+ {
69
+ fprintf(stderr, "Usage: %s prefix_bits value\n", argv[0]);
70
+ exit(EXIT_FAILURE);
71
+ }
72
+
73
+ prefix_bits = atoi(argv[1]);
74
+ val = strtoull(argv[2], NULL, 10);
75
+
76
+ fprintf(stderr, "expected size: %u\n", lsqpack_val2len(val, prefix_bits));
77
+ buf[0] = 0;
78
+ p = enc_int(buf, buf + sizeof(buf), val, prefix_bits);
79
+
80
+ if (p > buf)
81
+ {
82
+ fwrite(buf, 1, p - buf, stdout);
83
+ exit(EXIT_SUCCESS);
84
+ }
85
+ else
86
+ exit(EXIT_FAILURE);
87
+ }
@@ -0,0 +1,247 @@
1
+ /*
2
+ * fuzz-decode: special program for fuzzing. It still reads encoded
3
+ * files just like interop-decode, but tries to do it faster and
4
+ * forgoes several advanced options.
5
+ */
6
+
7
+ #ifdef WIN32
8
+
9
+ #include <stdio.h>
10
+
11
+ int
12
+ main (int argc, char **argv)
13
+ {
14
+ fprintf(stderr, "%s is not supported on Windows: need mmap(2)\n", argv[0]);
15
+ return 1;
16
+ }
17
+
18
+ #else
19
+
20
+ #include <assert.h>
21
+
22
+ #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__)
23
+ #include <sys/endian.h>
24
+ #define bswap_16 bswap16
25
+ #define bswap_32 bswap32
26
+ #define bswap_64 bswap64
27
+ #elif defined(__APPLE__)
28
+ #include <libkern/OSByteOrder.h>
29
+ #define bswap_16 OSSwapInt16
30
+ #define bswap_32 OSSwapInt32
31
+ #define bswap_64 OSSwapInt64
32
+ #elif defined(WIN32)
33
+ #define bswap_16 _byteswap_ushort
34
+ #define bswap_32 _byteswap_ulong
35
+ #define bswap_64 _byteswap_uint64
36
+ #else
37
+ #include <byteswap.h>
38
+ #endif
39
+
40
+ #include <errno.h>
41
+ #include <inttypes.h>
42
+ #include <stdio.h>
43
+ #include <stdlib.h>
44
+ #include <string.h>
45
+ #include <unistd.h>
46
+ #include <sys/queue.h>
47
+ #include <sys/types.h>
48
+ #include <sys/stat.h>
49
+ #include <sys/mman.h>
50
+ #include <fcntl.h>
51
+
52
+ #include "lsqpack.h"
53
+
54
+ #define MIN(a, b) ((a) < (b) ? (a) : (b))
55
+
56
+ static void
57
+ usage (const char *name)
58
+ {
59
+ fprintf(stderr,
60
+ "Usage: %s [options] [-i input] [-o output]\n"
61
+ "\n"
62
+ "Options:\n"
63
+ " -i FILE Input file.\n"
64
+ " -f FILE Fuzz file: this is the stuff the fuzzer will change.\n"
65
+ " -s NUMBER Maximum number of risked streams. Defaults to %u.\n"
66
+ " -t NUMBER Dynamic table size. Defaults to %u.\n"
67
+ "\n"
68
+ " -h Print this help screen and exit\n"
69
+ , name, LSQPACK_DEF_MAX_RISKED_STREAMS, LSQPACK_DEF_DYN_TABLE_SIZE);
70
+ }
71
+
72
+
73
+ static void
74
+ hblock_unblocked (void *buf_p)
75
+ {
76
+ exit(1);
77
+ }
78
+
79
+
80
+ int
81
+ main (int argc, char **argv)
82
+ {
83
+ int in_fd = -1, fuzz_fd = STDIN_FILENO;
84
+ int opt;
85
+ unsigned dyn_table_size = LSQPACK_DEF_DYN_TABLE_SIZE,
86
+ max_risked_streams = LSQPACK_DEF_MAX_RISKED_STREAMS;
87
+ struct lsqpack_dec decoder;
88
+ const unsigned char *p, *end;
89
+ unsigned char *begin;
90
+ struct stat st;
91
+ uint64_t stream_id;
92
+ uint32_t size;
93
+ int r;
94
+
95
+ while (-1 != (opt = getopt(argc, argv, "i:f:s:t:h")))
96
+ {
97
+ switch (opt)
98
+ {
99
+ case 'i':
100
+ in_fd = open(optarg, O_RDONLY);
101
+ if (in_fd < 0)
102
+ {
103
+ fprintf(stderr, "cannot open `%s' for reading: %s\n",
104
+ optarg, strerror(errno));
105
+ exit(EXIT_FAILURE);
106
+ }
107
+ break;
108
+ case 'f':
109
+ fuzz_fd = open(optarg, O_RDONLY);
110
+ if (fuzz_fd < 0)
111
+ {
112
+ fprintf(stderr, "cannot open `%s' for reading: %s\n",
113
+ optarg, strerror(errno));
114
+ exit(EXIT_FAILURE);
115
+ }
116
+ break;
117
+ case 's':
118
+ max_risked_streams = atoi(optarg);
119
+ break;
120
+ case 't':
121
+ dyn_table_size = atoi(optarg);
122
+ break;
123
+ case 'h':
124
+ usage(argv[0]);
125
+ exit(EXIT_SUCCESS);
126
+ default:
127
+ exit(EXIT_FAILURE);
128
+ }
129
+ }
130
+
131
+ lsqpack_dec_init(&decoder, NULL, dyn_table_size, max_risked_streams,
132
+ hblock_unblocked);
133
+
134
+ if (in_fd < 0)
135
+ {
136
+ fprintf(stderr, "Specify input using `-i' option\n");
137
+ exit(1);
138
+ }
139
+
140
+ if (0 != fstat(in_fd, &st))
141
+ {
142
+ perror("fstat");
143
+ exit(1);
144
+ }
145
+
146
+ begin = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, in_fd, 0);
147
+ if (!begin)
148
+ {
149
+ perror("mmap");
150
+ exit(1);
151
+ }
152
+
153
+ p = begin;
154
+ end = begin + st.st_size;
155
+ while (p + sizeof(stream_id) + sizeof(size) < end)
156
+ {
157
+ stream_id = * (uint64_t *) p;
158
+ p += sizeof(uint64_t);
159
+ size = * (uint32_t *) p;
160
+ p += sizeof(uint32_t);
161
+ #if __BYTE_ORDER == __LITTLE_ENDIAN
162
+ stream_id = bswap_64(stream_id);
163
+ size = bswap_32(size);
164
+ #endif
165
+ if (p + size > end)
166
+ {
167
+ fprintf(stderr, "truncated input at offset %u",
168
+ (unsigned) (p - begin));
169
+ abort();
170
+ }
171
+ if (stream_id == 0)
172
+ {
173
+ r = lsqpack_dec_enc_in(&decoder, p, size);
174
+ if (r != 0)
175
+ abort();
176
+ }
177
+ else
178
+ {
179
+ const unsigned char *cur = p;
180
+ struct lsqpack_header_list *hlist;
181
+ enum lsqpack_read_header_status rhs;
182
+ rhs = lsqpack_dec_header_in(&decoder, NULL, stream_id,
183
+ size, &cur, size, &hlist, NULL, NULL);
184
+ if (rhs != LQRHS_DONE || (uint32_t) (cur - p) != size)
185
+ abort();
186
+ lsqpack_dec_destroy_header_list(hlist);
187
+ }
188
+ p += size;
189
+ }
190
+
191
+ munmap(begin, st.st_size);
192
+ (void) close(in_fd);
193
+
194
+ /* Now let's read the fuzzed part */
195
+
196
+ if (0 != fstat(fuzz_fd, &st))
197
+ {
198
+ perror("fstat");
199
+ exit(1);
200
+ }
201
+
202
+ begin = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fuzz_fd, 0);
203
+ if (!begin)
204
+ {
205
+ perror("mmap");
206
+ exit(1);
207
+ }
208
+
209
+ p = begin;
210
+ end = begin + st.st_size;
211
+ while (p + sizeof(stream_id) + sizeof(size) < end)
212
+ {
213
+ stream_id = * (uint64_t *) p;
214
+ p += sizeof(uint64_t);
215
+ size = * (uint32_t *) p;
216
+ p += sizeof(uint32_t);
217
+ #if __BYTE_ORDER == __LITTLE_ENDIAN
218
+ stream_id = bswap_64(stream_id);
219
+ size = bswap_32(size);
220
+ #endif
221
+ if (stream_id == 0)
222
+ {
223
+ r = lsqpack_dec_enc_in(&decoder, p, MIN(size, (uint32_t) (end - p)));
224
+ (void) r;
225
+ }
226
+ else
227
+ {
228
+ const unsigned char *cur = p;
229
+ struct lsqpack_header_list *hlist;
230
+ enum lsqpack_read_header_status rhs;
231
+ size = MIN(size, (uint32_t) (end - p));
232
+ rhs = lsqpack_dec_header_in(&decoder, NULL, stream_id,
233
+ size, &cur, size, &hlist, NULL, NULL);
234
+ (void) rhs;
235
+ }
236
+ break;
237
+ }
238
+
239
+ munmap(begin, st.st_size);
240
+ (void) close(fuzz_fd);
241
+
242
+ lsqpack_dec_cleanup(&decoder);
243
+
244
+ exit(0);
245
+ }
246
+
247
+ #endif