lsqpack 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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