From f2bbbe30e2205040da6e387fdc20c3debb001552 Mon Sep 17 00:00:00 2001 From: Sauyon Lee Date: Fri, 15 May 2020 07:32:51 -0700 Subject: [PATCH] Stub WebSocket dependencies --- .../semmle/go/dataflow/BarrierGuardUtil.qll | 10 +- .../Websocket/DialFunction.expected | 18 +- .../go/frameworks/Websocket/DialFunction.go | 6 + .../semmle/go/frameworks/Websocket/go.mod | 1 - .../vendor/github.com/gobwas/httphead/LICENSE | 21 - .../github.com/gobwas/httphead/README.md | 63 - .../github.com/gobwas/httphead/cookie.go | 200 --- .../vendor/github.com/gobwas/httphead/head.go | 275 ---- .../github.com/gobwas/httphead/httphead.go | 331 ----- .../github.com/gobwas/httphead/lexer.go | 360 ----- .../github.com/gobwas/httphead/octet.go | 83 -- .../github.com/gobwas/httphead/option.go | 187 --- .../github.com/gobwas/httphead/writer.go | 101 -- .../vendor/github.com/gobwas/pool/README.md | 107 -- .../vendor/github.com/gobwas/pool/generic.go | 87 -- .../gobwas/pool/internal/pmath/pmath.go | 65 - .../vendor/github.com/gobwas/pool/option.go | 43 - .../github.com/gobwas/pool/pbufio/pbufio.go | 106 -- .../gobwas/pool/pbufio/pbufio_go110.go | 13 - .../gobwas/pool/pbufio/pbufio_go19.go | 27 - .../vendor/github.com/gobwas/pool/pool.go | 25 - .../vendor/github.com/gobwas/ws/.gitignore | 5 - .../vendor/github.com/gobwas/ws/.travis.yml | 25 - .../vendor/github.com/gobwas/ws/Makefile | 47 - .../vendor/github.com/gobwas/ws/README.md | 360 ----- .../vendor/github.com/gobwas/ws/check.go | 145 -- .../vendor/github.com/gobwas/ws/cipher.go | 59 - .../vendor/github.com/gobwas/ws/dialer.go | 556 -------- .../github.com/gobwas/ws/dialer_tls_go17.go | 35 - .../github.com/gobwas/ws/dialer_tls_go18.go | 9 - .../vendor/github.com/gobwas/ws/doc.go | 81 -- .../vendor/github.com/gobwas/ws/errors.go | 54 - .../vendor/github.com/gobwas/ws/frame.go | 389 ------ .../vendor/github.com/gobwas/ws/http.go | 468 ------- .../vendor/github.com/gobwas/ws/nonce.go | 80 -- .../vendor/github.com/gobwas/ws/read.go | 147 -- .../vendor/github.com/gobwas/ws/server.go | 607 --------- .../vendor/github.com/gobwas/ws/server_test.s | 0 .../vendor/github.com/gobwas/ws/stub.go | 54 + .../vendor/github.com/gobwas/ws/util.go | 214 --- .../vendor/github.com/gobwas/ws/write.go | 104 -- .../github.com/gorilla/websocket/.gitignore | 25 - .../github.com/gorilla/websocket/AUTHORS | 9 - .../github.com/gorilla/websocket/README.md | 64 - .../github.com/gorilla/websocket/client.go | 395 ------ .../gorilla/websocket/client_clone.go | 16 - .../gorilla/websocket/client_clone_legacy.go | 38 - .../gorilla/websocket/compression.go | 148 -- .../github.com/gorilla/websocket/conn.go | 1201 ----------------- .../gorilla/websocket/conn_write.go | 15 - .../gorilla/websocket/conn_write_legacy.go | 18 - .../github.com/gorilla/websocket/doc.go | 227 ---- .../github.com/gorilla/websocket/go.mod | 3 - .../github.com/gorilla/websocket/join.go | 42 - .../github.com/gorilla/websocket/json.go | 60 - .../github.com/gorilla/websocket/mask.go | 54 - .../github.com/gorilla/websocket/mask_safe.go | 15 - .../github.com/gorilla/websocket/prepared.go | 102 -- .../github.com/gorilla/websocket/proxy.go | 77 -- .../github.com/gorilla/websocket/server.go | 363 ----- .../github.com/gorilla/websocket/stub.go | 135 ++ .../github.com/gorilla/websocket/trace.go | 19 - .../github.com/gorilla/websocket/trace_17.go | 12 - .../github.com/gorilla/websocket/util.go | 283 ---- .../gorilla/websocket/x_net_proxy.go | 473 ------- .../github.com/klauspost/compress/LICENSE | 28 - .../klauspost/compress/flate/deflate.go | 819 ----------- .../klauspost/compress/flate/dict_decoder.go | 184 --- .../klauspost/compress/flate/fast_encoder.go | 254 ---- .../klauspost/compress/flate/gen_inflate.go | 274 ---- .../compress/flate/huffman_bit_writer.go | 911 ------------- .../klauspost/compress/flate/huffman_code.go | 363 ----- .../compress/flate/huffman_sortByFreq.go | 178 --- .../compress/flate/huffman_sortByLiteral.go | 201 --- .../klauspost/compress/flate/inflate.go | 1000 -------------- .../klauspost/compress/flate/inflate_gen.go | 922 ------------- .../klauspost/compress/flate/level1.go | 179 --- .../klauspost/compress/flate/level2.go | 205 --- .../klauspost/compress/flate/level3.go | 229 ---- .../klauspost/compress/flate/level4.go | 212 --- .../klauspost/compress/flate/level5.go | 279 ---- .../klauspost/compress/flate/level6.go | 282 ---- .../klauspost/compress/flate/stateless.go | 297 ---- .../klauspost/compress/flate/token.go | 375 ----- .../github.com/sacOO7/go-logger/.gitignore | 12 - .../github.com/sacOO7/go-logger/LICENSE | 21 - .../github.com/sacOO7/go-logger/logging.go | 82 -- .../github.com/sacOO7/go-logger/loggingL.go | 13 - .../sacOO7/go-logger/logginglevel_string.go | 16 - .../github.com/sacOO7/gowebsocket/.gitignore | 21 - .../github.com/sacOO7/gowebsocket/README.md | 157 --- .../sacOO7/gowebsocket/gowebsocket.go | 186 --- .../github.com/sacOO7/gowebsocket/stub.go | 58 + .../github.com/sacOO7/gowebsocket/utils.go | 15 - .../Websocket/vendor/golang.org/x/net/AUTHORS | 3 - .../vendor/golang.org/x/net/CONTRIBUTORS | 3 - .../Websocket/vendor/golang.org/x/net/PATENTS | 22 - .../golang.org/x/net/{ => websocket}/LICENSE | 0 .../golang.org/x/net/websocket/client.go | 106 -- .../vendor/golang.org/x/net/websocket/dial.go | 24 - .../vendor/golang.org/x/net/websocket/hybi.go | 583 -------- .../golang.org/x/net/websocket/server.go | 113 -- .../vendor/golang.org/x/net/websocket/stub.go | 120 ++ .../golang.org/x/net/websocket/websocket.go | 451 ------- .../frameworks/Websocket/vendor/modules.txt | 17 +- .../vendor/nhooyr.io/websocket/.gitignore | 1 - .../vendor/nhooyr.io/websocket/.travis.yml | 40 - .../websocket/{LICENSE.txt => LICENSE} | 0 .../vendor/nhooyr.io/websocket/Makefile | 7 - .../vendor/nhooyr.io/websocket/README.md | 132 -- .../vendor/nhooyr.io/websocket/accept.go | 365 ----- .../vendor/nhooyr.io/websocket/accept_js.go | 20 - .../vendor/nhooyr.io/websocket/close.go | 76 -- .../vendor/nhooyr.io/websocket/close_notjs.go | 211 --- .../vendor/nhooyr.io/websocket/compress.go | 39 - .../nhooyr.io/websocket/compress_notjs.go | 181 --- .../vendor/nhooyr.io/websocket/conn.go | 13 - .../vendor/nhooyr.io/websocket/conn_notjs.go | 265 ---- .../vendor/nhooyr.io/websocket/dial.go | 287 ---- .../vendor/nhooyr.io/websocket/doc.go | 32 - .../vendor/nhooyr.io/websocket/frame.go | 294 ---- .../vendor/nhooyr.io/websocket/go.mod | 14 - .../websocket/internal/bpool/bpool.go | 24 - .../nhooyr.io/websocket/internal/errd/wrap.go | 14 - .../websocket/internal/wsjs/wsjs_js.go | 170 --- .../nhooyr.io/websocket/internal/xsync/go.go | 25 - .../websocket/internal/xsync/int64.go | 23 - .../vendor/nhooyr.io/websocket/netconn.go | 166 --- .../vendor/nhooyr.io/websocket/read.go | 471 ------- .../vendor/nhooyr.io/websocket/stringer.go | 91 -- .../vendor/nhooyr.io/websocket/stub.go | 76 ++ .../vendor/nhooyr.io/websocket/write.go | 386 ------ .../vendor/nhooyr.io/websocket/ws_js.go | 379 ------ .../Security/CWE-918/RequestForgery.expected | 70 +- ql/test/query-tests/Security/CWE-918/go.mod | 1 - ql/test/query-tests/Security/CWE-918/main | Bin 0 -> 6935277 bytes .../vendor/github.com/gobwas/httphead/LICENSE | 21 - .../github.com/gobwas/httphead/README.md | 63 - .../github.com/gobwas/httphead/cookie.go | 200 --- .../vendor/github.com/gobwas/httphead/head.go | 275 ---- .../github.com/gobwas/httphead/httphead.go | 331 ----- .../github.com/gobwas/httphead/lexer.go | 360 ----- .../github.com/gobwas/httphead/octet.go | 83 -- .../github.com/gobwas/httphead/option.go | 187 --- .../github.com/gobwas/httphead/writer.go | 101 -- .../vendor/github.com/gobwas/pool/README.md | 107 -- .../vendor/github.com/gobwas/pool/generic.go | 87 -- .../gobwas/pool/internal/pmath/pmath.go | 65 - .../vendor/github.com/gobwas/pool/option.go | 43 - .../github.com/gobwas/pool/pbufio/pbufio.go | 106 -- .../gobwas/pool/pbufio/pbufio_go110.go | 13 - .../gobwas/pool/pbufio/pbufio_go19.go | 27 - .../vendor/github.com/gobwas/pool/pool.go | 25 - .../vendor/github.com/gobwas/ws/.gitignore | 5 - .../vendor/github.com/gobwas/ws/.travis.yml | 25 - .../vendor/github.com/gobwas/ws/Makefile | 47 - .../vendor/github.com/gobwas/ws/README.md | 360 ----- .../vendor/github.com/gobwas/ws/check.go | 145 -- .../vendor/github.com/gobwas/ws/cipher.go | 59 - .../vendor/github.com/gobwas/ws/dialer.go | 556 -------- .../github.com/gobwas/ws/dialer_tls_go17.go | 35 - .../github.com/gobwas/ws/dialer_tls_go18.go | 9 - .../vendor/github.com/gobwas/ws/doc.go | 81 -- .../vendor/github.com/gobwas/ws/errors.go | 54 - .../vendor/github.com/gobwas/ws/frame.go | 389 ------ .../vendor/github.com/gobwas/ws/http.go | 468 ------- .../vendor/github.com/gobwas/ws/nonce.go | 80 -- .../vendor/github.com/gobwas/ws/read.go | 147 -- .../vendor/github.com/gobwas/ws/server.go | 607 --------- .../vendor/github.com/gobwas/ws/server_test.s | 0 .../vendor/github.com/gobwas/ws/stub.go | 54 + .../vendor/github.com/gobwas/ws/util.go | 214 --- .../vendor/github.com/gobwas/ws/write.go | 104 -- .../github.com/gorilla/websocket/.gitignore | 25 - .../github.com/gorilla/websocket/AUTHORS | 9 - .../github.com/gorilla/websocket/README.md | 64 - .../github.com/gorilla/websocket/client.go | 395 ------ .../gorilla/websocket/client_clone.go | 16 - .../gorilla/websocket/client_clone_legacy.go | 38 - .../gorilla/websocket/compression.go | 148 -- .../github.com/gorilla/websocket/conn.go | 1201 ----------------- .../gorilla/websocket/conn_write.go | 15 - .../gorilla/websocket/conn_write_legacy.go | 18 - .../github.com/gorilla/websocket/doc.go | 227 ---- .../github.com/gorilla/websocket/go.mod | 3 - .../github.com/gorilla/websocket/join.go | 42 - .../github.com/gorilla/websocket/json.go | 60 - .../github.com/gorilla/websocket/mask.go | 54 - .../github.com/gorilla/websocket/mask_safe.go | 15 - .../github.com/gorilla/websocket/prepared.go | 102 -- .../github.com/gorilla/websocket/proxy.go | 77 -- .../github.com/gorilla/websocket/server.go | 363 ----- .../github.com/gorilla/websocket/stub.go | 135 ++ .../github.com/gorilla/websocket/trace.go | 19 - .../github.com/gorilla/websocket/trace_17.go | 12 - .../github.com/gorilla/websocket/util.go | 283 ---- .../gorilla/websocket/x_net_proxy.go | 473 ------- .../github.com/klauspost/compress/LICENSE | 28 - .../klauspost/compress/flate/deflate.go | 819 ----------- .../klauspost/compress/flate/dict_decoder.go | 184 --- .../klauspost/compress/flate/fast_encoder.go | 254 ---- .../klauspost/compress/flate/gen_inflate.go | 274 ---- .../compress/flate/huffman_bit_writer.go | 911 ------------- .../klauspost/compress/flate/huffman_code.go | 363 ----- .../compress/flate/huffman_sortByFreq.go | 178 --- .../compress/flate/huffman_sortByLiteral.go | 201 --- .../klauspost/compress/flate/inflate.go | 1000 -------------- .../klauspost/compress/flate/inflate_gen.go | 922 ------------- .../klauspost/compress/flate/level1.go | 179 --- .../klauspost/compress/flate/level2.go | 205 --- .../klauspost/compress/flate/level3.go | 229 ---- .../klauspost/compress/flate/level4.go | 212 --- .../klauspost/compress/flate/level5.go | 279 ---- .../klauspost/compress/flate/level6.go | 282 ---- .../klauspost/compress/flate/stateless.go | 297 ---- .../klauspost/compress/flate/token.go | 375 ----- .../github.com/sacOO7/go-logger/.gitignore | 12 - .../github.com/sacOO7/go-logger/LICENSE | 21 - .../github.com/sacOO7/go-logger/logging.go | 82 -- .../github.com/sacOO7/go-logger/loggingL.go | 13 - .../sacOO7/go-logger/logginglevel_string.go | 16 - .../github.com/sacOO7/gowebsocket/.gitignore | 21 - .../github.com/sacOO7/gowebsocket/README.md | 157 --- .../sacOO7/gowebsocket/gowebsocket.go | 186 --- .../github.com/sacOO7/gowebsocket/stub.go | 58 + .../github.com/sacOO7/gowebsocket/utils.go | 15 - .../CWE-918/vendor/golang.org/x/net/AUTHORS | 3 - .../vendor/golang.org/x/net/CONTRIBUTORS | 3 - .../CWE-918/vendor/golang.org/x/net/PATENTS | 22 - .../golang.org/x/net/{ => websocket}/LICENSE | 0 .../golang.org/x/net/websocket/client.go | 106 -- .../vendor/golang.org/x/net/websocket/dial.go | 24 - .../vendor/golang.org/x/net/websocket/hybi.go | 583 -------- .../golang.org/x/net/websocket/server.go | 113 -- .../vendor/golang.org/x/net/websocket/stub.go | 120 ++ .../golang.org/x/net/websocket/websocket.go | 451 ------- .../Security/CWE-918/vendor/modules.txt | 17 +- .../vendor/nhooyr.io/websocket/.gitignore | 1 - .../vendor/nhooyr.io/websocket/.travis.yml | 40 - .../websocket/{LICENSE.txt => LICENSE} | 0 .../vendor/nhooyr.io/websocket/Makefile | 7 - .../vendor/nhooyr.io/websocket/README.md | 132 -- .../vendor/nhooyr.io/websocket/accept.go | 365 ----- .../vendor/nhooyr.io/websocket/accept_js.go | 20 - .../vendor/nhooyr.io/websocket/close.go | 76 -- .../vendor/nhooyr.io/websocket/close_notjs.go | 211 --- .../vendor/nhooyr.io/websocket/compress.go | 39 - .../nhooyr.io/websocket/compress_notjs.go | 181 --- .../vendor/nhooyr.io/websocket/conn.go | 13 - .../vendor/nhooyr.io/websocket/conn_notjs.go | 265 ---- .../vendor/nhooyr.io/websocket/dial.go | 287 ---- .../CWE-918/vendor/nhooyr.io/websocket/doc.go | 32 - .../vendor/nhooyr.io/websocket/frame.go | 294 ---- .../CWE-918/vendor/nhooyr.io/websocket/go.mod | 14 - .../websocket/internal/bpool/bpool.go | 24 - .../nhooyr.io/websocket/internal/errd/wrap.go | 14 - .../websocket/internal/wsjs/wsjs_js.go | 170 --- .../nhooyr.io/websocket/internal/xsync/go.go | 25 - .../websocket/internal/xsync/int64.go | 23 - .../vendor/nhooyr.io/websocket/netconn.go | 166 --- .../vendor/nhooyr.io/websocket/read.go | 471 ------- .../vendor/nhooyr.io/websocket/stringer.go | 91 -- .../vendor/nhooyr.io/websocket/stub.go | 76 ++ .../vendor/nhooyr.io/websocket/write.go | 386 ------ .../vendor/nhooyr.io/websocket/ws_js.go | 379 ------ .../query-tests/Security/CWE-918/websocket.go | 8 +- 266 files changed, 950 insertions(+), 43852 deletions(-) delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/LICENSE delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/README.md delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/cookie.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/head.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/httphead.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/lexer.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/octet.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/option.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/writer.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/README.md delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/generic.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/internal/pmath/pmath.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/option.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/pbufio/pbufio.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/pbufio/pbufio_go110.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/pbufio/pbufio_go19.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/pool.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/.gitignore delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/.travis.yml delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/Makefile delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/README.md delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/check.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/cipher.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/dialer.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/dialer_tls_go17.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/dialer_tls_go18.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/doc.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/errors.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/frame.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/http.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/nonce.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/read.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/server.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/server_test.s create mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/stub.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/util.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/write.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/.gitignore delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/AUTHORS delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/README.md delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/client.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/client_clone.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/client_clone_legacy.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/compression.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/conn.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/conn_write.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/conn_write_legacy.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/doc.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/go.mod delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/join.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/json.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/mask.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/mask_safe.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/prepared.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/proxy.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/server.go create mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/stub.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/trace.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/trace_17.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/util.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/x_net_proxy.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/LICENSE delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/deflate.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/dict_decoder.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/fast_encoder.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/gen_inflate.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/huffman_bit_writer.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/huffman_code.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/huffman_sortByFreq.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/huffman_sortByLiteral.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/inflate.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/inflate_gen.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/level1.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/level2.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/level3.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/level4.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/level5.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/level6.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/stateless.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/token.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/go-logger/.gitignore delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/go-logger/LICENSE delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/go-logger/logging.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/go-logger/loggingL.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/go-logger/logginglevel_string.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/gowebsocket/.gitignore delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/gowebsocket/README.md delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/gowebsocket/gowebsocket.go create mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/gowebsocket/stub.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/gowebsocket/utils.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/AUTHORS delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/CONTRIBUTORS delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/PATENTS rename ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/{ => websocket}/LICENSE (100%) delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/client.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/dial.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/hybi.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/server.go create mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/stub.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/websocket.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/.gitignore delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/.travis.yml rename ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/{LICENSE.txt => LICENSE} (100%) delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/Makefile delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/README.md delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/accept.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/accept_js.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/close.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/close_notjs.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/compress.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/compress_notjs.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/conn.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/conn_notjs.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/dial.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/doc.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/frame.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/go.mod delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/internal/bpool/bpool.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/internal/errd/wrap.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/internal/wsjs/wsjs_js.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/internal/xsync/go.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/internal/xsync/int64.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/netconn.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/read.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/stringer.go create mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/stub.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/write.go delete mode 100644 ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/ws_js.go create mode 100755 ql/test/query-tests/Security/CWE-918/main delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/httphead/LICENSE delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/httphead/README.md delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/httphead/cookie.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/httphead/head.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/httphead/httphead.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/httphead/lexer.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/httphead/octet.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/httphead/option.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/httphead/writer.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/pool/README.md delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/pool/generic.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/pool/internal/pmath/pmath.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/pool/option.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/pool/pbufio/pbufio.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/pool/pbufio/pbufio_go110.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/pool/pbufio/pbufio_go19.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/pool/pool.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/ws/.gitignore delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/ws/.travis.yml delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/ws/Makefile delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/ws/README.md delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/ws/check.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/ws/cipher.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/ws/dialer.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/ws/dialer_tls_go17.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/ws/dialer_tls_go18.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/ws/doc.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/ws/errors.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/ws/frame.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/ws/http.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/ws/nonce.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/ws/read.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/ws/server.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/ws/server_test.s create mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/ws/stub.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/ws/util.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gobwas/ws/write.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/.gitignore delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/AUTHORS delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/README.md delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/client.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/client_clone.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/client_clone_legacy.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/compression.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/conn.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/conn_write.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/conn_write_legacy.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/doc.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/go.mod delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/join.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/json.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/mask.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/mask_safe.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/prepared.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/proxy.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/server.go create mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/stub.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/trace.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/trace_17.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/util.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/gorilla/websocket/x_net_proxy.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/klauspost/compress/LICENSE delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/klauspost/compress/flate/deflate.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/klauspost/compress/flate/dict_decoder.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/klauspost/compress/flate/fast_encoder.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/klauspost/compress/flate/gen_inflate.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/klauspost/compress/flate/huffman_bit_writer.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/klauspost/compress/flate/huffman_code.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/klauspost/compress/flate/huffman_sortByFreq.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/klauspost/compress/flate/huffman_sortByLiteral.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/klauspost/compress/flate/inflate.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/klauspost/compress/flate/inflate_gen.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/klauspost/compress/flate/level1.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/klauspost/compress/flate/level2.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/klauspost/compress/flate/level3.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/klauspost/compress/flate/level4.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/klauspost/compress/flate/level5.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/klauspost/compress/flate/level6.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/klauspost/compress/flate/stateless.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/klauspost/compress/flate/token.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/sacOO7/go-logger/.gitignore delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/sacOO7/go-logger/LICENSE delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/sacOO7/go-logger/logging.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/sacOO7/go-logger/loggingL.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/sacOO7/go-logger/logginglevel_string.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/sacOO7/gowebsocket/.gitignore delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/sacOO7/gowebsocket/README.md delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/sacOO7/gowebsocket/gowebsocket.go create mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/sacOO7/gowebsocket/stub.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/github.com/sacOO7/gowebsocket/utils.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/golang.org/x/net/AUTHORS delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/golang.org/x/net/CONTRIBUTORS delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/golang.org/x/net/PATENTS rename ql/test/query-tests/Security/CWE-918/vendor/golang.org/x/net/{ => websocket}/LICENSE (100%) delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/golang.org/x/net/websocket/client.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/golang.org/x/net/websocket/dial.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/golang.org/x/net/websocket/hybi.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/golang.org/x/net/websocket/server.go create mode 100644 ql/test/query-tests/Security/CWE-918/vendor/golang.org/x/net/websocket/stub.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/golang.org/x/net/websocket/websocket.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/.gitignore delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/.travis.yml rename ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/{LICENSE.txt => LICENSE} (100%) delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/Makefile delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/README.md delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/accept.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/accept_js.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/close.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/close_notjs.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/compress.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/compress_notjs.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/conn.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/conn_notjs.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/dial.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/doc.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/frame.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/go.mod delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/internal/bpool/bpool.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/internal/errd/wrap.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/internal/wsjs/wsjs_js.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/internal/xsync/go.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/internal/xsync/int64.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/netconn.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/read.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/stringer.go create mode 100644 ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/stub.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/write.go delete mode 100644 ql/test/query-tests/Security/CWE-918/vendor/nhooyr.io/websocket/ws_js.go diff --git a/ql/src/semmle/go/dataflow/BarrierGuardUtil.qll b/ql/src/semmle/go/dataflow/BarrierGuardUtil.qll index c94307dd1ae..0dfbb5dc046 100644 --- a/ql/src/semmle/go/dataflow/BarrierGuardUtil.qll +++ b/ql/src/semmle/go/dataflow/BarrierGuardUtil.qll @@ -25,7 +25,7 @@ class RedirectCheckBarrierGuard extends DataFlow::BarrierGuard, DataFlow::CallNo * An equality check comparing a data-flow node against a constant string, considered as * a barrier guard for sanitizing untrusted URLs. * - * Additionally, a check comparing `url.Hostname()` against a constant string is also + * Additionally, a check comparing `url.Hostname()` against a constant string is also * considered a barrier guard for `url`. */ class UrlCheck extends DataFlow::BarrierGuard, DataFlow::EqualityTestNode { @@ -40,11 +40,11 @@ class UrlCheck extends DataFlow::BarrierGuard, DataFlow::EqualityTestNode { mc.getTarget().getName() = "Hostname" and url = mc.getReceiver() ) - } + ) + } - override predicate checks(Expr e, boolean outcome) { - e = url.asExpr() and outcome = this.getPolarity() - } + override predicate checks(Expr e, boolean outcome) { + e = url.asExpr() and outcome = this.getPolarity() } } diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/DialFunction.expected b/ql/test/library-tests/semmle/go/frameworks/Websocket/DialFunction.expected index 80e2b9058de..e714b20e5d6 100644 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/DialFunction.expected +++ b/ql/test/library-tests/semmle/go/frameworks/Websocket/DialFunction.expected @@ -1,9 +1,9 @@ -| DialFunction.go:19:11:19:52 | call to Dial | DialFunction.go:19:26:19:39 | untrustedInput | -| DialFunction.go:22:12:22:39 | call to DialConfig | DialFunction.go:21:35:21:48 | untrustedInput | -| DialFunction.go:24:2:24:49 | call to Dial | DialFunction.go:24:30:24:43 | untrustedInput | -| DialFunction.go:27:2:27:38 | call to Dial | DialFunction.go:27:14:27:27 | untrustedInput | -| DialFunction.go:29:2:29:61 | call to DialContext | DialFunction.go:29:37:29:50 | untrustedInput | -| DialFunction.go:31:2:31:44 | call to Dial | DialFunction.go:31:30:31:43 | untrustedInput | -| DialFunction.go:34:2:34:45 | call to Dial | DialFunction.go:34:31:34:44 | untrustedInput | -| DialFunction.go:36:2:36:31 | call to BuildProxy | DialFunction.go:36:17:36:30 | untrustedInput | -| DialFunction.go:37:2:37:24 | call to New | DialFunction.go:37:10:37:23 | untrustedInput | +| DialFunction.go:25:11:25:52 | call to Dial | DialFunction.go:25:26:25:39 | untrustedInput | +| DialFunction.go:28:12:28:39 | call to DialConfig | DialFunction.go:27:35:27:48 | untrustedInput | +| DialFunction.go:30:2:30:49 | call to Dial | DialFunction.go:30:30:30:43 | untrustedInput | +| DialFunction.go:33:2:33:38 | call to Dial | DialFunction.go:33:14:33:27 | untrustedInput | +| DialFunction.go:35:2:35:61 | call to DialContext | DialFunction.go:35:37:35:50 | untrustedInput | +| DialFunction.go:37:2:37:44 | call to Dial | DialFunction.go:37:30:37:43 | untrustedInput | +| DialFunction.go:40:2:40:45 | call to Dial | DialFunction.go:40:31:40:44 | untrustedInput | +| DialFunction.go:42:2:42:31 | call to BuildProxy | DialFunction.go:42:17:42:30 | untrustedInput | +| DialFunction.go:43:2:43:24 | call to New | DialFunction.go:43:10:43:23 | untrustedInput | diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/DialFunction.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/DialFunction.go index ed59e3a82cd..520bd08f945 100644 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/DialFunction.go +++ b/ql/test/library-tests/semmle/go/frameworks/Websocket/DialFunction.go @@ -1,5 +1,11 @@ package main +//go:generate depstubber -vendor github.com/gobwas/ws Dialer Dial +//go:generate depstubber -vendor github.com/gorilla/websocket Dialer +//go:generate depstubber -vendor github.com/sacOO7/gowebsocket "" New,BuildProxy +//go:generate depstubber -vendor golang.org/x/net/websocket "" Dial,NewConfig,DialConfig +//go:generate depstubber -vendor nhooyr.io/websocket "" Dial + import ( "context" diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/go.mod b/ql/test/library-tests/semmle/go/frameworks/Websocket/go.mod index 5f614a3d1d3..ce6c493a190 100644 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/go.mod +++ b/ql/test/library-tests/semmle/go/frameworks/Websocket/go.mod @@ -5,7 +5,6 @@ go 1.14 require ( github.com/gobwas/ws v1.0.3 github.com/gorilla/websocket v1.4.2 - github.com/sacOO7/go-logger v0.0.0-20180719173527-9ac9add5a50d // indirect github.com/sacOO7/gowebsocket v0.0.0-20180719182212-1436bb906a4e golang.org/x/net v0.0.0-20200421231249-e086a090c8fd nhooyr.io/websocket v1.8.5 diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/LICENSE b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/LICENSE deleted file mode 100644 index 274431766fa..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 Sergey Kamardin - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/README.md b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/README.md deleted file mode 100644 index 67a97fdbe92..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/README.md +++ /dev/null @@ -1,63 +0,0 @@ -# httphead.[go](https://golang.org) - -[![GoDoc][godoc-image]][godoc-url] - -> Tiny HTTP header value parsing library in go. - -## Overview - -This library contains low-level functions for scanning HTTP RFC2616 compatible header value grammars. - -## Install - -```shell - go get github.com/gobwas/httphead -``` - -## Example - -The example below shows how multiple-choise HTTP header value could be parsed with this library: - -```go - options, ok := httphead.ParseOptions([]byte(`foo;bar=1,baz`), nil) - fmt.Println(options, ok) - // Output: [{foo map[bar:1]} {baz map[]}] true -``` - -The low-level example below shows how to optimize keys skipping and selection -of some key: - -```go - // The right part of full header line like: - // X-My-Header: key;foo=bar;baz,key;baz - header := []byte(`foo;a=0,foo;a=1,foo;a=2,foo;a=3`) - - // We want to search key "foo" with an "a" parameter that equal to "2". - var ( - foo = []byte(`foo`) - a = []byte(`a`) - v = []byte(`2`) - ) - var found bool - httphead.ScanOptions(header, func(i int, key, param, value []byte) Control { - if !bytes.Equal(key, foo) { - return ControlSkip - } - if !bytes.Equal(param, a) { - if bytes.Equal(value, v) { - // Found it! - found = true - return ControlBreak - } - return ControlSkip - } - return ControlContinue - }) -``` - -For more usage examples please see [docs][godoc-url] or package tests. - -[godoc-image]: https://godoc.org/github.com/gobwas/httphead?status.svg -[godoc-url]: https://godoc.org/github.com/gobwas/httphead -[travis-image]: https://travis-ci.org/gobwas/httphead.svg?branch=master -[travis-url]: https://travis-ci.org/gobwas/httphead diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/cookie.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/cookie.go deleted file mode 100644 index 05c9a1fb6a1..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/cookie.go +++ /dev/null @@ -1,200 +0,0 @@ -package httphead - -import ( - "bytes" -) - -// ScanCookie scans cookie pairs from data using DefaultCookieScanner.Scan() -// method. -func ScanCookie(data []byte, it func(key, value []byte) bool) bool { - return DefaultCookieScanner.Scan(data, it) -} - -// DefaultCookieScanner is a CookieScanner which is used by ScanCookie(). -// Note that it is intended to have the same behavior as http.Request.Cookies() -// has. -var DefaultCookieScanner = CookieScanner{} - -// CookieScanner contains options for scanning cookie pairs. -// See https://tools.ietf.org/html/rfc6265#section-4.1.1 -type CookieScanner struct { - // DisableNameValidation disables name validation of a cookie. If false, - // only RFC2616 "tokens" are accepted. - DisableNameValidation bool - - // DisableValueValidation disables value validation of a cookie. If false, - // only RFC6265 "cookie-octet" characters are accepted. - // - // Note that Strict option also affects validation of a value. - // - // If Strict is false, then scanner begins to allow space and comma - // characters inside the value for better compatibility with non standard - // cookies implementations. - DisableValueValidation bool - - // BreakOnPairError sets scanner to immediately return after first pair syntax - // validation error. - // If false, scanner will try to skip invalid pair bytes and go ahead. - BreakOnPairError bool - - // Strict enables strict RFC6265 mode scanning. It affects name and value - // validation, as also some other rules. - // If false, it is intended to bring the same behavior as - // http.Request.Cookies(). - Strict bool -} - -// Scan maps data to name and value pairs. Usually data represents value of the -// Cookie header. -func (c CookieScanner) Scan(data []byte, it func(name, value []byte) bool) bool { - lexer := &Scanner{data: data} - - const ( - statePair = iota - stateBefore - ) - - state := statePair - - for lexer.Buffered() > 0 { - switch state { - case stateBefore: - // Pairs separated by ";" and space, according to the RFC6265: - // cookie-pair *( ";" SP cookie-pair ) - // - // Cookie pairs MUST be separated by (";" SP). So our only option - // here is to fail as syntax error. - a, b := lexer.Peek2() - if a != ';' { - return false - } - - state = statePair - - advance := 1 - if b == ' ' { - advance++ - } else if c.Strict { - return false - } - - lexer.Advance(advance) - - case statePair: - if !lexer.FetchUntil(';') { - return false - } - - var value []byte - name := lexer.Bytes() - if i := bytes.IndexByte(name, '='); i != -1 { - value = name[i+1:] - name = name[:i] - } else if c.Strict { - if !c.BreakOnPairError { - goto nextPair - } - return false - } - - if !c.Strict { - trimLeft(name) - } - if !c.DisableNameValidation && !ValidCookieName(name) { - if !c.BreakOnPairError { - goto nextPair - } - return false - } - - if !c.Strict { - value = trimRight(value) - } - value = stripQuotes(value) - if !c.DisableValueValidation && !ValidCookieValue(value, c.Strict) { - if !c.BreakOnPairError { - goto nextPair - } - return false - } - - if !it(name, value) { - return true - } - - nextPair: - state = stateBefore - } - } - - return true -} - -// ValidCookieValue reports whether given value is a valid RFC6265 -// "cookie-octet" bytes. -// -// cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E -// ; US-ASCII characters excluding CTLs, -// ; whitespace DQUOTE, comma, semicolon, -// ; and backslash -// -// Note that the false strict parameter disables errors on space 0x20 and comma -// 0x2c. This could be useful to bring some compatibility with non-compliant -// clients/servers in the real world. -// It acts the same as standard library cookie parser if strict is false. -func ValidCookieValue(value []byte, strict bool) bool { - if len(value) == 0 { - return true - } - for _, c := range value { - switch c { - case '"', ';', '\\': - return false - case ',', ' ': - if strict { - return false - } - default: - if c <= 0x20 { - return false - } - if c >= 0x7f { - return false - } - } - } - return true -} - -// ValidCookieName reports wheter given bytes is a valid RFC2616 "token" bytes. -func ValidCookieName(name []byte) bool { - for _, c := range name { - if !OctetTypes[c].IsToken() { - return false - } - } - return true -} - -func stripQuotes(bts []byte) []byte { - if last := len(bts) - 1; last > 0 && bts[0] == '"' && bts[last] == '"' { - return bts[1:last] - } - return bts -} - -func trimLeft(p []byte) []byte { - var i int - for i < len(p) && OctetTypes[p[i]].IsSpace() { - i++ - } - return p[i:] -} - -func trimRight(p []byte) []byte { - j := len(p) - for j > 0 && OctetTypes[p[j-1]].IsSpace() { - j-- - } - return p[:j] -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/head.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/head.go deleted file mode 100644 index a50e907dd18..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/head.go +++ /dev/null @@ -1,275 +0,0 @@ -package httphead - -import ( - "bufio" - "bytes" -) - -// Version contains protocol major and minor version. -type Version struct { - Major int - Minor int -} - -// RequestLine contains parameters parsed from the first request line. -type RequestLine struct { - Method []byte - URI []byte - Version Version -} - -// ResponseLine contains parameters parsed from the first response line. -type ResponseLine struct { - Version Version - Status int - Reason []byte -} - -// SplitRequestLine splits given slice of bytes into three chunks without -// parsing. -func SplitRequestLine(line []byte) (method, uri, version []byte) { - return split3(line, ' ') -} - -// ParseRequestLine parses http request line like "GET / HTTP/1.0". -func ParseRequestLine(line []byte) (r RequestLine, ok bool) { - var i int - for i = 0; i < len(line); i++ { - c := line[i] - if !OctetTypes[c].IsToken() { - if i > 0 && c == ' ' { - break - } - return - } - } - if i == len(line) { - return - } - - var proto []byte - r.Method = line[:i] - r.URI, proto = split2(line[i+1:], ' ') - if len(r.URI) == 0 { - return - } - if major, minor, ok := ParseVersion(proto); ok { - r.Version.Major = major - r.Version.Minor = minor - return r, true - } - - return r, false -} - -// SplitResponseLine splits given slice of bytes into three chunks without -// parsing. -func SplitResponseLine(line []byte) (version, status, reason []byte) { - return split3(line, ' ') -} - -// ParseResponseLine parses first response line into ResponseLine struct. -func ParseResponseLine(line []byte) (r ResponseLine, ok bool) { - var ( - proto []byte - status []byte - ) - proto, status, r.Reason = split3(line, ' ') - if major, minor, ok := ParseVersion(proto); ok { - r.Version.Major = major - r.Version.Minor = minor - } else { - return r, false - } - if n, ok := IntFromASCII(status); ok { - r.Status = n - } else { - return r, false - } - // TODO(gobwas): parse here r.Reason fot TEXT rule: - // TEXT = - return r, true -} - -var ( - httpVersion10 = []byte("HTTP/1.0") - httpVersion11 = []byte("HTTP/1.1") - httpVersionPrefix = []byte("HTTP/") -) - -// ParseVersion parses major and minor version of HTTP protocol. -// It returns parsed values and true if parse is ok. -func ParseVersion(bts []byte) (major, minor int, ok bool) { - switch { - case bytes.Equal(bts, httpVersion11): - return 1, 1, true - case bytes.Equal(bts, httpVersion10): - return 1, 0, true - case len(bts) < 8: - return - case !bytes.Equal(bts[:5], httpVersionPrefix): - return - } - - bts = bts[5:] - - dot := bytes.IndexByte(bts, '.') - if dot == -1 { - return - } - major, ok = IntFromASCII(bts[:dot]) - if !ok { - return - } - minor, ok = IntFromASCII(bts[dot+1:]) - if !ok { - return - } - - return major, minor, true -} - -// ReadLine reads line from br. It reads until '\n' and returns bytes without -// '\n' or '\r\n' at the end. -// It returns err if and only if line does not end in '\n'. Note that read -// bytes returned in any case of error. -// -// It is much like the textproto/Reader.ReadLine() except the thing that it -// returns raw bytes, instead of string. That is, it avoids copying bytes read -// from br. -// -// textproto/Reader.ReadLineBytes() is also makes copy of resulting bytes to be -// safe with future I/O operations on br. -// -// We could control I/O operations on br and do not need to make additional -// copy for safety. -func ReadLine(br *bufio.Reader) ([]byte, error) { - var line []byte - for { - bts, err := br.ReadSlice('\n') - if err == bufio.ErrBufferFull { - // Copy bytes because next read will discard them. - line = append(line, bts...) - continue - } - // Avoid copy of single read. - if line == nil { - line = bts - } else { - line = append(line, bts...) - } - if err != nil { - return line, err - } - // Size of line is at least 1. - // In other case bufio.ReadSlice() returns error. - n := len(line) - // Cut '\n' or '\r\n'. - if n > 1 && line[n-2] == '\r' { - line = line[:n-2] - } else { - line = line[:n-1] - } - return line, nil - } -} - -// ParseHeaderLine parses HTTP header as key-value pair. It returns parsed -// values and true if parse is ok. -func ParseHeaderLine(line []byte) (k, v []byte, ok bool) { - colon := bytes.IndexByte(line, ':') - if colon == -1 { - return - } - k = trim(line[:colon]) - for _, c := range k { - if !OctetTypes[c].IsToken() { - return nil, nil, false - } - } - v = trim(line[colon+1:]) - return k, v, true -} - -// IntFromASCII converts ascii encoded decimal numeric value from HTTP entities -// to an integer. -func IntFromASCII(bts []byte) (ret int, ok bool) { - // ASCII numbers all start with the high-order bits 0011. - // If you see that, and the next bits are 0-9 (0000 - 1001) you can grab those - // bits and interpret them directly as an integer. - var n int - if n = len(bts); n < 1 { - return 0, false - } - for i := 0; i < n; i++ { - if bts[i]&0xf0 != 0x30 { - return 0, false - } - ret += int(bts[i]&0xf) * pow(10, n-i-1) - } - return ret, true -} - -const ( - toLower = 'a' - 'A' // for use with OR. - toUpper = ^byte(toLower) // for use with AND. -) - -// CanonicalizeHeaderKey is like standard textproto/CanonicalMIMEHeaderKey, -// except that it operates with slice of bytes and modifies it inplace without -// copying. -func CanonicalizeHeaderKey(k []byte) { - upper := true - for i, c := range k { - if upper && 'a' <= c && c <= 'z' { - k[i] &= toUpper - } else if !upper && 'A' <= c && c <= 'Z' { - k[i] |= toLower - } - upper = c == '-' - } -} - -// pow for integers implementation. -// See Donald Knuth, The Art of Computer Programming, Volume 2, Section 4.6.3 -func pow(a, b int) int { - p := 1 - for b > 0 { - if b&1 != 0 { - p *= a - } - b >>= 1 - a *= a - } - return p -} - -func split3(p []byte, sep byte) (p1, p2, p3 []byte) { - a := bytes.IndexByte(p, sep) - b := bytes.IndexByte(p[a+1:], sep) - if a == -1 || b == -1 { - return p, nil, nil - } - b += a + 1 - return p[:a], p[a+1 : b], p[b+1:] -} - -func split2(p []byte, sep byte) (p1, p2 []byte) { - i := bytes.IndexByte(p, sep) - if i == -1 { - return p, nil - } - return p[:i], p[i+1:] -} - -func trim(p []byte) []byte { - var i, j int - for i = 0; i < len(p) && (p[i] == ' ' || p[i] == '\t'); { - i++ - } - for j = len(p); j > i && (p[j-1] == ' ' || p[j-1] == '\t'); { - j-- - } - return p[i:j] -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/httphead.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/httphead.go deleted file mode 100644 index 2387e8033c9..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/httphead.go +++ /dev/null @@ -1,331 +0,0 @@ -// Package httphead contains utils for parsing HTTP and HTTP-grammar compatible -// text protocols headers. -// -// That is, this package first aim is to bring ability to easily parse -// constructions, described here https://tools.ietf.org/html/rfc2616#section-2 -package httphead - -import ( - "bytes" - "strings" -) - -// ScanTokens parses data in this form: -// -// list = 1#token -// -// It returns false if data is malformed. -func ScanTokens(data []byte, it func([]byte) bool) bool { - lexer := &Scanner{data: data} - - var ok bool - for lexer.Next() { - switch lexer.Type() { - case ItemToken: - ok = true - if !it(lexer.Bytes()) { - return true - } - case ItemSeparator: - if !isComma(lexer.Bytes()) { - return false - } - default: - return false - } - } - - return ok && !lexer.err -} - -// ParseOptions parses all header options and appends it to given slice of -// Option. It returns flag of successful (wellformed input) parsing. -// -// Note that appended options are all consist of subslices of data. That is, -// mutation of data will mutate appended options. -func ParseOptions(data []byte, options []Option) ([]Option, bool) { - var i int - index := -1 - return options, ScanOptions(data, func(idx int, name, attr, val []byte) Control { - if idx != index { - index = idx - i = len(options) - options = append(options, Option{Name: name}) - } - if attr != nil { - options[i].Parameters.Set(attr, val) - } - return ControlContinue - }) -} - -// SelectFlag encodes way of options selection. -type SelectFlag byte - -// String represetns flag as string. -func (f SelectFlag) String() string { - var flags [2]string - var n int - if f&SelectCopy != 0 { - flags[n] = "copy" - n++ - } - if f&SelectUnique != 0 { - flags[n] = "unique" - n++ - } - return "[" + strings.Join(flags[:n], "|") + "]" -} - -const ( - // SelectCopy causes selector to copy selected option before appending it - // to resulting slice. - // If SelectCopy flag is not passed to selector, then appended options will - // contain sub-slices of the initial data. - SelectCopy SelectFlag = 1 << iota - - // SelectUnique causes selector to append only not yet existing option to - // resulting slice. Unique is checked by comparing option names. - SelectUnique -) - -// OptionSelector contains configuration for selecting Options from header value. -type OptionSelector struct { - // Check is a filter function that applied to every Option that possibly - // could be selected. - // If Check is nil all options will be selected. - Check func(Option) bool - - // Flags contains flags for options selection. - Flags SelectFlag - - // Alloc used to allocate slice of bytes when selector is configured with - // SelectCopy flag. It will be called with number of bytes needed for copy - // of single Option. - // If Alloc is nil make is used. - Alloc func(n int) []byte -} - -// Select parses header data and appends it to given slice of Option. -// It also returns flag of successful (wellformed input) parsing. -func (s OptionSelector) Select(data []byte, options []Option) ([]Option, bool) { - var current Option - var has bool - index := -1 - - alloc := s.Alloc - if alloc == nil { - alloc = defaultAlloc - } - check := s.Check - if check == nil { - check = defaultCheck - } - - ok := ScanOptions(data, func(idx int, name, attr, val []byte) Control { - if idx != index { - if has && check(current) { - if s.Flags&SelectCopy != 0 { - current = current.Copy(alloc(current.Size())) - } - options = append(options, current) - has = false - } - if s.Flags&SelectUnique != 0 { - for i := len(options) - 1; i >= 0; i-- { - if bytes.Equal(options[i].Name, name) { - return ControlSkip - } - } - } - index = idx - current = Option{Name: name} - has = true - } - if attr != nil { - current.Parameters.Set(attr, val) - } - - return ControlContinue - }) - if has && check(current) { - if s.Flags&SelectCopy != 0 { - current = current.Copy(alloc(current.Size())) - } - options = append(options, current) - } - - return options, ok -} - -func defaultAlloc(n int) []byte { return make([]byte, n) } -func defaultCheck(Option) bool { return true } - -// Control represents operation that scanner should perform. -type Control byte - -const ( - // ControlContinue causes scanner to continue scan tokens. - ControlContinue Control = iota - // ControlBreak causes scanner to stop scan tokens. - ControlBreak - // ControlSkip causes scanner to skip current entity. - ControlSkip -) - -// ScanOptions parses data in this form: -// -// values = 1#value -// value = token *( ";" param ) -// param = token [ "=" (token | quoted-string) ] -// -// It calls given callback with the index of the option, option itself and its -// parameter (attribute and its value, both could be nil). Index is useful when -// header contains multiple choises for the same named option. -// -// Given callback should return one of the defined Control* values. -// ControlSkip means that passed key is not in caller's interest. That is, all -// parameters of that key will be skipped. -// ControlBreak means that no more keys and parameters should be parsed. That -// is, it must break parsing immediately. -// ControlContinue means that caller want to receive next parameter and its -// value or the next key. -// -// It returns false if data is malformed. -func ScanOptions(data []byte, it func(index int, option, attribute, value []byte) Control) bool { - lexer := &Scanner{data: data} - - var ok bool - var state int - const ( - stateKey = iota - stateParamBeforeName - stateParamName - stateParamBeforeValue - stateParamValue - ) - - var ( - index int - key, param, value []byte - mustCall bool - ) - for lexer.Next() { - var ( - call bool - growIndex int - ) - - t := lexer.Type() - v := lexer.Bytes() - - switch t { - case ItemToken: - switch state { - case stateKey, stateParamBeforeName: - key = v - state = stateParamBeforeName - mustCall = true - case stateParamName: - param = v - state = stateParamBeforeValue - mustCall = true - case stateParamValue: - value = v - state = stateParamBeforeName - call = true - default: - return false - } - - case ItemString: - if state != stateParamValue { - return false - } - value = v - state = stateParamBeforeName - call = true - - case ItemSeparator: - switch { - case isComma(v) && state == stateKey: - // Nothing to do. - - case isComma(v) && state == stateParamBeforeName: - state = stateKey - // Make call only if we have not called this key yet. - call = mustCall - if !call { - // If we have already called callback with the key - // that just ended. - index++ - } else { - // Else grow the index after calling callback. - growIndex = 1 - } - - case isComma(v) && state == stateParamBeforeValue: - state = stateKey - growIndex = 1 - call = true - - case isSemicolon(v) && state == stateParamBeforeName: - state = stateParamName - - case isSemicolon(v) && state == stateParamBeforeValue: - state = stateParamName - call = true - - case isEquality(v) && state == stateParamBeforeValue: - state = stateParamValue - - default: - return false - } - - default: - return false - } - - if call { - switch it(index, key, param, value) { - case ControlBreak: - // User want to stop to parsing parameters. - return true - - case ControlSkip: - // User want to skip current param. - state = stateKey - lexer.SkipEscaped(',') - - case ControlContinue: - // User is interested in rest of parameters. - // Nothing to do. - - default: - panic("unexpected control value") - } - ok = true - param = nil - value = nil - mustCall = false - index += growIndex - } - } - if mustCall { - ok = true - it(index, key, param, value) - } - - return ok && !lexer.err -} - -func isComma(b []byte) bool { - return len(b) == 1 && b[0] == ',' -} -func isSemicolon(b []byte) bool { - return len(b) == 1 && b[0] == ';' -} -func isEquality(b []byte) bool { - return len(b) == 1 && b[0] == '=' -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/lexer.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/lexer.go deleted file mode 100644 index 729855ed0d3..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/lexer.go +++ /dev/null @@ -1,360 +0,0 @@ -package httphead - -import ( - "bytes" -) - -// ItemType encodes type of the lexing token. -type ItemType int - -const ( - // ItemUndef reports that token is undefined. - ItemUndef ItemType = iota - // ItemToken reports that token is RFC2616 token. - ItemToken - // ItemSeparator reports that token is RFC2616 separator. - ItemSeparator - // ItemString reports that token is RFC2616 quouted string. - ItemString - // ItemComment reports that token is RFC2616 comment. - ItemComment - // ItemOctet reports that token is octet slice. - ItemOctet -) - -// Scanner represents header tokens scanner. -// See https://tools.ietf.org/html/rfc2616#section-2 -type Scanner struct { - data []byte - pos int - - itemType ItemType - itemBytes []byte - - err bool -} - -// NewScanner creates new RFC2616 data scanner. -func NewScanner(data []byte) *Scanner { - return &Scanner{data: data} -} - -// Next scans for next token. It returns true on successful scanning, and false -// on error or EOF. -func (l *Scanner) Next() bool { - c, ok := l.nextChar() - if !ok { - return false - } - switch c { - case '"': // quoted-string; - return l.fetchQuotedString() - - case '(': // comment; - return l.fetchComment() - - case '\\', ')': // unexpected chars; - l.err = true - return false - - default: - return l.fetchToken() - } -} - -// FetchUntil fetches ItemOctet from current scanner position to first -// occurence of the c or to the end of the underlying data. -func (l *Scanner) FetchUntil(c byte) bool { - l.resetItem() - if l.pos == len(l.data) { - return false - } - return l.fetchOctet(c) -} - -// Peek reads byte at current position without advancing it. On end of data it -// returns 0. -func (l *Scanner) Peek() byte { - if l.pos == len(l.data) { - return 0 - } - return l.data[l.pos] -} - -// Peek2 reads two first bytes at current position without advancing it. -// If there not enough data it returs 0. -func (l *Scanner) Peek2() (a, b byte) { - if l.pos == len(l.data) { - return 0, 0 - } - if l.pos+1 == len(l.data) { - return l.data[l.pos], 0 - } - return l.data[l.pos], l.data[l.pos+1] -} - -// Buffered reporst how many bytes there are left to scan. -func (l *Scanner) Buffered() int { - return len(l.data) - l.pos -} - -// Advance moves current position index at n bytes. It returns true on -// successful move. -func (l *Scanner) Advance(n int) bool { - l.pos += n - if l.pos > len(l.data) { - l.pos = len(l.data) - return false - } - return true -} - -// Skip skips all bytes until first occurence of c. -func (l *Scanner) Skip(c byte) { - if l.err { - return - } - // Reset scanner state. - l.resetItem() - - if i := bytes.IndexByte(l.data[l.pos:], c); i == -1 { - // Reached the end of data. - l.pos = len(l.data) - } else { - l.pos += i + 1 - } -} - -// SkipEscaped skips all bytes until first occurence of non-escaped c. -func (l *Scanner) SkipEscaped(c byte) { - if l.err { - return - } - // Reset scanner state. - l.resetItem() - - if i := ScanUntil(l.data[l.pos:], c); i == -1 { - // Reached the end of data. - l.pos = len(l.data) - } else { - l.pos += i + 1 - } -} - -// Type reports current token type. -func (l *Scanner) Type() ItemType { - return l.itemType -} - -// Bytes returns current token bytes. -func (l *Scanner) Bytes() []byte { - return l.itemBytes -} - -func (l *Scanner) nextChar() (byte, bool) { - // Reset scanner state. - l.resetItem() - - if l.err { - return 0, false - } - l.pos += SkipSpace(l.data[l.pos:]) - if l.pos == len(l.data) { - return 0, false - } - return l.data[l.pos], true -} - -func (l *Scanner) resetItem() { - l.itemType = ItemUndef - l.itemBytes = nil -} - -func (l *Scanner) fetchOctet(c byte) bool { - i := l.pos - if j := bytes.IndexByte(l.data[l.pos:], c); j == -1 { - // Reached the end of data. - l.pos = len(l.data) - } else { - l.pos += j - } - - l.itemType = ItemOctet - l.itemBytes = l.data[i:l.pos] - - return true -} - -func (l *Scanner) fetchToken() bool { - n, t := ScanToken(l.data[l.pos:]) - if n == -1 { - l.err = true - return false - } - - l.itemType = t - l.itemBytes = l.data[l.pos : l.pos+n] - l.pos += n - - return true -} - -func (l *Scanner) fetchQuotedString() (ok bool) { - l.pos++ - - n := ScanUntil(l.data[l.pos:], '"') - if n == -1 { - l.err = true - return false - } - - l.itemType = ItemString - l.itemBytes = RemoveByte(l.data[l.pos:l.pos+n], '\\') - l.pos += n + 1 - - return true -} - -func (l *Scanner) fetchComment() (ok bool) { - l.pos++ - - n := ScanPairGreedy(l.data[l.pos:], '(', ')') - if n == -1 { - l.err = true - return false - } - - l.itemType = ItemComment - l.itemBytes = RemoveByte(l.data[l.pos:l.pos+n], '\\') - l.pos += n + 1 - - return true -} - -// ScanUntil scans for first non-escaped character c in given data. -// It returns index of matched c and -1 if c is not found. -func ScanUntil(data []byte, c byte) (n int) { - for { - i := bytes.IndexByte(data[n:], c) - if i == -1 { - return -1 - } - n += i - if n == 0 || data[n-1] != '\\' { - break - } - n++ - } - return -} - -// ScanPairGreedy scans for complete pair of opening and closing chars in greedy manner. -// Note that first opening byte must not be present in data. -func ScanPairGreedy(data []byte, open, close byte) (n int) { - var m int - opened := 1 - for { - i := bytes.IndexByte(data[n:], close) - if i == -1 { - return -1 - } - n += i - // If found index is not escaped then it is the end. - if n == 0 || data[n-1] != '\\' { - opened-- - } - - for m < i { - j := bytes.IndexByte(data[m:i], open) - if j == -1 { - break - } - m += j + 1 - opened++ - } - - if opened == 0 { - break - } - - n++ - m = n - } - return -} - -// RemoveByte returns data without c. If c is not present in data it returns -// the same slice. If not, it copies data without c. -func RemoveByte(data []byte, c byte) []byte { - j := bytes.IndexByte(data, c) - if j == -1 { - return data - } - - n := len(data) - 1 - - // If character is present, than allocate slice with n-1 capacity. That is, - // resulting bytes could be at most n-1 length. - result := make([]byte, n) - k := copy(result, data[:j]) - - for i := j + 1; i < n; { - j = bytes.IndexByte(data[i:], c) - if j != -1 { - k += copy(result[k:], data[i:i+j]) - i = i + j + 1 - } else { - k += copy(result[k:], data[i:]) - break - } - } - - return result[:k] -} - -// SkipSpace skips spaces and lws-sequences from p. -// It returns number ob bytes skipped. -func SkipSpace(p []byte) (n int) { - for len(p) > 0 { - switch { - case len(p) >= 3 && - p[0] == '\r' && - p[1] == '\n' && - OctetTypes[p[2]].IsSpace(): - p = p[3:] - n += 3 - case OctetTypes[p[0]].IsSpace(): - p = p[1:] - n++ - default: - return - } - } - return -} - -// ScanToken scan for next token in p. It returns length of the token and its -// type. It do not trim p. -func ScanToken(p []byte) (n int, t ItemType) { - if len(p) == 0 { - return 0, ItemUndef - } - - c := p[0] - switch { - case OctetTypes[c].IsSeparator(): - return 1, ItemSeparator - - case OctetTypes[c].IsToken(): - for n = 1; n < len(p); n++ { - c := p[n] - if !OctetTypes[c].IsToken() { - break - } - } - return n, ItemToken - - default: - return -1, ItemUndef - } -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/octet.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/octet.go deleted file mode 100644 index 2a04cdd0909..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/octet.go +++ /dev/null @@ -1,83 +0,0 @@ -package httphead - -// OctetType desribes character type. -// -// From the "Basic Rules" chapter of RFC2616 -// See https://tools.ietf.org/html/rfc2616#section-2.2 -// -// OCTET = -// CHAR = -// UPALPHA = -// LOALPHA = -// ALPHA = UPALPHA | LOALPHA -// DIGIT = -// CTL = -// CR = -// LF = -// SP = -// HT = -// <"> = -// CRLF = CR LF -// LWS = [CRLF] 1*( SP | HT ) -// -// Many HTTP/1.1 header field values consist of words separated by LWS -// or special characters. These special characters MUST be in a quoted -// string to be used within a parameter value (as defined in section -// 3.6). -// -// token = 1* -// separators = "(" | ")" | "<" | ">" | "@" -// | "," | ";" | ":" | "\" | <"> -// | "/" | "[" | "]" | "?" | "=" -// | "{" | "}" | SP | HT -type OctetType byte - -// IsChar reports whether octet is CHAR. -func (t OctetType) IsChar() bool { return t&octetChar != 0 } - -// IsControl reports whether octet is CTL. -func (t OctetType) IsControl() bool { return t&octetControl != 0 } - -// IsSeparator reports whether octet is separator. -func (t OctetType) IsSeparator() bool { return t&octetSeparator != 0 } - -// IsSpace reports whether octet is space (SP or HT). -func (t OctetType) IsSpace() bool { return t&octetSpace != 0 } - -// IsToken reports whether octet is token. -func (t OctetType) IsToken() bool { return t&octetToken != 0 } - -const ( - octetChar OctetType = 1 << iota - octetControl - octetSpace - octetSeparator - octetToken -) - -// OctetTypes is a table of octets. -var OctetTypes [256]OctetType - -func init() { - for c := 32; c < 256; c++ { - var t OctetType - if c <= 127 { - t |= octetChar - } - if 0 <= c && c <= 31 || c == 127 { - t |= octetControl - } - switch c { - case '(', ')', '<', '>', '@', ',', ';', ':', '"', '/', '[', ']', '?', '=', '{', '}', '\\': - t |= octetSeparator - case ' ', '\t': - t |= octetSpace | octetSeparator - } - - if t.IsChar() && !t.IsControl() && !t.IsSeparator() && !t.IsSpace() { - t |= octetToken - } - - OctetTypes[c] = t - } -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/option.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/option.go deleted file mode 100644 index 243be08c9a0..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/option.go +++ /dev/null @@ -1,187 +0,0 @@ -package httphead - -import ( - "bytes" - "sort" -) - -// Option represents a header option. -type Option struct { - Name []byte - Parameters Parameters -} - -// Size returns number of bytes need to be allocated for use in opt.Copy. -func (opt Option) Size() int { - return len(opt.Name) + opt.Parameters.bytes -} - -// Copy copies all underlying []byte slices into p and returns new Option. -// Note that p must be at least of opt.Size() length. -func (opt Option) Copy(p []byte) Option { - n := copy(p, opt.Name) - opt.Name = p[:n] - opt.Parameters, p = opt.Parameters.Copy(p[n:]) - return opt -} - -// String represents option as a string. -func (opt Option) String() string { - return "{" + string(opt.Name) + " " + opt.Parameters.String() + "}" -} - -// NewOption creates named option with given parameters. -func NewOption(name string, params map[string]string) Option { - p := Parameters{} - for k, v := range params { - p.Set([]byte(k), []byte(v)) - } - return Option{ - Name: []byte(name), - Parameters: p, - } -} - -// Equal reports whether option is equal to b. -func (opt Option) Equal(b Option) bool { - if bytes.Equal(opt.Name, b.Name) { - return opt.Parameters.Equal(b.Parameters) - } - return false -} - -// Parameters represents option's parameters. -type Parameters struct { - pos int - bytes int - arr [8]pair - dyn []pair -} - -// Equal reports whether a equal to b. -func (p Parameters) Equal(b Parameters) bool { - switch { - case p.dyn == nil && b.dyn == nil: - case p.dyn != nil && b.dyn != nil: - default: - return false - } - - ad, bd := p.data(), b.data() - if len(ad) != len(bd) { - return false - } - - sort.Sort(pairs(ad)) - sort.Sort(pairs(bd)) - - for i := 0; i < len(ad); i++ { - av, bv := ad[i], bd[i] - if !bytes.Equal(av.key, bv.key) || !bytes.Equal(av.value, bv.value) { - return false - } - } - return true -} - -// Size returns number of bytes that needed to copy p. -func (p *Parameters) Size() int { - return p.bytes -} - -// Copy copies all underlying []byte slices into dst and returns new -// Parameters. -// Note that dst must be at least of p.Size() length. -func (p *Parameters) Copy(dst []byte) (Parameters, []byte) { - ret := Parameters{ - pos: p.pos, - bytes: p.bytes, - } - if p.dyn != nil { - ret.dyn = make([]pair, len(p.dyn)) - for i, v := range p.dyn { - ret.dyn[i], dst = v.copy(dst) - } - } else { - for i, p := range p.arr { - ret.arr[i], dst = p.copy(dst) - } - } - return ret, dst -} - -// Get returns value by key and flag about existence such value. -func (p *Parameters) Get(key string) (value []byte, ok bool) { - for _, v := range p.data() { - if string(v.key) == key { - return v.value, true - } - } - return nil, false -} - -// Set sets value by key. -func (p *Parameters) Set(key, value []byte) { - p.bytes += len(key) + len(value) - - if p.pos < len(p.arr) { - p.arr[p.pos] = pair{key, value} - p.pos++ - return - } - - if p.dyn == nil { - p.dyn = make([]pair, len(p.arr), len(p.arr)+1) - copy(p.dyn, p.arr[:]) - } - p.dyn = append(p.dyn, pair{key, value}) -} - -// ForEach iterates over parameters key-value pairs and calls cb for each one. -func (p *Parameters) ForEach(cb func(k, v []byte) bool) { - for _, v := range p.data() { - if !cb(v.key, v.value) { - break - } - } -} - -// String represents parameters as a string. -func (p *Parameters) String() (ret string) { - ret = "[" - for i, v := range p.data() { - if i > 0 { - ret += " " - } - ret += string(v.key) + ":" + string(v.value) - } - return ret + "]" -} - -func (p *Parameters) data() []pair { - if p.dyn != nil { - return p.dyn - } - return p.arr[:p.pos] -} - -type pair struct { - key, value []byte -} - -func (p pair) copy(dst []byte) (pair, []byte) { - n := copy(dst, p.key) - p.key = dst[:n] - m := n + copy(dst[n:], p.value) - p.value = dst[n:m] - - dst = dst[m:] - - return p, dst -} - -type pairs []pair - -func (p pairs) Len() int { return len(p) } -func (p pairs) Less(a, b int) bool { return bytes.Compare(p[a].key, p[b].key) == -1 } -func (p pairs) Swap(a, b int) { p[a], p[b] = p[b], p[a] } diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/writer.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/writer.go deleted file mode 100644 index e5df3ddf404..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/httphead/writer.go +++ /dev/null @@ -1,101 +0,0 @@ -package httphead - -import "io" - -var ( - comma = []byte{','} - equality = []byte{'='} - semicolon = []byte{';'} - quote = []byte{'"'} - escape = []byte{'\\'} -) - -// WriteOptions write options list to the dest. -// It uses the same form as {Scan,Parse}Options functions: -// values = 1#value -// value = token *( ";" param ) -// param = token [ "=" (token | quoted-string) ] -// -// It wraps valuse into the quoted-string sequence if it contains any -// non-token characters. -func WriteOptions(dest io.Writer, options []Option) (n int, err error) { - w := writer{w: dest} - for i, opt := range options { - if i > 0 { - w.write(comma) - } - - writeTokenSanitized(&w, opt.Name) - - for _, p := range opt.Parameters.data() { - w.write(semicolon) - writeTokenSanitized(&w, p.key) - if len(p.value) != 0 { - w.write(equality) - writeTokenSanitized(&w, p.value) - } - } - } - return w.result() -} - -// writeTokenSanitized writes token as is or as quouted string if it contains -// non-token characters. -// -// Note that is is not expects LWS sequnces be in s, cause LWS is used only as -// header field continuation: -// "A CRLF is allowed in the definition of TEXT only as part of a header field -// continuation. It is expected that the folding LWS will be replaced with a -// single SP before interpretation of the TEXT value." -// See https://tools.ietf.org/html/rfc2616#section-2 -// -// That is we sanitizing s for writing, so there could not be any header field -// continuation. -// That is any CRLF will be escaped as any other control characters not allowd in TEXT. -func writeTokenSanitized(bw *writer, bts []byte) { - var qt bool - var pos int - for i := 0; i < len(bts); i++ { - c := bts[i] - if !OctetTypes[c].IsToken() && !qt { - qt = true - bw.write(quote) - } - if OctetTypes[c].IsControl() || c == '"' { - if !qt { - qt = true - bw.write(quote) - } - bw.write(bts[pos:i]) - bw.write(escape) - bw.write(bts[i : i+1]) - pos = i + 1 - } - } - if !qt { - bw.write(bts) - } else { - bw.write(bts[pos:]) - bw.write(quote) - } -} - -type writer struct { - w io.Writer - n int - err error -} - -func (w *writer) write(p []byte) { - if w.err != nil { - return - } - var n int - n, w.err = w.w.Write(p) - w.n += n - return -} - -func (w *writer) result() (int, error) { - return w.n, w.err -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/README.md b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/README.md deleted file mode 100644 index 45685581dae..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/README.md +++ /dev/null @@ -1,107 +0,0 @@ -# pool - -[![GoDoc][godoc-image]][godoc-url] - -> Tiny memory reuse helpers for Go. - -## generic - -Without use of subpackages, `pool` allows to reuse any struct distinguishable -by size in generic way: - -```go -package main - -import "github.com/gobwas/pool" - -func main() { - x, n := pool.Get(100) // Returns object with size 128 or nil. - if x == nil { - // Create x somehow with knowledge that n is 128. - } - defer pool.Put(x, n) - - // Work with x. -} -``` - -Pool allows you to pass specific options for constructing custom pool: - -```go -package main - -import "github.com/gobwas/pool" - -func main() { - p := pool.Custom( - pool.WithLogSizeMapping(), // Will ceil size n passed to Get(n) to nearest power of two. - pool.WithLogSizeRange(64, 512), // Will reuse objects in logarithmic range [64, 512]. - pool.WithSize(65536), // Will reuse object with size 65536. - ) - x, n := p.Get(1000) // Returns nil and 1000 because mapped size 1000 => 1024 is not reusing by the pool. - defer pool.Put(x, n) // Will not reuse x. - - // Work with x. -} -``` - -Note that there are few non-generic pooling implementations inside subpackages. - -## pbytes - -Subpackage `pbytes` is intended for `[]byte` reuse. - -```go -package main - -import "github.com/gobwas/pool/pbytes" - -func main() { - bts := pbytes.GetCap(100) // Returns make([]byte, 0, 128). - defer pbytes.Put(bts) - - // Work with bts. -} -``` - -You can also create your own range for pooling: - -```go -package main - -import "github.com/gobwas/pool/pbytes" - -func main() { - // Reuse only slices whose capacity is 128, 256, 512 or 1024. - pool := pbytes.New(128, 1024) - - bts := pool.GetCap(100) // Returns make([]byte, 0, 128). - defer pool.Put(bts) - - // Work with bts. -} -``` - -## pbufio - -Subpackage `pbufio` is intended for `*bufio.{Reader, Writer}` reuse. - -```go -package main - -import "github.com/gobwas/pool/pbufio" - -func main() { - bw := pbufio.GetWriter(os.Stdout, 100) // Returns bufio.NewWriterSize(128). - defer pbufio.PutWriter(bw) - - // Work with bw. -} -``` - -Like with `pbytes`, you can also create pool with custom reuse bounds. - - - -[godoc-image]: https://godoc.org/github.com/gobwas/pool?status.svg -[godoc-url]: https://godoc.org/github.com/gobwas/pool diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/generic.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/generic.go deleted file mode 100644 index d40b362458b..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/generic.go +++ /dev/null @@ -1,87 +0,0 @@ -package pool - -import ( - "sync" - - "github.com/gobwas/pool/internal/pmath" -) - -var DefaultPool = New(128, 65536) - -// Get pulls object whose generic size is at least of given size. It also -// returns a real size of x for further pass to Put(). It returns -1 as real -// size for nil x. Size >-1 does not mean that x is non-nil, so checks must be -// done. -// -// Note that size could be ceiled to the next power of two. -// -// Get is a wrapper around DefaultPool.Get(). -func Get(size int) (interface{}, int) { return DefaultPool.Get(size) } - -// Put takes x and its size for future reuse. -// Put is a wrapper around DefaultPool.Put(). -func Put(x interface{}, size int) { DefaultPool.Put(x, size) } - -// Pool contains logic of reusing objects distinguishable by size in generic -// way. -type Pool struct { - pool map[int]*sync.Pool - size func(int) int -} - -// New creates new Pool that reuses objects which size is in logarithmic range -// [min, max]. -// -// Note that it is a shortcut for Custom() constructor with Options provided by -// WithLogSizeMapping() and WithLogSizeRange(min, max) calls. -func New(min, max int) *Pool { - return Custom( - WithLogSizeMapping(), - WithLogSizeRange(min, max), - ) -} - -// Custom creates new Pool with given options. -func Custom(opts ...Option) *Pool { - p := &Pool{ - pool: make(map[int]*sync.Pool), - size: pmath.Identity, - } - - c := (*poolConfig)(p) - for _, opt := range opts { - opt(c) - } - - return p -} - -// Get pulls object whose generic size is at least of given size. -// It also returns a real size of x for further pass to Put() even if x is nil. -// Note that size could be ceiled to the next power of two. -func (p *Pool) Get(size int) (interface{}, int) { - n := p.size(size) - if pool := p.pool[n]; pool != nil { - return pool.Get(), n - } - return nil, size -} - -// Put takes x and its size for future reuse. -func (p *Pool) Put(x interface{}, size int) { - if pool := p.pool[size]; pool != nil { - pool.Put(x) - } -} - -type poolConfig Pool - -// AddSize adds size n to the map. -func (p *poolConfig) AddSize(n int) { - p.pool[n] = new(sync.Pool) -} - -// SetSizeMapping sets up incoming size mapping function. -func (p *poolConfig) SetSizeMapping(size func(int) int) { - p.size = size -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/internal/pmath/pmath.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/internal/pmath/pmath.go deleted file mode 100644 index df152ed12a5..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/internal/pmath/pmath.go +++ /dev/null @@ -1,65 +0,0 @@ -package pmath - -const ( - bitsize = 32 << (^uint(0) >> 63) - maxint = int(1<<(bitsize-1) - 1) - maxintHeadBit = 1 << (bitsize - 2) -) - -// LogarithmicRange iterates from ceiled to power of two min to max, -// calling cb on each iteration. -func LogarithmicRange(min, max int, cb func(int)) { - if min == 0 { - min = 1 - } - for n := CeilToPowerOfTwo(min); n <= max; n <<= 1 { - cb(n) - } -} - -// IsPowerOfTwo reports whether given integer is a power of two. -func IsPowerOfTwo(n int) bool { - return n&(n-1) == 0 -} - -// Identity is identity. -func Identity(n int) int { - return n -} - -// CeilToPowerOfTwo returns the least power of two integer value greater than -// or equal to n. -func CeilToPowerOfTwo(n int) int { - if n&maxintHeadBit != 0 && n > maxintHeadBit { - panic("argument is too large") - } - if n <= 2 { - return n - } - n-- - n = fillBits(n) - n++ - return n -} - -// FloorToPowerOfTwo returns the greatest power of two integer value less than -// or equal to n. -func FloorToPowerOfTwo(n int) int { - if n <= 2 { - return n - } - n = fillBits(n) - n >>= 1 - n++ - return n -} - -func fillBits(n int) int { - n |= n >> 1 - n |= n >> 2 - n |= n >> 4 - n |= n >> 8 - n |= n >> 16 - n |= n >> 32 - return n -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/option.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/option.go deleted file mode 100644 index d6e42b70055..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/option.go +++ /dev/null @@ -1,43 +0,0 @@ -package pool - -import "github.com/gobwas/pool/internal/pmath" - -// Option configures pool. -type Option func(Config) - -// Config describes generic pool configuration. -type Config interface { - AddSize(n int) - SetSizeMapping(func(int) int) -} - -// WithSizeLogRange returns an Option that will add logarithmic range of -// pooling sizes containing [min, max] values. -func WithLogSizeRange(min, max int) Option { - return func(c Config) { - pmath.LogarithmicRange(min, max, func(n int) { - c.AddSize(n) - }) - } -} - -// WithSize returns an Option that will add given pooling size to the pool. -func WithSize(n int) Option { - return func(c Config) { - c.AddSize(n) - } -} - -func WithSizeMapping(sz func(int) int) Option { - return func(c Config) { - c.SetSizeMapping(sz) - } -} - -func WithLogSizeMapping() Option { - return WithSizeMapping(pmath.CeilToPowerOfTwo) -} - -func WithIdentitySizeMapping() Option { - return WithSizeMapping(pmath.Identity) -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/pbufio/pbufio.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/pbufio/pbufio.go deleted file mode 100644 index d526bd80da8..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/pbufio/pbufio.go +++ /dev/null @@ -1,106 +0,0 @@ -// Package pbufio contains tools for pooling bufio.Reader and bufio.Writers. -package pbufio - -import ( - "bufio" - "io" - - "github.com/gobwas/pool" -) - -var ( - DefaultWriterPool = NewWriterPool(256, 65536) - DefaultReaderPool = NewReaderPool(256, 65536) -) - -// GetWriter returns bufio.Writer whose buffer has at least size bytes. -// Note that size could be ceiled to the next power of two. -// GetWriter is a wrapper around DefaultWriterPool.Get(). -func GetWriter(w io.Writer, size int) *bufio.Writer { return DefaultWriterPool.Get(w, size) } - -// PutWriter takes bufio.Writer for future reuse. -// It does not reuse bufio.Writer which underlying buffer size is not power of -// PutWriter is a wrapper around DefaultWriterPool.Put(). -func PutWriter(bw *bufio.Writer) { DefaultWriterPool.Put(bw) } - -// GetReader returns bufio.Reader whose buffer has at least size bytes. It returns -// its capacity for further pass to Put(). -// Note that size could be ceiled to the next power of two. -// GetReader is a wrapper around DefaultReaderPool.Get(). -func GetReader(w io.Reader, size int) *bufio.Reader { return DefaultReaderPool.Get(w, size) } - -// PutReader takes bufio.Reader and its size for future reuse. -// It does not reuse bufio.Reader if size is not power of two or is out of pool -// min/max range. -// PutReader is a wrapper around DefaultReaderPool.Put(). -func PutReader(bw *bufio.Reader) { DefaultReaderPool.Put(bw) } - -// WriterPool contains logic of *bufio.Writer reuse with various size. -type WriterPool struct { - pool *pool.Pool -} - -// NewWriterPool creates new WriterPool that reuses writers which size is in -// logarithmic range [min, max]. -func NewWriterPool(min, max int) *WriterPool { - return &WriterPool{pool.New(min, max)} -} - -// CustomWriterPool creates new WriterPool with given options. -func CustomWriterPool(opts ...pool.Option) *WriterPool { - return &WriterPool{pool.Custom(opts...)} -} - -// Get returns bufio.Writer whose buffer has at least size bytes. -func (wp *WriterPool) Get(w io.Writer, size int) *bufio.Writer { - v, n := wp.pool.Get(size) - if v != nil { - bw := v.(*bufio.Writer) - bw.Reset(w) - return bw - } - return bufio.NewWriterSize(w, n) -} - -// Put takes ownership of bufio.Writer for further reuse. -func (wp *WriterPool) Put(bw *bufio.Writer) { - // Should reset even if we do Reset() inside Get(). - // This is done to prevent locking underlying io.Writer from GC. - bw.Reset(nil) - wp.pool.Put(bw, writerSize(bw)) -} - -// ReaderPool contains logic of *bufio.Reader reuse with various size. -type ReaderPool struct { - pool *pool.Pool -} - -// NewReaderPool creates new ReaderPool that reuses writers which size is in -// logarithmic range [min, max]. -func NewReaderPool(min, max int) *ReaderPool { - return &ReaderPool{pool.New(min, max)} -} - -// CustomReaderPool creates new ReaderPool with given options. -func CustomReaderPool(opts ...pool.Option) *ReaderPool { - return &ReaderPool{pool.Custom(opts...)} -} - -// Get returns bufio.Reader whose buffer has at least size bytes. -func (rp *ReaderPool) Get(r io.Reader, size int) *bufio.Reader { - v, n := rp.pool.Get(size) - if v != nil { - br := v.(*bufio.Reader) - br.Reset(r) - return br - } - return bufio.NewReaderSize(r, n) -} - -// Put takes ownership of bufio.Reader for further reuse. -func (rp *ReaderPool) Put(br *bufio.Reader) { - // Should reset even if we do Reset() inside Get(). - // This is done to prevent locking underlying io.Reader from GC. - br.Reset(nil) - rp.pool.Put(br, readerSize(br)) -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/pbufio/pbufio_go110.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/pbufio/pbufio_go110.go deleted file mode 100644 index c736ae56e11..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/pbufio/pbufio_go110.go +++ /dev/null @@ -1,13 +0,0 @@ -// +build go1.10 - -package pbufio - -import "bufio" - -func writerSize(bw *bufio.Writer) int { - return bw.Size() -} - -func readerSize(br *bufio.Reader) int { - return br.Size() -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/pbufio/pbufio_go19.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/pbufio/pbufio_go19.go deleted file mode 100644 index e71dd447d2a..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/pbufio/pbufio_go19.go +++ /dev/null @@ -1,27 +0,0 @@ -// +build !go1.10 - -package pbufio - -import "bufio" - -func writerSize(bw *bufio.Writer) int { - return bw.Available() + bw.Buffered() -} - -// readerSize returns buffer size of the given buffered reader. -// NOTE: current workaround implementation resets underlying io.Reader. -func readerSize(br *bufio.Reader) int { - br.Reset(sizeReader) - br.ReadByte() - n := br.Buffered() + 1 - br.Reset(nil) - return n -} - -var sizeReader optimisticReader - -type optimisticReader struct{} - -func (optimisticReader) Read(p []byte) (int, error) { - return len(p), nil -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/pool.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/pool.go deleted file mode 100644 index 1fe9e602fc5..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/pool/pool.go +++ /dev/null @@ -1,25 +0,0 @@ -// Package pool contains helpers for pooling structures distinguishable by -// size. -// -// Quick example: -// -// import "github.com/gobwas/pool" -// -// func main() { -// // Reuse objects in logarithmic range from 0 to 64 (0,1,2,4,6,8,16,32,64). -// p := pool.New(0, 64) -// -// buf, n := p.Get(10) // Returns buffer with 16 capacity. -// if buf == nil { -// buf = bytes.NewBuffer(make([]byte, n)) -// } -// defer p.Put(buf, n) -// -// // Work with buf. -// } -// -// There are non-generic implementations for pooling: -// - pool/pbytes for []byte reuse; -// - pool/pbufio for *bufio.Reader and *bufio.Writer reuse; -// -package pool diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/.gitignore b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/.gitignore deleted file mode 100644 index e3e2b1080d0..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -bin/ -reports/ -cpu.out -mem.out -ws.test diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/.travis.yml b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/.travis.yml deleted file mode 100644 index cf74f1bee3c..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/.travis.yml +++ /dev/null @@ -1,25 +0,0 @@ -sudo: required - -language: go - -services: - - docker - -os: - - linux - - windows - -go: - - 1.8.x - - 1.9.x - - 1.10.x - - 1.11.x - - 1.x - -install: - - go get github.com/gobwas/pool - - go get github.com/gobwas/httphead - -script: - - if [ "$TRAVIS_OS_NAME" = "windows" ]; then go test ./...; fi - - if [ "$TRAVIS_OS_NAME" = "linux" ]; then make test autobahn; fi diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/Makefile b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/Makefile deleted file mode 100644 index 075e83c74bc..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -BENCH ?=. -BENCH_BASE?=master - -clean: - rm -f bin/reporter - rm -fr autobahn/report/* - -bin/reporter: - go build -o bin/reporter ./autobahn - -bin/gocovmerge: - go build -o bin/gocovmerge github.com/wadey/gocovmerge - -.PHONY: autobahn -autobahn: clean bin/reporter - ./autobahn/script/test.sh --build - bin/reporter $(PWD)/autobahn/report/index.json - -test: - go test -coverprofile=ws.coverage . - go test -coverprofile=wsutil.coverage ./wsutil - -cover: bin/gocovmerge test autobahn - bin/gocovmerge ws.coverage wsutil.coverage autobahn/report/server.coverage > total.coverage - -benchcmp: BENCH_BRANCH=$(shell git rev-parse --abbrev-ref HEAD) -benchcmp: BENCH_OLD:=$(shell mktemp -t old.XXXX) -benchcmp: BENCH_NEW:=$(shell mktemp -t new.XXXX) -benchcmp: - if [ ! -z "$(shell git status -s)" ]; then\ - echo "could not compare with $(BENCH_BASE) – found unstaged changes";\ - exit 1;\ - fi;\ - if [ "$(BENCH_BRANCH)" == "$(BENCH_BASE)" ]; then\ - echo "comparing the same branches";\ - exit 1;\ - fi;\ - echo "benchmarking $(BENCH_BRANCH)...";\ - go test -run=none -bench=$(BENCH) -benchmem > $(BENCH_NEW);\ - echo "benchmarking $(BENCH_BASE)...";\ - git checkout -q $(BENCH_BASE);\ - go test -run=none -bench=$(BENCH) -benchmem > $(BENCH_OLD);\ - git checkout -q $(BENCH_BRANCH);\ - echo "\nresults:";\ - echo "========\n";\ - benchcmp $(BENCH_OLD) $(BENCH_NEW);\ - diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/README.md b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/README.md deleted file mode 100644 index 74acd78bd08..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/README.md +++ /dev/null @@ -1,360 +0,0 @@ -# ws - -[![GoDoc][godoc-image]][godoc-url] -[![Travis][travis-image]][travis-url] - -> [RFC6455][rfc-url] WebSocket implementation in Go. - -# Features - -- Zero-copy upgrade -- No intermediate allocations during I/O -- Low-level API which allows to build your own logic of packet handling and - buffers reuse -- High-level wrappers and helpers around API in `wsutil` package, which allow - to start fast without digging the protocol internals - -# Documentation - -[GoDoc][godoc-url]. - -# Why - -Existing WebSocket implementations do not allow users to reuse I/O buffers -between connections in clear way. This library aims to export efficient -low-level interface for working with the protocol without forcing only one way -it could be used. - -By the way, if you want get the higher-level tools, you can use `wsutil` -package. - -# Status - -Library is tagged as `v1*` so its API must not be broken during some -improvements or refactoring. - -This implementation of RFC6455 passes [Autobahn Test -Suite](https://github.com/crossbario/autobahn-testsuite) and currently has -about 78% coverage. - -# Examples - -Example applications using `ws` are developed in separate repository -[ws-examples](https://github.com/gobwas/ws-examples). - -# Usage - -The higher-level example of WebSocket echo server: - -```go -package main - -import ( - "net/http" - - "github.com/gobwas/ws" - "github.com/gobwas/ws/wsutil" -) - -func main() { - http.ListenAndServe(":8080", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - conn, _, _, err := ws.UpgradeHTTP(r, w) - if err != nil { - // handle error - } - go func() { - defer conn.Close() - - for { - msg, op, err := wsutil.ReadClientData(conn) - if err != nil { - // handle error - } - err = wsutil.WriteServerMessage(conn, op, msg) - if err != nil { - // handle error - } - } - }() - })) -} -``` - -Lower-level, but still high-level example: - - -```go -import ( - "net/http" - "io" - - "github.com/gobwas/ws" - "github.com/gobwas/ws/wsutil" -) - -func main() { - http.ListenAndServe(":8080", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - conn, _, _, err := ws.UpgradeHTTP(r, w) - if err != nil { - // handle error - } - go func() { - defer conn.Close() - - var ( - state = ws.StateServerSide - reader = wsutil.NewReader(conn, state) - writer = wsutil.NewWriter(conn, state, ws.OpText) - ) - for { - header, err := reader.NextFrame() - if err != nil { - // handle error - } - - // Reset writer to write frame with right operation code. - writer.Reset(conn, state, header.OpCode) - - if _, err = io.Copy(writer, reader); err != nil { - // handle error - } - if err = writer.Flush(); err != nil { - // handle error - } - } - }() - })) -} -``` - -We can apply the same pattern to read and write structured responses through a JSON encoder and decoder.: - -```go - ... - var ( - r = wsutil.NewReader(conn, ws.StateServerSide) - w = wsutil.NewWriter(conn, ws.StateServerSide, ws.OpText) - decoder = json.NewDecoder(r) - encoder = json.NewEncoder(w) - ) - for { - hdr, err = r.NextFrame() - if err != nil { - return err - } - if hdr.OpCode == ws.OpClose { - return io.EOF - } - var req Request - if err := decoder.Decode(&req); err != nil { - return err - } - var resp Response - if err := encoder.Encode(&resp); err != nil { - return err - } - if err = w.Flush(); err != nil { - return err - } - } - ... -``` - -The lower-level example without `wsutil`: - -```go -package main - -import ( - "net" - "io" - - "github.com/gobwas/ws" -) - -func main() { - ln, err := net.Listen("tcp", "localhost:8080") - if err != nil { - log.Fatal(err) - } - - for { - conn, err := ln.Accept() - if err != nil { - // handle error - } - _, err = ws.Upgrade(conn) - if err != nil { - // handle error - } - - go func() { - defer conn.Close() - - for { - header, err := ws.ReadHeader(conn) - if err != nil { - // handle error - } - - payload := make([]byte, header.Length) - _, err = io.ReadFull(conn, payload) - if err != nil { - // handle error - } - if header.Masked { - ws.Cipher(payload, header.Mask, 0) - } - - // Reset the Masked flag, server frames must not be masked as - // RFC6455 says. - header.Masked = false - - if err := ws.WriteHeader(conn, header); err != nil { - // handle error - } - if _, err := conn.Write(payload); err != nil { - // handle error - } - - if header.OpCode == ws.OpClose { - return - } - } - }() - } -} -``` - -# Zero-copy upgrade - -Zero-copy upgrade helps to avoid unnecessary allocations and copying while -handling HTTP Upgrade request. - -Processing of all non-websocket headers is made in place with use of registered -user callbacks whose arguments are only valid until callback returns. - -The simple example looks like this: - -```go -package main - -import ( - "net" - "log" - - "github.com/gobwas/ws" -) - -func main() { - ln, err := net.Listen("tcp", "localhost:8080") - if err != nil { - log.Fatal(err) - } - u := ws.Upgrader{ - OnHeader: func(key, value []byte) (err error) { - log.Printf("non-websocket header: %q=%q", key, value) - return - }, - } - for { - conn, err := ln.Accept() - if err != nil { - // handle error - } - - _, err = u.Upgrade(conn) - if err != nil { - // handle error - } - } -} -``` - -Usage of `ws.Upgrader` here brings ability to control incoming connections on -tcp level and simply not to accept them by some logic. - -Zero-copy upgrade is for high-load services which have to control many -resources such as connections buffers. - -The real life example could be like this: - -```go -package main - -import ( - "fmt" - "io" - "log" - "net" - "net/http" - "runtime" - - "github.com/gobwas/httphead" - "github.com/gobwas/ws" -) - -func main() { - ln, err := net.Listen("tcp", "localhost:8080") - if err != nil { - // handle error - } - - // Prepare handshake header writer from http.Header mapping. - header := ws.HandshakeHeaderHTTP(http.Header{ - "X-Go-Version": []string{runtime.Version()}, - }) - - u := ws.Upgrader{ - OnHost: func(host []byte) error { - if string(host) == "github.com" { - return nil - } - return ws.RejectConnectionError( - ws.RejectionStatus(403), - ws.RejectionHeader(ws.HandshakeHeaderString( - "X-Want-Host: github.com\r\n", - )), - ) - }, - OnHeader: func(key, value []byte) error { - if string(key) != "Cookie" { - return nil - } - ok := httphead.ScanCookie(value, func(key, value []byte) bool { - // Check session here or do some other stuff with cookies. - // Maybe copy some values for future use. - return true - }) - if ok { - return nil - } - return ws.RejectConnectionError( - ws.RejectionReason("bad cookie"), - ws.RejectionStatus(400), - ) - }, - OnBeforeUpgrade: func() (ws.HandshakeHeader, error) { - return header, nil - }, - } - for { - conn, err := ln.Accept() - if err != nil { - log.Fatal(err) - } - _, err = u.Upgrade(conn) - if err != nil { - log.Printf("upgrade error: %s", err) - } - } -} -``` - - - -[rfc-url]: https://tools.ietf.org/html/rfc6455 -[godoc-image]: https://godoc.org/github.com/gobwas/ws?status.svg -[godoc-url]: https://godoc.org/github.com/gobwas/ws -[travis-image]: https://travis-ci.org/gobwas/ws.svg?branch=master -[travis-url]: https://travis-ci.org/gobwas/ws diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/check.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/check.go deleted file mode 100644 index 8aa0df8cc28..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/check.go +++ /dev/null @@ -1,145 +0,0 @@ -package ws - -import "unicode/utf8" - -// State represents state of websocket endpoint. -// It used by some functions to be more strict when checking compatibility with RFC6455. -type State uint8 - -const ( - // StateServerSide means that endpoint (caller) is a server. - StateServerSide State = 0x1 << iota - // StateClientSide means that endpoint (caller) is a client. - StateClientSide - // StateExtended means that extension was negotiated during handshake. - StateExtended - // StateFragmented means that endpoint (caller) has received fragmented - // frame and waits for continuation parts. - StateFragmented -) - -// Is checks whether the s has v enabled. -func (s State) Is(v State) bool { - return uint8(s)&uint8(v) != 0 -} - -// Set enables v state on s. -func (s State) Set(v State) State { - return s | v -} - -// Clear disables v state on s. -func (s State) Clear(v State) State { - return s & (^v) -} - -// ServerSide reports whether states represents server side. -func (s State) ServerSide() bool { return s.Is(StateServerSide) } - -// ClientSide reports whether state represents client side. -func (s State) ClientSide() bool { return s.Is(StateClientSide) } - -// Extended reports whether state is extended. -func (s State) Extended() bool { return s.Is(StateExtended) } - -// Fragmented reports whether state is fragmented. -func (s State) Fragmented() bool { return s.Is(StateFragmented) } - -// ProtocolError describes error during checking/parsing websocket frames or -// headers. -type ProtocolError string - -// Error implements error interface. -func (p ProtocolError) Error() string { return string(p) } - -// Errors used by the protocol checkers. -var ( - ErrProtocolOpCodeReserved = ProtocolError("use of reserved op code") - ErrProtocolControlPayloadOverflow = ProtocolError("control frame payload limit exceeded") - ErrProtocolControlNotFinal = ProtocolError("control frame is not final") - ErrProtocolNonZeroRsv = ProtocolError("non-zero rsv bits with no extension negotiated") - ErrProtocolMaskRequired = ProtocolError("frames from client to server must be masked") - ErrProtocolMaskUnexpected = ProtocolError("frames from server to client must be not masked") - ErrProtocolContinuationExpected = ProtocolError("unexpected non-continuation data frame") - ErrProtocolContinuationUnexpected = ProtocolError("unexpected continuation data frame") - ErrProtocolStatusCodeNotInUse = ProtocolError("status code is not in use") - ErrProtocolStatusCodeApplicationLevel = ProtocolError("status code is only application level") - ErrProtocolStatusCodeNoMeaning = ProtocolError("status code has no meaning yet") - ErrProtocolStatusCodeUnknown = ProtocolError("status code is not defined in spec") - ErrProtocolInvalidUTF8 = ProtocolError("invalid utf8 sequence in close reason") -) - -// CheckHeader checks h to contain valid header data for given state s. -// -// Note that zero state (0) means that state is clean, -// neither server or client side, nor fragmented, nor extended. -func CheckHeader(h Header, s State) error { - if h.OpCode.IsReserved() { - return ErrProtocolOpCodeReserved - } - if h.OpCode.IsControl() { - if h.Length > MaxControlFramePayloadSize { - return ErrProtocolControlPayloadOverflow - } - if !h.Fin { - return ErrProtocolControlNotFinal - } - } - - switch { - // [RFC6455]: MUST be 0 unless an extension is negotiated that defines meanings for - // non-zero values. If a nonzero value is received and none of the - // negotiated extensions defines the meaning of such a nonzero value, the - // receiving endpoint MUST _Fail the WebSocket Connection_. - case h.Rsv != 0 && !s.Extended(): - return ErrProtocolNonZeroRsv - - // [RFC6455]: The server MUST close the connection upon receiving a frame that is not masked. - // In this case, a server MAY send a Close frame with a status code of 1002 (protocol error) - // as defined in Section 7.4.1. A server MUST NOT mask any frames that it sends to the client. - // A client MUST close a connection if it detects a masked frame. In this case, it MAY use the - // status code 1002 (protocol error) as defined in Section 7.4.1. - case s.ServerSide() && !h.Masked: - return ErrProtocolMaskRequired - case s.ClientSide() && h.Masked: - return ErrProtocolMaskUnexpected - - // [RFC6455]: See detailed explanation in 5.4 section. - case s.Fragmented() && !h.OpCode.IsControl() && h.OpCode != OpContinuation: - return ErrProtocolContinuationExpected - case !s.Fragmented() && h.OpCode == OpContinuation: - return ErrProtocolContinuationUnexpected - - default: - return nil - } -} - -// CheckCloseFrameData checks received close information -// to be valid RFC6455 compatible close info. -// -// Note that code.Empty() or code.IsAppLevel() will raise error. -// -// If endpoint sends close frame without status code (with frame.Length = 0), -// application should not check its payload. -func CheckCloseFrameData(code StatusCode, reason string) error { - switch { - case code.IsNotUsed(): - return ErrProtocolStatusCodeNotInUse - - case code.IsProtocolReserved(): - return ErrProtocolStatusCodeApplicationLevel - - case code == StatusNoMeaningYet: - return ErrProtocolStatusCodeNoMeaning - - case code.IsProtocolSpec() && !code.IsProtocolDefined(): - return ErrProtocolStatusCodeUnknown - - case !utf8.ValidString(reason): - return ErrProtocolInvalidUTF8 - - default: - return nil - } -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/cipher.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/cipher.go deleted file mode 100644 index 11a2af99bfc..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/cipher.go +++ /dev/null @@ -1,59 +0,0 @@ -package ws - -import ( - "encoding/binary" - "unsafe" -) - -// Cipher applies XOR cipher to the payload using mask. -// Offset is used to cipher chunked data (e.g. in io.Reader implementations). -// -// To convert masked data into unmasked data, or vice versa, the following -// algorithm is applied. The same algorithm applies regardless of the -// direction of the translation, e.g., the same steps are applied to -// mask the data as to unmask the data. -func Cipher(payload []byte, mask [4]byte, offset int) { - n := len(payload) - if n < 8 { - for i := 0; i < n; i++ { - payload[i] ^= mask[(offset+i)%4] - } - return - } - - // Calculate position in mask due to previously processed bytes number. - mpos := offset % 4 - // Count number of bytes will processed one by one from the beginning of payload. - ln := remain[mpos] - // Count number of bytes will processed one by one from the end of payload. - // This is done to process payload by 8 bytes in each iteration of main loop. - rn := (n - ln) % 8 - - for i := 0; i < ln; i++ { - payload[i] ^= mask[(mpos+i)%4] - } - for i := n - rn; i < n; i++ { - payload[i] ^= mask[(mpos+i)%4] - } - - // We should cast mask to uint32 with unsafe instead of encoding.BigEndian - // to avoid care of os dependent byte order. That is, on any endianess mask - // and payload will be presented with the same order. In other words, we - // could not use encoding.BigEndian on xoring payload as uint64. - m := *(*uint32)(unsafe.Pointer(&mask)) - m2 := uint64(m)<<32 | uint64(m) - - // Skip already processed right part. - // Get number of uint64 parts remaining to process. - n = (n - ln - rn) >> 3 - for i := 0; i < n; i++ { - idx := ln + (i << 3) - p := binary.LittleEndian.Uint64(payload[idx : idx+8]) - p = p ^ m2 - binary.LittleEndian.PutUint64(payload[idx:idx+8], p) - } -} - -// remain maps position in masking key [0,4) to number -// of bytes that need to be processed manually inside Cipher(). -var remain = [4]int{0, 3, 2, 1} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/dialer.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/dialer.go deleted file mode 100644 index 4357be2142b..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/dialer.go +++ /dev/null @@ -1,556 +0,0 @@ -package ws - -import ( - "bufio" - "bytes" - "context" - "crypto/tls" - "fmt" - "io" - "net" - "net/url" - "strconv" - "strings" - "time" - - "github.com/gobwas/httphead" - "github.com/gobwas/pool/pbufio" -) - -// Constants used by Dialer. -const ( - DefaultClientReadBufferSize = 4096 - DefaultClientWriteBufferSize = 4096 -) - -// Handshake represents handshake result. -type Handshake struct { - // Protocol is the subprotocol selected during handshake. - Protocol string - - // Extensions is the list of negotiated extensions. - Extensions []httphead.Option -} - -// Errors used by the websocket client. -var ( - ErrHandshakeBadStatus = fmt.Errorf("unexpected http status") - ErrHandshakeBadSubProtocol = fmt.Errorf("unexpected protocol in %q header", headerSecProtocol) - ErrHandshakeBadExtensions = fmt.Errorf("unexpected extensions in %q header", headerSecProtocol) -) - -// DefaultDialer is dialer that holds no options and is used by Dial function. -var DefaultDialer Dialer - -// Dial is like Dialer{}.Dial(). -func Dial(ctx context.Context, urlstr string) (net.Conn, *bufio.Reader, Handshake, error) { - return DefaultDialer.Dial(ctx, urlstr) -} - -// Dialer contains options for establishing websocket connection to an url. -type Dialer struct { - // ReadBufferSize and WriteBufferSize is an I/O buffer sizes. - // They used to read and write http data while upgrading to WebSocket. - // Allocated buffers are pooled with sync.Pool to avoid extra allocations. - // - // If a size is zero then default value is used. - ReadBufferSize, WriteBufferSize int - - // Timeout is the maximum amount of time a Dial() will wait for a connect - // and an handshake to complete. - // - // The default is no timeout. - Timeout time.Duration - - // Protocols is the list of subprotocols that the client wants to speak, - // ordered by preference. - // - // See https://tools.ietf.org/html/rfc6455#section-4.1 - Protocols []string - - // Extensions is the list of extensions that client wants to speak. - // - // Note that if server decides to use some of this extensions, Dial() will - // return Handshake struct containing a slice of items, which are the - // shallow copies of the items from this list. That is, internals of - // Extensions items are shared during Dial(). - // - // See https://tools.ietf.org/html/rfc6455#section-4.1 - // See https://tools.ietf.org/html/rfc6455#section-9.1 - Extensions []httphead.Option - - // Header is an optional HandshakeHeader instance that could be used to - // write additional headers to the handshake request. - // - // It used instead of any key-value mappings to avoid allocations in user - // land. - Header HandshakeHeader - - // OnStatusError is the callback that will be called after receiving non - // "101 Continue" HTTP response status. It receives an io.Reader object - // representing server response bytes. That is, it gives ability to parse - // HTTP response somehow (probably with http.ReadResponse call) and make a - // decision of further logic. - // - // The arguments are only valid until the callback returns. - OnStatusError func(status int, reason []byte, resp io.Reader) - - // OnHeader is the callback that will be called after successful parsing of - // header, that is not used during WebSocket handshake procedure. That is, - // it will be called with non-websocket headers, which could be relevant - // for application-level logic. - // - // The arguments are only valid until the callback returns. - // - // Returned value could be used to prevent processing response. - OnHeader func(key, value []byte) (err error) - - // NetDial is the function that is used to get plain tcp connection. - // If it is not nil, then it is used instead of net.Dialer. - NetDial func(ctx context.Context, network, addr string) (net.Conn, error) - - // TLSClient is the callback that will be called after successful dial with - // received connection and its remote host name. If it is nil, then the - // default tls.Client() will be used. - // If it is not nil, then TLSConfig field is ignored. - TLSClient func(conn net.Conn, hostname string) net.Conn - - // TLSConfig is passed to tls.Client() to start TLS over established - // connection. If TLSClient is not nil, then it is ignored. If TLSConfig is - // non-nil and its ServerName is empty, then for every Dial() it will be - // cloned and appropriate ServerName will be set. - TLSConfig *tls.Config - - // WrapConn is the optional callback that will be called when connection is - // ready for an i/o. That is, it will be called after successful dial and - // TLS initialization (for "wss" schemes). It may be helpful for different - // user land purposes such as end to end encryption. - // - // Note that for debugging purposes of an http handshake (e.g. sent request - // and received response), there is an wsutil.DebugDialer struct. - WrapConn func(conn net.Conn) net.Conn -} - -// Dial connects to the url host and upgrades connection to WebSocket. -// -// If server has sent frames right after successful handshake then returned -// buffer will be non-nil. In other cases buffer is always nil. For better -// memory efficiency received non-nil bufio.Reader should be returned to the -// inner pool with PutReader() function after use. -// -// Note that Dialer does not implement IDNA (RFC5895) logic as net/http does. -// If you want to dial non-ascii host name, take care of its name serialization -// avoiding bad request issues. For more info see net/http Request.Write() -// implementation, especially cleanHost() function. -func (d Dialer) Dial(ctx context.Context, urlstr string) (conn net.Conn, br *bufio.Reader, hs Handshake, err error) { - u, err := url.ParseRequestURI(urlstr) - if err != nil { - return - } - - // Prepare context to dial with. Initially it is the same as original, but - // if d.Timeout is non-zero and points to time that is before ctx.Deadline, - // we use more shorter context for dial. - dialctx := ctx - - var deadline time.Time - if t := d.Timeout; t != 0 { - deadline = time.Now().Add(t) - if d, ok := ctx.Deadline(); !ok || deadline.Before(d) { - var cancel context.CancelFunc - dialctx, cancel = context.WithDeadline(ctx, deadline) - defer cancel() - } - } - if conn, err = d.dial(dialctx, u); err != nil { - return - } - defer func() { - if err != nil { - conn.Close() - } - }() - if ctx == context.Background() { - // No need to start I/O interrupter goroutine which is not zero-cost. - conn.SetDeadline(deadline) - defer conn.SetDeadline(noDeadline) - } else { - // Context could be canceled or its deadline could be exceeded. - // Start the interrupter goroutine to handle context cancelation. - done := setupContextDeadliner(ctx, conn) - defer func() { - // Map Upgrade() error to a possible context expiration error. That - // is, even if Upgrade() err is nil, context could be already - // expired and connection be "poisoned" by SetDeadline() call. - // In that case we must not return ctx.Err() error. - done(&err) - }() - } - - br, hs, err = d.Upgrade(conn, u) - - return -} - -var ( - // netEmptyDialer is a net.Dialer without options, used in Dialer.dial() if - // Dialer.NetDial is not provided. - netEmptyDialer net.Dialer - // tlsEmptyConfig is an empty tls.Config used as default one. - tlsEmptyConfig tls.Config -) - -func tlsDefaultConfig() *tls.Config { - return &tlsEmptyConfig -} - -func hostport(host string, defaultPort string) (hostname, addr string) { - var ( - colon = strings.LastIndexByte(host, ':') - bracket = strings.IndexByte(host, ']') - ) - if colon > bracket { - return host[:colon], host - } - return host, host + defaultPort -} - -func (d Dialer) dial(ctx context.Context, u *url.URL) (conn net.Conn, err error) { - dial := d.NetDial - if dial == nil { - dial = netEmptyDialer.DialContext - } - switch u.Scheme { - case "ws": - _, addr := hostport(u.Host, ":80") - conn, err = dial(ctx, "tcp", addr) - case "wss": - hostname, addr := hostport(u.Host, ":443") - conn, err = dial(ctx, "tcp", addr) - if err != nil { - return - } - tlsClient := d.TLSClient - if tlsClient == nil { - tlsClient = d.tlsClient - } - conn = tlsClient(conn, hostname) - default: - return nil, fmt.Errorf("unexpected websocket scheme: %q", u.Scheme) - } - if wrap := d.WrapConn; wrap != nil { - conn = wrap(conn) - } - return -} - -func (d Dialer) tlsClient(conn net.Conn, hostname string) net.Conn { - config := d.TLSConfig - if config == nil { - config = tlsDefaultConfig() - } - if config.ServerName == "" { - config = tlsCloneConfig(config) - config.ServerName = hostname - } - // Do not make conn.Handshake() here because downstairs we will prepare - // i/o on this conn with proper context's timeout handling. - return tls.Client(conn, config) -} - -var ( - // This variables are set like in net/net.go. - // noDeadline is just zero value for readability. - noDeadline = time.Time{} - // aLongTimeAgo is a non-zero time, far in the past, used for immediate - // cancelation of dials. - aLongTimeAgo = time.Unix(42, 0) -) - -// Upgrade writes an upgrade request to the given io.ReadWriter conn at given -// url u and reads a response from it. -// -// It is a caller responsibility to manage I/O deadlines on conn. -// -// It returns handshake info and some bytes which could be written by the peer -// right after response and be caught by us during buffered read. -func (d Dialer) Upgrade(conn io.ReadWriter, u *url.URL) (br *bufio.Reader, hs Handshake, err error) { - // headerSeen constants helps to report whether or not some header was seen - // during reading request bytes. - const ( - headerSeenUpgrade = 1 << iota - headerSeenConnection - headerSeenSecAccept - - // headerSeenAll is the value that we expect to receive at the end of - // headers read/parse loop. - headerSeenAll = 0 | - headerSeenUpgrade | - headerSeenConnection | - headerSeenSecAccept - ) - - br = pbufio.GetReader(conn, - nonZero(d.ReadBufferSize, DefaultClientReadBufferSize), - ) - bw := pbufio.GetWriter(conn, - nonZero(d.WriteBufferSize, DefaultClientWriteBufferSize), - ) - defer func() { - pbufio.PutWriter(bw) - if br.Buffered() == 0 || err != nil { - // Server does not wrote additional bytes to the connection or - // error occurred. That is, no reason to return buffer. - pbufio.PutReader(br) - br = nil - } - }() - - nonce := make([]byte, nonceSize) - initNonce(nonce) - - httpWriteUpgradeRequest(bw, u, nonce, d.Protocols, d.Extensions, d.Header) - if err = bw.Flush(); err != nil { - return - } - - // Read HTTP status line like "HTTP/1.1 101 Switching Protocols". - sl, err := readLine(br) - if err != nil { - return - } - // Begin validation of the response. - // See https://tools.ietf.org/html/rfc6455#section-4.2.2 - // Parse request line data like HTTP version, uri and method. - resp, err := httpParseResponseLine(sl) - if err != nil { - return - } - // Even if RFC says "1.1 or higher" without mentioning the part of the - // version, we apply it only to minor part. - if resp.major != 1 || resp.minor < 1 { - err = ErrHandshakeBadProtocol - return - } - if resp.status != 101 { - err = StatusError(resp.status) - if onStatusError := d.OnStatusError; onStatusError != nil { - // Invoke callback with multireader of status-line bytes br. - onStatusError(resp.status, resp.reason, - io.MultiReader( - bytes.NewReader(sl), - strings.NewReader(crlf), - br, - ), - ) - } - return - } - // If response status is 101 then we expect all technical headers to be - // valid. If not, then we stop processing response without giving user - // ability to read non-technical headers. That is, we do not distinguish - // technical errors (such as parsing error) and protocol errors. - var headerSeen byte - for { - line, e := readLine(br) - if e != nil { - err = e - return - } - if len(line) == 0 { - // Blank line, no more lines to read. - break - } - - k, v, ok := httpParseHeaderLine(line) - if !ok { - err = ErrMalformedResponse - return - } - - switch btsToString(k) { - case headerUpgradeCanonical: - headerSeen |= headerSeenUpgrade - if !bytes.Equal(v, specHeaderValueUpgrade) && !bytes.EqualFold(v, specHeaderValueUpgrade) { - err = ErrHandshakeBadUpgrade - return - } - - case headerConnectionCanonical: - headerSeen |= headerSeenConnection - // Note that as RFC6455 says: - // > A |Connection| header field with value "Upgrade". - // That is, in server side, "Connection" header could contain - // multiple token. But in response it must contains exactly one. - if !bytes.Equal(v, specHeaderValueConnection) && !bytes.EqualFold(v, specHeaderValueConnection) { - err = ErrHandshakeBadConnection - return - } - - case headerSecAcceptCanonical: - headerSeen |= headerSeenSecAccept - if !checkAcceptFromNonce(v, nonce) { - err = ErrHandshakeBadSecAccept - return - } - - case headerSecProtocolCanonical: - // RFC6455 1.3: - // "The server selects one or none of the acceptable protocols - // and echoes that value in its handshake to indicate that it has - // selected that protocol." - for _, want := range d.Protocols { - if string(v) == want { - hs.Protocol = want - break - } - } - if hs.Protocol == "" { - // Server echoed subprotocol that is not present in client - // requested protocols. - err = ErrHandshakeBadSubProtocol - return - } - - case headerSecExtensionsCanonical: - hs.Extensions, err = matchSelectedExtensions(v, d.Extensions, hs.Extensions) - if err != nil { - return - } - - default: - if onHeader := d.OnHeader; onHeader != nil { - if e := onHeader(k, v); e != nil { - err = e - return - } - } - } - } - if err == nil && headerSeen != headerSeenAll { - switch { - case headerSeen&headerSeenUpgrade == 0: - err = ErrHandshakeBadUpgrade - case headerSeen&headerSeenConnection == 0: - err = ErrHandshakeBadConnection - case headerSeen&headerSeenSecAccept == 0: - err = ErrHandshakeBadSecAccept - default: - panic("unknown headers state") - } - } - return -} - -// PutReader returns bufio.Reader instance to the inner reuse pool. -// It is useful in rare cases, when Dialer.Dial() returns non-nil buffer which -// contains unprocessed buffered data, that was sent by the server quickly -// right after handshake. -func PutReader(br *bufio.Reader) { - pbufio.PutReader(br) -} - -// StatusError contains an unexpected status-line code from the server. -type StatusError int - -func (s StatusError) Error() string { - return "unexpected HTTP response status: " + strconv.Itoa(int(s)) -} - -func isTimeoutError(err error) bool { - t, ok := err.(net.Error) - return ok && t.Timeout() -} - -func matchSelectedExtensions(selected []byte, wanted, received []httphead.Option) ([]httphead.Option, error) { - if len(selected) == 0 { - return received, nil - } - var ( - index int - option httphead.Option - err error - ) - index = -1 - match := func() (ok bool) { - for _, want := range wanted { - if option.Equal(want) { - // Check parsed extension to be present in client - // requested extensions. We move matched extension - // from client list to avoid allocation. - received = append(received, want) - return true - } - } - return false - } - ok := httphead.ScanOptions(selected, func(i int, name, attr, val []byte) httphead.Control { - if i != index { - // Met next option. - index = i - if i != 0 && !match() { - // Server returned non-requested extension. - err = ErrHandshakeBadExtensions - return httphead.ControlBreak - } - option = httphead.Option{Name: name} - } - if attr != nil { - option.Parameters.Set(attr, val) - } - return httphead.ControlContinue - }) - if !ok { - err = ErrMalformedResponse - return received, err - } - if !match() { - return received, ErrHandshakeBadExtensions - } - return received, err -} - -// setupContextDeadliner is a helper function that starts connection I/O -// interrupter goroutine. -// -// Started goroutine calls SetDeadline() with long time ago value when context -// become expired to make any I/O operations failed. It returns done function -// that stops started goroutine and maps error received from conn I/O methods -// to possible context expiration error. -// -// In concern with possible SetDeadline() call inside interrupter goroutine, -// caller passes pointer to its I/O error (even if it is nil) to done(&err). -// That is, even if I/O error is nil, context could be already expired and -// connection "poisoned" by SetDeadline() call. In that case done(&err) will -// store at *err ctx.Err() result. If err is caused not by timeout, it will -// leaved untouched. -func setupContextDeadliner(ctx context.Context, conn net.Conn) (done func(*error)) { - var ( - quit = make(chan struct{}) - interrupt = make(chan error, 1) - ) - go func() { - select { - case <-quit: - interrupt <- nil - case <-ctx.Done(): - // Cancel i/o immediately. - conn.SetDeadline(aLongTimeAgo) - interrupt <- ctx.Err() - } - }() - return func(err *error) { - close(quit) - // If ctx.Err() is non-nil and the original err is net.Error with - // Timeout() == true, then it means that I/O was canceled by us by - // SetDeadline(aLongTimeAgo) call, or by somebody else previously - // by conn.SetDeadline(x). - // - // Even on race condition when both deadlines are expired - // (SetDeadline() made not by us and context's), we prefer ctx.Err() to - // be returned. - if ctxErr := <-interrupt; ctxErr != nil && (*err == nil || isTimeoutError(*err)) { - *err = ctxErr - } - } -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/dialer_tls_go17.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/dialer_tls_go17.go deleted file mode 100644 index b606e0ad909..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/dialer_tls_go17.go +++ /dev/null @@ -1,35 +0,0 @@ -// +build !go1.8 - -package ws - -import "crypto/tls" - -func tlsCloneConfig(c *tls.Config) *tls.Config { - // NOTE: we copying SessionTicketsDisabled and SessionTicketKey here - // without calling inner c.initOnceServer somehow because we only could get - // here from the ws.Dialer code, which is obviously a client and makes - // tls.Client() when it gets new net.Conn. - return &tls.Config{ - Rand: c.Rand, - Time: c.Time, - Certificates: c.Certificates, - NameToCertificate: c.NameToCertificate, - GetCertificate: c.GetCertificate, - RootCAs: c.RootCAs, - NextProtos: c.NextProtos, - ServerName: c.ServerName, - ClientAuth: c.ClientAuth, - ClientCAs: c.ClientCAs, - InsecureSkipVerify: c.InsecureSkipVerify, - CipherSuites: c.CipherSuites, - PreferServerCipherSuites: c.PreferServerCipherSuites, - SessionTicketsDisabled: c.SessionTicketsDisabled, - SessionTicketKey: c.SessionTicketKey, - ClientSessionCache: c.ClientSessionCache, - MinVersion: c.MinVersion, - MaxVersion: c.MaxVersion, - CurvePreferences: c.CurvePreferences, - DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled, - Renegotiation: c.Renegotiation, - } -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/dialer_tls_go18.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/dialer_tls_go18.go deleted file mode 100644 index a6704d5173a..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/dialer_tls_go18.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build go1.8 - -package ws - -import "crypto/tls" - -func tlsCloneConfig(c *tls.Config) *tls.Config { - return c.Clone() -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/doc.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/doc.go deleted file mode 100644 index c9d5791570c..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/doc.go +++ /dev/null @@ -1,81 +0,0 @@ -/* -Package ws implements a client and server for the WebSocket protocol as -specified in RFC 6455. - -The main purpose of this package is to provide simple low-level API for -efficient work with protocol. - -Overview. - -Upgrade to WebSocket (or WebSocket handshake) can be done in two ways. - -The first way is to use `net/http` server: - - http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - conn, _, _, err := ws.UpgradeHTTP(r, w) - }) - -The second and much more efficient way is so-called "zero-copy upgrade". It -avoids redundant allocations and copying of not used headers or other request -data. User decides by himself which data should be copied. - - ln, err := net.Listen("tcp", ":8080") - if err != nil { - // handle error - } - - conn, err := ln.Accept() - if err != nil { - // handle error - } - - handshake, err := ws.Upgrade(conn) - if err != nil { - // handle error - } - -For customization details see `ws.Upgrader` documentation. - -After WebSocket handshake you can work with connection in multiple ways. -That is, `ws` does not force the only one way of how to work with WebSocket: - - header, err := ws.ReadHeader(conn) - if err != nil { - // handle err - } - - buf := make([]byte, header.Length) - _, err := io.ReadFull(conn, buf) - if err != nil { - // handle err - } - - resp := ws.NewBinaryFrame([]byte("hello, world!")) - if err := ws.WriteFrame(conn, frame); err != nil { - // handle err - } - -As you can see, it stream friendly: - - const N = 42 - - ws.WriteHeader(ws.Header{ - Fin: true, - Length: N, - OpCode: ws.OpBinary, - }) - - io.CopyN(conn, rand.Reader, N) - -Or: - - header, err := ws.ReadHeader(conn) - if err != nil { - // handle err - } - - io.CopyN(ioutil.Discard, conn, header.Length) - -For more info see the documentation. -*/ -package ws diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/errors.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/errors.go deleted file mode 100644 index 48fce3b72c1..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/errors.go +++ /dev/null @@ -1,54 +0,0 @@ -package ws - -// RejectOption represents an option used to control the way connection is -// rejected. -type RejectOption func(*rejectConnectionError) - -// RejectionReason returns an option that makes connection to be rejected with -// given reason. -func RejectionReason(reason string) RejectOption { - return func(err *rejectConnectionError) { - err.reason = reason - } -} - -// RejectionStatus returns an option that makes connection to be rejected with -// given HTTP status code. -func RejectionStatus(code int) RejectOption { - return func(err *rejectConnectionError) { - err.code = code - } -} - -// RejectionHeader returns an option that makes connection to be rejected with -// given HTTP headers. -func RejectionHeader(h HandshakeHeader) RejectOption { - return func(err *rejectConnectionError) { - err.header = h - } -} - -// RejectConnectionError constructs an error that could be used to control the way -// handshake is rejected by Upgrader. -func RejectConnectionError(options ...RejectOption) error { - err := new(rejectConnectionError) - for _, opt := range options { - opt(err) - } - return err -} - -// rejectConnectionError represents a rejection of upgrade error. -// -// It can be returned by Upgrader's On* hooks to control the way WebSocket -// handshake is rejected. -type rejectConnectionError struct { - reason string - code int - header HandshakeHeader -} - -// Error implements error interface. -func (r *rejectConnectionError) Error() string { - return r.reason -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/frame.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/frame.go deleted file mode 100644 index f157ee3e9ff..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/frame.go +++ /dev/null @@ -1,389 +0,0 @@ -package ws - -import ( - "bytes" - "encoding/binary" - "math/rand" -) - -// Constants defined by specification. -const ( - // All control frames MUST have a payload length of 125 bytes or less and MUST NOT be fragmented. - MaxControlFramePayloadSize = 125 -) - -// OpCode represents operation code. -type OpCode byte - -// Operation codes defined by specification. -// See https://tools.ietf.org/html/rfc6455#section-5.2 -const ( - OpContinuation OpCode = 0x0 - OpText OpCode = 0x1 - OpBinary OpCode = 0x2 - OpClose OpCode = 0x8 - OpPing OpCode = 0x9 - OpPong OpCode = 0xa -) - -// IsControl checks whether the c is control operation code. -// See https://tools.ietf.org/html/rfc6455#section-5.5 -func (c OpCode) IsControl() bool { - // RFC6455: Control frames are identified by opcodes where - // the most significant bit of the opcode is 1. - // - // Note that OpCode is only 4 bit length. - return c&0x8 != 0 -} - -// IsData checks whether the c is data operation code. -// See https://tools.ietf.org/html/rfc6455#section-5.6 -func (c OpCode) IsData() bool { - // RFC6455: Data frames (e.g., non-control frames) are identified by opcodes - // where the most significant bit of the opcode is 0. - // - // Note that OpCode is only 4 bit length. - return c&0x8 == 0 -} - -// IsReserved checks whether the c is reserved operation code. -// See https://tools.ietf.org/html/rfc6455#section-5.2 -func (c OpCode) IsReserved() bool { - // RFC6455: - // %x3-7 are reserved for further non-control frames - // %xB-F are reserved for further control frames - return (0x3 <= c && c <= 0x7) || (0xb <= c && c <= 0xf) -} - -// StatusCode represents the encoded reason for closure of websocket connection. -// -// There are few helper methods on StatusCode that helps to define a range in -// which given code is lay in. accordingly to ranges defined in specification. -// -// See https://tools.ietf.org/html/rfc6455#section-7.4 -type StatusCode uint16 - -// StatusCodeRange describes range of StatusCode values. -type StatusCodeRange struct { - Min, Max StatusCode -} - -// Status code ranges defined by specification. -// See https://tools.ietf.org/html/rfc6455#section-7.4.2 -var ( - StatusRangeNotInUse = StatusCodeRange{0, 999} - StatusRangeProtocol = StatusCodeRange{1000, 2999} - StatusRangeApplication = StatusCodeRange{3000, 3999} - StatusRangePrivate = StatusCodeRange{4000, 4999} -) - -// Status codes defined by specification. -// See https://tools.ietf.org/html/rfc6455#section-7.4.1 -const ( - StatusNormalClosure StatusCode = 1000 - StatusGoingAway StatusCode = 1001 - StatusProtocolError StatusCode = 1002 - StatusUnsupportedData StatusCode = 1003 - StatusNoMeaningYet StatusCode = 1004 - StatusInvalidFramePayloadData StatusCode = 1007 - StatusPolicyViolation StatusCode = 1008 - StatusMessageTooBig StatusCode = 1009 - StatusMandatoryExt StatusCode = 1010 - StatusInternalServerError StatusCode = 1011 - StatusTLSHandshake StatusCode = 1015 - - // StatusAbnormalClosure is a special code designated for use in - // applications. - StatusAbnormalClosure StatusCode = 1006 - - // StatusNoStatusRcvd is a special code designated for use in applications. - StatusNoStatusRcvd StatusCode = 1005 -) - -// In reports whether the code is defined in given range. -func (s StatusCode) In(r StatusCodeRange) bool { - return r.Min <= s && s <= r.Max -} - -// Empty reports whether the code is empty. -// Empty code has no any meaning neither app level codes nor other. -// This method is useful just to check that code is golang default value 0. -func (s StatusCode) Empty() bool { - return s == 0 -} - -// IsNotUsed reports whether the code is predefined in not used range. -func (s StatusCode) IsNotUsed() bool { - return s.In(StatusRangeNotInUse) -} - -// IsApplicationSpec reports whether the code should be defined by -// application, framework or libraries specification. -func (s StatusCode) IsApplicationSpec() bool { - return s.In(StatusRangeApplication) -} - -// IsPrivateSpec reports whether the code should be defined privately. -func (s StatusCode) IsPrivateSpec() bool { - return s.In(StatusRangePrivate) -} - -// IsProtocolSpec reports whether the code should be defined by protocol specification. -func (s StatusCode) IsProtocolSpec() bool { - return s.In(StatusRangeProtocol) -} - -// IsProtocolDefined reports whether the code is already defined by protocol specification. -func (s StatusCode) IsProtocolDefined() bool { - switch s { - case StatusNormalClosure, - StatusGoingAway, - StatusProtocolError, - StatusUnsupportedData, - StatusInvalidFramePayloadData, - StatusPolicyViolation, - StatusMessageTooBig, - StatusMandatoryExt, - StatusInternalServerError, - StatusNoStatusRcvd, - StatusAbnormalClosure, - StatusTLSHandshake: - return true - } - return false -} - -// IsProtocolReserved reports whether the code is defined by protocol specification -// to be reserved only for application usage purpose. -func (s StatusCode) IsProtocolReserved() bool { - switch s { - // [RFC6455]: {1005,1006,1015} is a reserved value and MUST NOT be set as a status code in a - // Close control frame by an endpoint. - case StatusNoStatusRcvd, StatusAbnormalClosure, StatusTLSHandshake: - return true - default: - return false - } -} - -// Compiled control frames for common use cases. -// For construct-serialize optimizations. -var ( - CompiledPing = MustCompileFrame(NewPingFrame(nil)) - CompiledPong = MustCompileFrame(NewPongFrame(nil)) - CompiledClose = MustCompileFrame(NewCloseFrame(nil)) - - CompiledCloseNormalClosure = MustCompileFrame(closeFrameNormalClosure) - CompiledCloseGoingAway = MustCompileFrame(closeFrameGoingAway) - CompiledCloseProtocolError = MustCompileFrame(closeFrameProtocolError) - CompiledCloseUnsupportedData = MustCompileFrame(closeFrameUnsupportedData) - CompiledCloseNoMeaningYet = MustCompileFrame(closeFrameNoMeaningYet) - CompiledCloseInvalidFramePayloadData = MustCompileFrame(closeFrameInvalidFramePayloadData) - CompiledClosePolicyViolation = MustCompileFrame(closeFramePolicyViolation) - CompiledCloseMessageTooBig = MustCompileFrame(closeFrameMessageTooBig) - CompiledCloseMandatoryExt = MustCompileFrame(closeFrameMandatoryExt) - CompiledCloseInternalServerError = MustCompileFrame(closeFrameInternalServerError) - CompiledCloseTLSHandshake = MustCompileFrame(closeFrameTLSHandshake) -) - -// Header represents websocket frame header. -// See https://tools.ietf.org/html/rfc6455#section-5.2 -type Header struct { - Fin bool - Rsv byte - OpCode OpCode - Masked bool - Mask [4]byte - Length int64 -} - -// Rsv1 reports whether the header has first rsv bit set. -func (h Header) Rsv1() bool { return h.Rsv&bit5 != 0 } - -// Rsv2 reports whether the header has second rsv bit set. -func (h Header) Rsv2() bool { return h.Rsv&bit6 != 0 } - -// Rsv3 reports whether the header has third rsv bit set. -func (h Header) Rsv3() bool { return h.Rsv&bit7 != 0 } - -// Frame represents websocket frame. -// See https://tools.ietf.org/html/rfc6455#section-5.2 -type Frame struct { - Header Header - Payload []byte -} - -// NewFrame creates frame with given operation code, -// flag of completeness and payload bytes. -func NewFrame(op OpCode, fin bool, p []byte) Frame { - return Frame{ - Header: Header{ - Fin: fin, - OpCode: op, - Length: int64(len(p)), - }, - Payload: p, - } -} - -// NewTextFrame creates text frame with p as payload. -// Note that p is not copied. -func NewTextFrame(p []byte) Frame { - return NewFrame(OpText, true, p) -} - -// NewBinaryFrame creates binary frame with p as payload. -// Note that p is not copied. -func NewBinaryFrame(p []byte) Frame { - return NewFrame(OpBinary, true, p) -} - -// NewPingFrame creates ping frame with p as payload. -// Note that p is not copied. -// Note that p must have length of MaxControlFramePayloadSize bytes or less due -// to RFC. -func NewPingFrame(p []byte) Frame { - return NewFrame(OpPing, true, p) -} - -// NewPongFrame creates pong frame with p as payload. -// Note that p is not copied. -// Note that p must have length of MaxControlFramePayloadSize bytes or less due -// to RFC. -func NewPongFrame(p []byte) Frame { - return NewFrame(OpPong, true, p) -} - -// NewCloseFrame creates close frame with given close body. -// Note that p is not copied. -// Note that p must have length of MaxControlFramePayloadSize bytes or less due -// to RFC. -func NewCloseFrame(p []byte) Frame { - return NewFrame(OpClose, true, p) -} - -// NewCloseFrameBody encodes a closure code and a reason into a binary -// representation. -// -// It returns slice which is at most MaxControlFramePayloadSize bytes length. -// If the reason is too big it will be cropped to fit the limit defined by the -// spec. -// -// See https://tools.ietf.org/html/rfc6455#section-5.5 -func NewCloseFrameBody(code StatusCode, reason string) []byte { - n := min(2+len(reason), MaxControlFramePayloadSize) - p := make([]byte, n) - - crop := min(MaxControlFramePayloadSize-2, len(reason)) - PutCloseFrameBody(p, code, reason[:crop]) - - return p -} - -// PutCloseFrameBody encodes code and reason into buf. -// -// It will panic if the buffer is too small to accommodate a code or a reason. -// -// PutCloseFrameBody does not check buffer to be RFC compliant, but note that -// by RFC it must be at most MaxControlFramePayloadSize. -func PutCloseFrameBody(p []byte, code StatusCode, reason string) { - _ = p[1+len(reason)] - binary.BigEndian.PutUint16(p, uint16(code)) - copy(p[2:], reason) -} - -// MaskFrame masks frame and returns frame with masked payload and Mask header's field set. -// Note that it copies f payload to prevent collisions. -// For less allocations you could use MaskFrameInPlace or construct frame manually. -func MaskFrame(f Frame) Frame { - return MaskFrameWith(f, NewMask()) -} - -// MaskFrameWith masks frame with given mask and returns frame -// with masked payload and Mask header's field set. -// Note that it copies f payload to prevent collisions. -// For less allocations you could use MaskFrameInPlaceWith or construct frame manually. -func MaskFrameWith(f Frame, mask [4]byte) Frame { - // TODO(gobwas): check CopyCipher ws copy() Cipher(). - p := make([]byte, len(f.Payload)) - copy(p, f.Payload) - f.Payload = p - return MaskFrameInPlaceWith(f, mask) -} - -// MaskFrameInPlace masks frame and returns frame with masked payload and Mask -// header's field set. -// Note that it applies xor cipher to f.Payload without copying, that is, it -// modifies f.Payload inplace. -func MaskFrameInPlace(f Frame) Frame { - return MaskFrameInPlaceWith(f, NewMask()) -} - -// MaskFrameInPlaceWith masks frame with given mask and returns frame -// with masked payload and Mask header's field set. -// Note that it applies xor cipher to f.Payload without copying, that is, it -// modifies f.Payload inplace. -func MaskFrameInPlaceWith(f Frame, m [4]byte) Frame { - f.Header.Masked = true - f.Header.Mask = m - Cipher(f.Payload, m, 0) - return f -} - -// NewMask creates new random mask. -func NewMask() (ret [4]byte) { - binary.BigEndian.PutUint32(ret[:], rand.Uint32()) - return -} - -// CompileFrame returns byte representation of given frame. -// In terms of memory consumption it is useful to precompile static frames -// which are often used. -func CompileFrame(f Frame) (bts []byte, err error) { - buf := bytes.NewBuffer(make([]byte, 0, 16)) - err = WriteFrame(buf, f) - bts = buf.Bytes() - return -} - -// MustCompileFrame is like CompileFrame but panics if frame can not be -// encoded. -func MustCompileFrame(f Frame) []byte { - bts, err := CompileFrame(f) - if err != nil { - panic(err) - } - return bts -} - -// Rsv creates rsv byte representation. -func Rsv(r1, r2, r3 bool) (rsv byte) { - if r1 { - rsv |= bit5 - } - if r2 { - rsv |= bit6 - } - if r3 { - rsv |= bit7 - } - return rsv -} - -func makeCloseFrame(code StatusCode) Frame { - return NewCloseFrame(NewCloseFrameBody(code, "")) -} - -var ( - closeFrameNormalClosure = makeCloseFrame(StatusNormalClosure) - closeFrameGoingAway = makeCloseFrame(StatusGoingAway) - closeFrameProtocolError = makeCloseFrame(StatusProtocolError) - closeFrameUnsupportedData = makeCloseFrame(StatusUnsupportedData) - closeFrameNoMeaningYet = makeCloseFrame(StatusNoMeaningYet) - closeFrameInvalidFramePayloadData = makeCloseFrame(StatusInvalidFramePayloadData) - closeFramePolicyViolation = makeCloseFrame(StatusPolicyViolation) - closeFrameMessageTooBig = makeCloseFrame(StatusMessageTooBig) - closeFrameMandatoryExt = makeCloseFrame(StatusMandatoryExt) - closeFrameInternalServerError = makeCloseFrame(StatusInternalServerError) - closeFrameTLSHandshake = makeCloseFrame(StatusTLSHandshake) -) diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/http.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/http.go deleted file mode 100644 index e18df441b47..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/http.go +++ /dev/null @@ -1,468 +0,0 @@ -package ws - -import ( - "bufio" - "bytes" - "io" - "net/http" - "net/textproto" - "net/url" - "strconv" - - "github.com/gobwas/httphead" -) - -const ( - crlf = "\r\n" - colonAndSpace = ": " - commaAndSpace = ", " -) - -const ( - textHeadUpgrade = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\n" -) - -var ( - textHeadBadRequest = statusText(http.StatusBadRequest) - textHeadInternalServerError = statusText(http.StatusInternalServerError) - textHeadUpgradeRequired = statusText(http.StatusUpgradeRequired) - - textTailErrHandshakeBadProtocol = errorText(ErrHandshakeBadProtocol) - textTailErrHandshakeBadMethod = errorText(ErrHandshakeBadMethod) - textTailErrHandshakeBadHost = errorText(ErrHandshakeBadHost) - textTailErrHandshakeBadUpgrade = errorText(ErrHandshakeBadUpgrade) - textTailErrHandshakeBadConnection = errorText(ErrHandshakeBadConnection) - textTailErrHandshakeBadSecAccept = errorText(ErrHandshakeBadSecAccept) - textTailErrHandshakeBadSecKey = errorText(ErrHandshakeBadSecKey) - textTailErrHandshakeBadSecVersion = errorText(ErrHandshakeBadSecVersion) - textTailErrUpgradeRequired = errorText(ErrHandshakeUpgradeRequired) -) - -var ( - headerHost = "Host" - headerUpgrade = "Upgrade" - headerConnection = "Connection" - headerSecVersion = "Sec-WebSocket-Version" - headerSecProtocol = "Sec-WebSocket-Protocol" - headerSecExtensions = "Sec-WebSocket-Extensions" - headerSecKey = "Sec-WebSocket-Key" - headerSecAccept = "Sec-WebSocket-Accept" - - headerHostCanonical = textproto.CanonicalMIMEHeaderKey(headerHost) - headerUpgradeCanonical = textproto.CanonicalMIMEHeaderKey(headerUpgrade) - headerConnectionCanonical = textproto.CanonicalMIMEHeaderKey(headerConnection) - headerSecVersionCanonical = textproto.CanonicalMIMEHeaderKey(headerSecVersion) - headerSecProtocolCanonical = textproto.CanonicalMIMEHeaderKey(headerSecProtocol) - headerSecExtensionsCanonical = textproto.CanonicalMIMEHeaderKey(headerSecExtensions) - headerSecKeyCanonical = textproto.CanonicalMIMEHeaderKey(headerSecKey) - headerSecAcceptCanonical = textproto.CanonicalMIMEHeaderKey(headerSecAccept) -) - -var ( - specHeaderValueUpgrade = []byte("websocket") - specHeaderValueConnection = []byte("Upgrade") - specHeaderValueConnectionLower = []byte("upgrade") - specHeaderValueSecVersion = []byte("13") -) - -var ( - httpVersion1_0 = []byte("HTTP/1.0") - httpVersion1_1 = []byte("HTTP/1.1") - httpVersionPrefix = []byte("HTTP/") -) - -type httpRequestLine struct { - method, uri []byte - major, minor int -} - -type httpResponseLine struct { - major, minor int - status int - reason []byte -} - -// httpParseRequestLine parses http request line like "GET / HTTP/1.0". -func httpParseRequestLine(line []byte) (req httpRequestLine, err error) { - var proto []byte - req.method, req.uri, proto = bsplit3(line, ' ') - - var ok bool - req.major, req.minor, ok = httpParseVersion(proto) - if !ok { - err = ErrMalformedRequest - return - } - - return -} - -func httpParseResponseLine(line []byte) (resp httpResponseLine, err error) { - var ( - proto []byte - status []byte - ) - proto, status, resp.reason = bsplit3(line, ' ') - - var ok bool - resp.major, resp.minor, ok = httpParseVersion(proto) - if !ok { - return resp, ErrMalformedResponse - } - - var convErr error - resp.status, convErr = asciiToInt(status) - if convErr != nil { - return resp, ErrMalformedResponse - } - - return resp, nil -} - -// httpParseVersion parses major and minor version of HTTP protocol. It returns -// parsed values and true if parse is ok. -func httpParseVersion(bts []byte) (major, minor int, ok bool) { - switch { - case bytes.Equal(bts, httpVersion1_0): - return 1, 0, true - case bytes.Equal(bts, httpVersion1_1): - return 1, 1, true - case len(bts) < 8: - return - case !bytes.Equal(bts[:5], httpVersionPrefix): - return - } - - bts = bts[5:] - - dot := bytes.IndexByte(bts, '.') - if dot == -1 { - return - } - var err error - major, err = asciiToInt(bts[:dot]) - if err != nil { - return - } - minor, err = asciiToInt(bts[dot+1:]) - if err != nil { - return - } - - return major, minor, true -} - -// httpParseHeaderLine parses HTTP header as key-value pair. It returns parsed -// values and true if parse is ok. -func httpParseHeaderLine(line []byte) (k, v []byte, ok bool) { - colon := bytes.IndexByte(line, ':') - if colon == -1 { - return - } - - k = btrim(line[:colon]) - // TODO(gobwas): maybe use just lower here? - canonicalizeHeaderKey(k) - - v = btrim(line[colon+1:]) - - return k, v, true -} - -// httpGetHeader is the same as textproto.MIMEHeader.Get, except the thing, -// that key is already canonical. This helps to increase performance. -func httpGetHeader(h http.Header, key string) string { - if h == nil { - return "" - } - v := h[key] - if len(v) == 0 { - return "" - } - return v[0] -} - -// The request MAY include a header field with the name -// |Sec-WebSocket-Protocol|. If present, this value indicates one or more -// comma-separated subprotocol the client wishes to speak, ordered by -// preference. The elements that comprise this value MUST be non-empty strings -// with characters in the range U+0021 to U+007E not including separator -// characters as defined in [RFC2616] and MUST all be unique strings. The ABNF -// for the value of this header field is 1#token, where the definitions of -// constructs and rules are as given in [RFC2616]. -func strSelectProtocol(h string, check func(string) bool) (ret string, ok bool) { - ok = httphead.ScanTokens(strToBytes(h), func(v []byte) bool { - if check(btsToString(v)) { - ret = string(v) - return false - } - return true - }) - return -} -func btsSelectProtocol(h []byte, check func([]byte) bool) (ret string, ok bool) { - var selected []byte - ok = httphead.ScanTokens(h, func(v []byte) bool { - if check(v) { - selected = v - return false - } - return true - }) - if ok && selected != nil { - return string(selected), true - } - return -} - -func strSelectExtensions(h string, selected []httphead.Option, check func(httphead.Option) bool) ([]httphead.Option, bool) { - return btsSelectExtensions(strToBytes(h), selected, check) -} - -func btsSelectExtensions(h []byte, selected []httphead.Option, check func(httphead.Option) bool) ([]httphead.Option, bool) { - s := httphead.OptionSelector{ - Flags: httphead.SelectUnique | httphead.SelectCopy, - Check: check, - } - return s.Select(h, selected) -} - -func httpWriteHeader(bw *bufio.Writer, key, value string) { - httpWriteHeaderKey(bw, key) - bw.WriteString(value) - bw.WriteString(crlf) -} - -func httpWriteHeaderBts(bw *bufio.Writer, key string, value []byte) { - httpWriteHeaderKey(bw, key) - bw.Write(value) - bw.WriteString(crlf) -} - -func httpWriteHeaderKey(bw *bufio.Writer, key string) { - bw.WriteString(key) - bw.WriteString(colonAndSpace) -} - -func httpWriteUpgradeRequest( - bw *bufio.Writer, - u *url.URL, - nonce []byte, - protocols []string, - extensions []httphead.Option, - header HandshakeHeader, -) { - bw.WriteString("GET ") - bw.WriteString(u.RequestURI()) - bw.WriteString(" HTTP/1.1\r\n") - - httpWriteHeader(bw, headerHost, u.Host) - - httpWriteHeaderBts(bw, headerUpgrade, specHeaderValueUpgrade) - httpWriteHeaderBts(bw, headerConnection, specHeaderValueConnection) - httpWriteHeaderBts(bw, headerSecVersion, specHeaderValueSecVersion) - - // NOTE: write nonce bytes as a string to prevent heap allocation – - // WriteString() copy given string into its inner buffer, unlike Write() - // which may write p directly to the underlying io.Writer – which in turn - // will lead to p escape. - httpWriteHeader(bw, headerSecKey, btsToString(nonce)) - - if len(protocols) > 0 { - httpWriteHeaderKey(bw, headerSecProtocol) - for i, p := range protocols { - if i > 0 { - bw.WriteString(commaAndSpace) - } - bw.WriteString(p) - } - bw.WriteString(crlf) - } - - if len(extensions) > 0 { - httpWriteHeaderKey(bw, headerSecExtensions) - httphead.WriteOptions(bw, extensions) - bw.WriteString(crlf) - } - - if header != nil { - header.WriteTo(bw) - } - - bw.WriteString(crlf) -} - -func httpWriteResponseUpgrade(bw *bufio.Writer, nonce []byte, hs Handshake, header HandshakeHeaderFunc) { - bw.WriteString(textHeadUpgrade) - - httpWriteHeaderKey(bw, headerSecAccept) - writeAccept(bw, nonce) - bw.WriteString(crlf) - - if hs.Protocol != "" { - httpWriteHeader(bw, headerSecProtocol, hs.Protocol) - } - if len(hs.Extensions) > 0 { - httpWriteHeaderKey(bw, headerSecExtensions) - httphead.WriteOptions(bw, hs.Extensions) - bw.WriteString(crlf) - } - if header != nil { - header(bw) - } - - bw.WriteString(crlf) -} - -func httpWriteResponseError(bw *bufio.Writer, err error, code int, header HandshakeHeaderFunc) { - switch code { - case http.StatusBadRequest: - bw.WriteString(textHeadBadRequest) - case http.StatusInternalServerError: - bw.WriteString(textHeadInternalServerError) - case http.StatusUpgradeRequired: - bw.WriteString(textHeadUpgradeRequired) - default: - writeStatusText(bw, code) - } - - // Write custom headers. - if header != nil { - header(bw) - } - - switch err { - case ErrHandshakeBadProtocol: - bw.WriteString(textTailErrHandshakeBadProtocol) - case ErrHandshakeBadMethod: - bw.WriteString(textTailErrHandshakeBadMethod) - case ErrHandshakeBadHost: - bw.WriteString(textTailErrHandshakeBadHost) - case ErrHandshakeBadUpgrade: - bw.WriteString(textTailErrHandshakeBadUpgrade) - case ErrHandshakeBadConnection: - bw.WriteString(textTailErrHandshakeBadConnection) - case ErrHandshakeBadSecAccept: - bw.WriteString(textTailErrHandshakeBadSecAccept) - case ErrHandshakeBadSecKey: - bw.WriteString(textTailErrHandshakeBadSecKey) - case ErrHandshakeBadSecVersion: - bw.WriteString(textTailErrHandshakeBadSecVersion) - case ErrHandshakeUpgradeRequired: - bw.WriteString(textTailErrUpgradeRequired) - case nil: - bw.WriteString(crlf) - default: - writeErrorText(bw, err) - } -} - -func writeStatusText(bw *bufio.Writer, code int) { - bw.WriteString("HTTP/1.1 ") - bw.WriteString(strconv.Itoa(code)) - bw.WriteByte(' ') - bw.WriteString(http.StatusText(code)) - bw.WriteString(crlf) - bw.WriteString("Content-Type: text/plain; charset=utf-8") - bw.WriteString(crlf) -} - -func writeErrorText(bw *bufio.Writer, err error) { - body := err.Error() - bw.WriteString("Content-Length: ") - bw.WriteString(strconv.Itoa(len(body))) - bw.WriteString(crlf) - bw.WriteString(crlf) - bw.WriteString(body) -} - -// httpError is like the http.Error with WebSocket context exception. -func httpError(w http.ResponseWriter, body string, code int) { - w.Header().Set("Content-Type", "text/plain; charset=utf-8") - w.Header().Set("Content-Length", strconv.Itoa(len(body))) - w.WriteHeader(code) - w.Write([]byte(body)) -} - -// statusText is a non-performant status text generator. -// NOTE: Used only to generate constants. -func statusText(code int) string { - var buf bytes.Buffer - bw := bufio.NewWriter(&buf) - writeStatusText(bw, code) - bw.Flush() - return buf.String() -} - -// errorText is a non-performant error text generator. -// NOTE: Used only to generate constants. -func errorText(err error) string { - var buf bytes.Buffer - bw := bufio.NewWriter(&buf) - writeErrorText(bw, err) - bw.Flush() - return buf.String() -} - -// HandshakeHeader is the interface that writes both upgrade request or -// response headers into a given io.Writer. -type HandshakeHeader interface { - io.WriterTo -} - -// HandshakeHeaderString is an adapter to allow the use of headers represented -// by ordinary string as HandshakeHeader. -type HandshakeHeaderString string - -// WriteTo implements HandshakeHeader (and io.WriterTo) interface. -func (s HandshakeHeaderString) WriteTo(w io.Writer) (int64, error) { - n, err := io.WriteString(w, string(s)) - return int64(n), err -} - -// HandshakeHeaderBytes is an adapter to allow the use of headers represented -// by ordinary slice of bytes as HandshakeHeader. -type HandshakeHeaderBytes []byte - -// WriteTo implements HandshakeHeader (and io.WriterTo) interface. -func (b HandshakeHeaderBytes) WriteTo(w io.Writer) (int64, error) { - n, err := w.Write(b) - return int64(n), err -} - -// HandshakeHeaderFunc is an adapter to allow the use of headers represented by -// ordinary function as HandshakeHeader. -type HandshakeHeaderFunc func(io.Writer) (int64, error) - -// WriteTo implements HandshakeHeader (and io.WriterTo) interface. -func (f HandshakeHeaderFunc) WriteTo(w io.Writer) (int64, error) { - return f(w) -} - -// HandshakeHeaderHTTP is an adapter to allow the use of http.Header as -// HandshakeHeader. -type HandshakeHeaderHTTP http.Header - -// WriteTo implements HandshakeHeader (and io.WriterTo) interface. -func (h HandshakeHeaderHTTP) WriteTo(w io.Writer) (int64, error) { - wr := writer{w: w} - err := http.Header(h).Write(&wr) - return wr.n, err -} - -type writer struct { - n int64 - w io.Writer -} - -func (w *writer) WriteString(s string) (int, error) { - n, err := io.WriteString(w.w, s) - w.n += int64(n) - return n, err -} - -func (w *writer) Write(p []byte) (int, error) { - n, err := w.w.Write(p) - w.n += int64(n) - return n, err -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/nonce.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/nonce.go deleted file mode 100644 index e694da7c308..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/nonce.go +++ /dev/null @@ -1,80 +0,0 @@ -package ws - -import ( - "bufio" - "bytes" - "crypto/sha1" - "encoding/base64" - "fmt" - "math/rand" -) - -const ( - // RFC6455: The value of this header field MUST be a nonce consisting of a - // randomly selected 16-byte value that has been base64-encoded (see - // Section 4 of [RFC4648]). The nonce MUST be selected randomly for each - // connection. - nonceKeySize = 16 - nonceSize = 24 // base64.StdEncoding.EncodedLen(nonceKeySize) - - // RFC6455: The value of this header field is constructed by concatenating - // /key/, defined above in step 4 in Section 4.2.2, with the string - // "258EAFA5- E914-47DA-95CA-C5AB0DC85B11", taking the SHA-1 hash of this - // concatenated value to obtain a 20-byte value and base64- encoding (see - // Section 4 of [RFC4648]) this 20-byte hash. - acceptSize = 28 // base64.StdEncoding.EncodedLen(sha1.Size) -) - -// initNonce fills given slice with random base64-encoded nonce bytes. -func initNonce(dst []byte) { - // NOTE: bts does not escape. - bts := make([]byte, nonceKeySize) - if _, err := rand.Read(bts); err != nil { - panic(fmt.Sprintf("rand read error: %s", err)) - } - base64.StdEncoding.Encode(dst, bts) -} - -// checkAcceptFromNonce reports whether given accept bytes are valid for given -// nonce bytes. -func checkAcceptFromNonce(accept, nonce []byte) bool { - if len(accept) != acceptSize { - return false - } - // NOTE: expect does not escape. - expect := make([]byte, acceptSize) - initAcceptFromNonce(expect, nonce) - return bytes.Equal(expect, accept) -} - -// initAcceptFromNonce fills given slice with accept bytes generated from given -// nonce bytes. Given buffer should be exactly acceptSize bytes. -func initAcceptFromNonce(accept, nonce []byte) { - const magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" - - if len(accept) != acceptSize { - panic("accept buffer is invalid") - } - if len(nonce) != nonceSize { - panic("nonce is invalid") - } - - p := make([]byte, nonceSize+len(magic)) - copy(p[:nonceSize], nonce) - copy(p[nonceSize:], magic) - - sum := sha1.Sum(p) - base64.StdEncoding.Encode(accept, sum[:]) - - return -} - -func writeAccept(bw *bufio.Writer, nonce []byte) (int, error) { - accept := make([]byte, acceptSize) - initAcceptFromNonce(accept, nonce) - // NOTE: write accept bytes as a string to prevent heap allocation – - // WriteString() copy given string into its inner buffer, unlike Write() - // which may write p directly to the underlying io.Writer – which in turn - // will lead to p escape. - return bw.WriteString(btsToString(accept)) -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/read.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/read.go deleted file mode 100644 index bc653e4690f..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/read.go +++ /dev/null @@ -1,147 +0,0 @@ -package ws - -import ( - "encoding/binary" - "fmt" - "io" -) - -// Errors used by frame reader. -var ( - ErrHeaderLengthMSB = fmt.Errorf("header error: the most significant bit must be 0") - ErrHeaderLengthUnexpected = fmt.Errorf("header error: unexpected payload length bits") -) - -// ReadHeader reads a frame header from r. -func ReadHeader(r io.Reader) (h Header, err error) { - // Make slice of bytes with capacity 12 that could hold any header. - // - // The maximum header size is 14, but due to the 2 hop reads, - // after first hop that reads first 2 constant bytes, we could reuse 2 bytes. - // So 14 - 2 = 12. - bts := make([]byte, 2, MaxHeaderSize-2) - - // Prepare to hold first 2 bytes to choose size of next read. - _, err = io.ReadFull(r, bts) - if err != nil { - return - } - - h.Fin = bts[0]&bit0 != 0 - h.Rsv = (bts[0] & 0x70) >> 4 - h.OpCode = OpCode(bts[0] & 0x0f) - - var extra int - - if bts[1]&bit0 != 0 { - h.Masked = true - extra += 4 - } - - length := bts[1] & 0x7f - switch { - case length < 126: - h.Length = int64(length) - - case length == 126: - extra += 2 - - case length == 127: - extra += 8 - - default: - err = ErrHeaderLengthUnexpected - return - } - - if extra == 0 { - return - } - - // Increase len of bts to extra bytes need to read. - // Overwrite first 2 bytes that was read before. - bts = bts[:extra] - _, err = io.ReadFull(r, bts) - if err != nil { - return - } - - switch { - case length == 126: - h.Length = int64(binary.BigEndian.Uint16(bts[:2])) - bts = bts[2:] - - case length == 127: - if bts[0]&0x80 != 0 { - err = ErrHeaderLengthMSB - return - } - h.Length = int64(binary.BigEndian.Uint64(bts[:8])) - bts = bts[8:] - } - - if h.Masked { - copy(h.Mask[:], bts) - } - - return -} - -// ReadFrame reads a frame from r. -// It is not designed for high optimized use case cause it makes allocation -// for frame.Header.Length size inside to read frame payload into. -// -// Note that ReadFrame does not unmask payload. -func ReadFrame(r io.Reader) (f Frame, err error) { - f.Header, err = ReadHeader(r) - if err != nil { - return - } - - if f.Header.Length > 0 { - // int(f.Header.Length) is safe here cause we have - // checked it for overflow above in ReadHeader. - f.Payload = make([]byte, int(f.Header.Length)) - _, err = io.ReadFull(r, f.Payload) - } - - return -} - -// MustReadFrame is like ReadFrame but panics if frame can not be read. -func MustReadFrame(r io.Reader) Frame { - f, err := ReadFrame(r) - if err != nil { - panic(err) - } - return f -} - -// ParseCloseFrameData parses close frame status code and closure reason if any provided. -// If there is no status code in the payload -// the empty status code is returned (code.Empty()) with empty string as a reason. -func ParseCloseFrameData(payload []byte) (code StatusCode, reason string) { - if len(payload) < 2 { - // We returning empty StatusCode here, preventing the situation - // when endpoint really sent code 1005 and we should return ProtocolError on that. - // - // In other words, we ignoring this rule [RFC6455:7.1.5]: - // If this Close control frame contains no status code, _The WebSocket - // Connection Close Code_ is considered to be 1005. - return - } - code = StatusCode(binary.BigEndian.Uint16(payload)) - reason = string(payload[2:]) - return -} - -// ParseCloseFrameDataUnsafe is like ParseCloseFrameData except the thing -// that it does not copies payload bytes into reason, but prepares unsafe cast. -func ParseCloseFrameDataUnsafe(payload []byte) (code StatusCode, reason string) { - if len(payload) < 2 { - return - } - code = StatusCode(binary.BigEndian.Uint16(payload)) - reason = btsToString(payload[2:]) - return -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/server.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/server.go deleted file mode 100644 index 48059aded49..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/server.go +++ /dev/null @@ -1,607 +0,0 @@ -package ws - -import ( - "bufio" - "bytes" - "fmt" - "io" - "net" - "net/http" - "strings" - "time" - - "github.com/gobwas/httphead" - "github.com/gobwas/pool/pbufio" -) - -// Constants used by ConnUpgrader. -const ( - DefaultServerReadBufferSize = 4096 - DefaultServerWriteBufferSize = 512 -) - -// Errors used by both client and server when preparing WebSocket handshake. -var ( - ErrHandshakeBadProtocol = RejectConnectionError( - RejectionStatus(http.StatusHTTPVersionNotSupported), - RejectionReason(fmt.Sprintf("handshake error: bad HTTP protocol version")), - ) - ErrHandshakeBadMethod = RejectConnectionError( - RejectionStatus(http.StatusMethodNotAllowed), - RejectionReason(fmt.Sprintf("handshake error: bad HTTP request method")), - ) - ErrHandshakeBadHost = RejectConnectionError( - RejectionStatus(http.StatusBadRequest), - RejectionReason(fmt.Sprintf("handshake error: bad %q header", headerHost)), - ) - ErrHandshakeBadUpgrade = RejectConnectionError( - RejectionStatus(http.StatusBadRequest), - RejectionReason(fmt.Sprintf("handshake error: bad %q header", headerUpgrade)), - ) - ErrHandshakeBadConnection = RejectConnectionError( - RejectionStatus(http.StatusBadRequest), - RejectionReason(fmt.Sprintf("handshake error: bad %q header", headerConnection)), - ) - ErrHandshakeBadSecAccept = RejectConnectionError( - RejectionStatus(http.StatusBadRequest), - RejectionReason(fmt.Sprintf("handshake error: bad %q header", headerSecAccept)), - ) - ErrHandshakeBadSecKey = RejectConnectionError( - RejectionStatus(http.StatusBadRequest), - RejectionReason(fmt.Sprintf("handshake error: bad %q header", headerSecKey)), - ) - ErrHandshakeBadSecVersion = RejectConnectionError( - RejectionStatus(http.StatusBadRequest), - RejectionReason(fmt.Sprintf("handshake error: bad %q header", headerSecVersion)), - ) -) - -// ErrMalformedResponse is returned by Dialer to indicate that server response -// can not be parsed. -var ErrMalformedResponse = fmt.Errorf("malformed HTTP response") - -// ErrMalformedRequest is returned when HTTP request can not be parsed. -var ErrMalformedRequest = RejectConnectionError( - RejectionStatus(http.StatusBadRequest), - RejectionReason("malformed HTTP request"), -) - -// ErrHandshakeUpgradeRequired is returned by Upgrader to indicate that -// connection is rejected because given WebSocket version is malformed. -// -// According to RFC6455: -// If this version does not match a version understood by the server, the -// server MUST abort the WebSocket handshake described in this section and -// instead send an appropriate HTTP error code (such as 426 Upgrade Required) -// and a |Sec-WebSocket-Version| header field indicating the version(s) the -// server is capable of understanding. -var ErrHandshakeUpgradeRequired = RejectConnectionError( - RejectionStatus(http.StatusUpgradeRequired), - RejectionHeader(HandshakeHeaderString(headerSecVersion+": 13\r\n")), - RejectionReason(fmt.Sprintf("handshake error: bad %q header", headerSecVersion)), -) - -// ErrNotHijacker is an error returned when http.ResponseWriter does not -// implement http.Hijacker interface. -var ErrNotHijacker = RejectConnectionError( - RejectionStatus(http.StatusInternalServerError), - RejectionReason("given http.ResponseWriter is not a http.Hijacker"), -) - -// DefaultHTTPUpgrader is an HTTPUpgrader that holds no options and is used by -// UpgradeHTTP function. -var DefaultHTTPUpgrader HTTPUpgrader - -// UpgradeHTTP is like HTTPUpgrader{}.Upgrade(). -func UpgradeHTTP(r *http.Request, w http.ResponseWriter) (net.Conn, *bufio.ReadWriter, Handshake, error) { - return DefaultHTTPUpgrader.Upgrade(r, w) -} - -// DefaultUpgrader is an Upgrader that holds no options and is used by Upgrade -// function. -var DefaultUpgrader Upgrader - -// Upgrade is like Upgrader{}.Upgrade(). -func Upgrade(conn io.ReadWriter) (Handshake, error) { - return DefaultUpgrader.Upgrade(conn) -} - -// HTTPUpgrader contains options for upgrading connection to websocket from -// net/http Handler arguments. -type HTTPUpgrader struct { - // Timeout is the maximum amount of time an Upgrade() will spent while - // writing handshake response. - // - // The default is no timeout. - Timeout time.Duration - - // Header is an optional http.Header mapping that could be used to - // write additional headers to the handshake response. - // - // Note that if present, it will be written in any result of handshake. - Header http.Header - - // Protocol is the select function that is used to select subprotocol from - // list requested by client. If this field is set, then the first matched - // protocol is sent to a client as negotiated. - Protocol func(string) bool - - // Extension is the select function that is used to select extensions from - // list requested by client. If this field is set, then the all matched - // extensions are sent to a client as negotiated. - Extension func(httphead.Option) bool -} - -// Upgrade upgrades http connection to the websocket connection. -// -// It hijacks net.Conn from w and returns received net.Conn and -// bufio.ReadWriter. On successful handshake it returns Handshake struct -// describing handshake info. -func (u HTTPUpgrader) Upgrade(r *http.Request, w http.ResponseWriter) (conn net.Conn, rw *bufio.ReadWriter, hs Handshake, err error) { - // Hijack connection first to get the ability to write rejection errors the - // same way as in Upgrader. - hj, ok := w.(http.Hijacker) - if ok { - conn, rw, err = hj.Hijack() - } else { - err = ErrNotHijacker - } - if err != nil { - httpError(w, err.Error(), http.StatusInternalServerError) - return - } - - // See https://tools.ietf.org/html/rfc6455#section-4.1 - // The method of the request MUST be GET, and the HTTP version MUST be at least 1.1. - var nonce string - if r.Method != http.MethodGet { - err = ErrHandshakeBadMethod - } else if r.ProtoMajor < 1 || (r.ProtoMajor == 1 && r.ProtoMinor < 1) { - err = ErrHandshakeBadProtocol - } else if r.Host == "" { - err = ErrHandshakeBadHost - } else if u := httpGetHeader(r.Header, headerUpgradeCanonical); u != "websocket" && !strings.EqualFold(u, "websocket") { - err = ErrHandshakeBadUpgrade - } else if c := httpGetHeader(r.Header, headerConnectionCanonical); c != "Upgrade" && !strHasToken(c, "upgrade") { - err = ErrHandshakeBadConnection - } else if nonce = httpGetHeader(r.Header, headerSecKeyCanonical); len(nonce) != nonceSize { - err = ErrHandshakeBadSecKey - } else if v := httpGetHeader(r.Header, headerSecVersionCanonical); v != "13" { - // According to RFC6455: - // - // If this version does not match a version understood by the server, - // the server MUST abort the WebSocket handshake described in this - // section and instead send an appropriate HTTP error code (such as 426 - // Upgrade Required) and a |Sec-WebSocket-Version| header field - // indicating the version(s) the server is capable of understanding. - // - // So we branching here cause empty or not present version does not - // meet the ABNF rules of RFC6455: - // - // version = DIGIT | (NZDIGIT DIGIT) | - // ("1" DIGIT DIGIT) | ("2" DIGIT DIGIT) - // ; Limited to 0-255 range, with no leading zeros - // - // That is, if version is really invalid – we sent 426 status, if it - // not present or empty – it is 400. - if v != "" { - err = ErrHandshakeUpgradeRequired - } else { - err = ErrHandshakeBadSecVersion - } - } - if check := u.Protocol; err == nil && check != nil { - ps := r.Header[headerSecProtocolCanonical] - for i := 0; i < len(ps) && err == nil && hs.Protocol == ""; i++ { - var ok bool - hs.Protocol, ok = strSelectProtocol(ps[i], check) - if !ok { - err = ErrMalformedRequest - } - } - } - if check := u.Extension; err == nil && check != nil { - xs := r.Header[headerSecExtensionsCanonical] - for i := 0; i < len(xs) && err == nil; i++ { - var ok bool - hs.Extensions, ok = strSelectExtensions(xs[i], hs.Extensions, check) - if !ok { - err = ErrMalformedRequest - } - } - } - - // Clear deadlines set by server. - conn.SetDeadline(noDeadline) - if t := u.Timeout; t != 0 { - conn.SetWriteDeadline(time.Now().Add(t)) - defer conn.SetWriteDeadline(noDeadline) - } - - var header handshakeHeader - if h := u.Header; h != nil { - header[0] = HandshakeHeaderHTTP(h) - } - if err == nil { - httpWriteResponseUpgrade(rw.Writer, strToBytes(nonce), hs, header.WriteTo) - err = rw.Writer.Flush() - } else { - var code int - if rej, ok := err.(*rejectConnectionError); ok { - code = rej.code - header[1] = rej.header - } - if code == 0 { - code = http.StatusInternalServerError - } - httpWriteResponseError(rw.Writer, err, code, header.WriteTo) - // Do not store Flush() error to not override already existing one. - rw.Writer.Flush() - } - return -} - -// Upgrader contains options for upgrading connection to websocket. -type Upgrader struct { - // ReadBufferSize and WriteBufferSize is an I/O buffer sizes. - // They used to read and write http data while upgrading to WebSocket. - // Allocated buffers are pooled with sync.Pool to avoid extra allocations. - // - // If a size is zero then default value is used. - // - // Usually it is useful to set read buffer size bigger than write buffer - // size because incoming request could contain long header values, such as - // Cookie. Response, in other way, could be big only if user write multiple - // custom headers. Usually response takes less than 256 bytes. - ReadBufferSize, WriteBufferSize int - - // Protocol is a select function that is used to select subprotocol - // from list requested by client. If this field is set, then the first matched - // protocol is sent to a client as negotiated. - // - // The argument is only valid until the callback returns. - Protocol func([]byte) bool - - // ProtocolCustrom allow user to parse Sec-WebSocket-Protocol header manually. - // Note that returned bytes must be valid until Upgrade returns. - // If ProtocolCustom is set, it used instead of Protocol function. - ProtocolCustom func([]byte) (string, bool) - - // Extension is a select function that is used to select extensions - // from list requested by client. If this field is set, then the all matched - // extensions are sent to a client as negotiated. - // - // The argument is only valid until the callback returns. - // - // According to the RFC6455 order of extensions passed by a client is - // significant. That is, returning true from this function means that no - // other extension with the same name should be checked because server - // accepted the most preferable extension right now: - // "Note that the order of extensions is significant. Any interactions between - // multiple extensions MAY be defined in the documents defining the extensions. - // In the absence of such definitions, the interpretation is that the header - // fields listed by the client in its request represent a preference of the - // header fields it wishes to use, with the first options listed being most - // preferable." - Extension func(httphead.Option) bool - - // ExtensionCustorm allow user to parse Sec-WebSocket-Extensions header manually. - // Note that returned options should be valid until Upgrade returns. - // If ExtensionCustom is set, it used instead of Extension function. - ExtensionCustom func([]byte, []httphead.Option) ([]httphead.Option, bool) - - // Header is an optional HandshakeHeader instance that could be used to - // write additional headers to the handshake response. - // - // It used instead of any key-value mappings to avoid allocations in user - // land. - // - // Note that if present, it will be written in any result of handshake. - Header HandshakeHeader - - // OnRequest is a callback that will be called after request line - // successful parsing. - // - // The arguments are only valid until the callback returns. - // - // If returned error is non-nil then connection is rejected and response is - // sent with appropriate HTTP error code and body set to error message. - // - // RejectConnectionError could be used to get more control on response. - OnRequest func(uri []byte) error - - // OnHost is a callback that will be called after "Host" header successful - // parsing. - // - // It is separated from OnHeader callback because the Host header must be - // present in each request since HTTP/1.1. Thus Host header is non-optional - // and required for every WebSocket handshake. - // - // The arguments are only valid until the callback returns. - // - // If returned error is non-nil then connection is rejected and response is - // sent with appropriate HTTP error code and body set to error message. - // - // RejectConnectionError could be used to get more control on response. - OnHost func(host []byte) error - - // OnHeader is a callback that will be called after successful parsing of - // header, that is not used during WebSocket handshake procedure. That is, - // it will be called with non-websocket headers, which could be relevant - // for application-level logic. - // - // The arguments are only valid until the callback returns. - // - // If returned error is non-nil then connection is rejected and response is - // sent with appropriate HTTP error code and body set to error message. - // - // RejectConnectionError could be used to get more control on response. - OnHeader func(key, value []byte) error - - // OnBeforeUpgrade is a callback that will be called before sending - // successful upgrade response. - // - // Setting OnBeforeUpgrade allows user to make final application-level - // checks and decide whether this connection is allowed to successfully - // upgrade to WebSocket. - // - // It must return non-nil either HandshakeHeader or error and never both. - // - // If returned error is non-nil then connection is rejected and response is - // sent with appropriate HTTP error code and body set to error message. - // - // RejectConnectionError could be used to get more control on response. - OnBeforeUpgrade func() (header HandshakeHeader, err error) -} - -// Upgrade zero-copy upgrades connection to WebSocket. It interprets given conn -// as connection with incoming HTTP Upgrade request. -// -// It is a caller responsibility to manage i/o timeouts on conn. -// -// Non-nil error means that request for the WebSocket upgrade is invalid or -// malformed and usually connection should be closed. -// Even when error is non-nil Upgrade will write appropriate response into -// connection in compliance with RFC. -func (u Upgrader) Upgrade(conn io.ReadWriter) (hs Handshake, err error) { - // headerSeen constants helps to report whether or not some header was seen - // during reading request bytes. - const ( - headerSeenHost = 1 << iota - headerSeenUpgrade - headerSeenConnection - headerSeenSecVersion - headerSeenSecKey - - // headerSeenAll is the value that we expect to receive at the end of - // headers read/parse loop. - headerSeenAll = 0 | - headerSeenHost | - headerSeenUpgrade | - headerSeenConnection | - headerSeenSecVersion | - headerSeenSecKey - ) - - // Prepare I/O buffers. - // TODO(gobwas): make it configurable. - br := pbufio.GetReader(conn, - nonZero(u.ReadBufferSize, DefaultServerReadBufferSize), - ) - bw := pbufio.GetWriter(conn, - nonZero(u.WriteBufferSize, DefaultServerWriteBufferSize), - ) - defer func() { - pbufio.PutReader(br) - pbufio.PutWriter(bw) - }() - - // Read HTTP request line like "GET /ws HTTP/1.1". - rl, err := readLine(br) - if err != nil { - return - } - // Parse request line data like HTTP version, uri and method. - req, err := httpParseRequestLine(rl) - if err != nil { - return - } - - // Prepare stack-based handshake header list. - header := handshakeHeader{ - 0: u.Header, - } - - // Parse and check HTTP request. - // As RFC6455 says: - // The client's opening handshake consists of the following parts. If the - // server, while reading the handshake, finds that the client did not - // send a handshake that matches the description below (note that as per - // [RFC2616], the order of the header fields is not important), including - // but not limited to any violations of the ABNF grammar specified for - // the components of the handshake, the server MUST stop processing the - // client's handshake and return an HTTP response with an appropriate - // error code (such as 400 Bad Request). - // - // See https://tools.ietf.org/html/rfc6455#section-4.2.1 - - // An HTTP/1.1 or higher GET request, including a "Request-URI". - // - // Even if RFC says "1.1 or higher" without mentioning the part of the - // version, we apply it only to minor part. - switch { - case req.major != 1 || req.minor < 1: - // Abort processing the whole request because we do not even know how - // to actually parse it. - err = ErrHandshakeBadProtocol - - case btsToString(req.method) != http.MethodGet: - err = ErrHandshakeBadMethod - - default: - if onRequest := u.OnRequest; onRequest != nil { - err = onRequest(req.uri) - } - } - // Start headers read/parse loop. - var ( - // headerSeen reports which header was seen by setting corresponding - // bit on. - headerSeen byte - - nonce = make([]byte, nonceSize) - ) - for err == nil { - line, e := readLine(br) - if e != nil { - return hs, e - } - if len(line) == 0 { - // Blank line, no more lines to read. - break - } - - k, v, ok := httpParseHeaderLine(line) - if !ok { - err = ErrMalformedRequest - break - } - - switch btsToString(k) { - case headerHostCanonical: - headerSeen |= headerSeenHost - if onHost := u.OnHost; onHost != nil { - err = onHost(v) - } - - case headerUpgradeCanonical: - headerSeen |= headerSeenUpgrade - if !bytes.Equal(v, specHeaderValueUpgrade) && !bytes.EqualFold(v, specHeaderValueUpgrade) { - err = ErrHandshakeBadUpgrade - } - - case headerConnectionCanonical: - headerSeen |= headerSeenConnection - if !bytes.Equal(v, specHeaderValueConnection) && !btsHasToken(v, specHeaderValueConnectionLower) { - err = ErrHandshakeBadConnection - } - - case headerSecVersionCanonical: - headerSeen |= headerSeenSecVersion - if !bytes.Equal(v, specHeaderValueSecVersion) { - err = ErrHandshakeUpgradeRequired - } - - case headerSecKeyCanonical: - headerSeen |= headerSeenSecKey - if len(v) != nonceSize { - err = ErrHandshakeBadSecKey - } else { - copy(nonce[:], v) - } - - case headerSecProtocolCanonical: - if custom, check := u.ProtocolCustom, u.Protocol; hs.Protocol == "" && (custom != nil || check != nil) { - var ok bool - if custom != nil { - hs.Protocol, ok = custom(v) - } else { - hs.Protocol, ok = btsSelectProtocol(v, check) - } - if !ok { - err = ErrMalformedRequest - } - } - - case headerSecExtensionsCanonical: - if custom, check := u.ExtensionCustom, u.Extension; custom != nil || check != nil { - var ok bool - if custom != nil { - hs.Extensions, ok = custom(v, hs.Extensions) - } else { - hs.Extensions, ok = btsSelectExtensions(v, hs.Extensions, check) - } - if !ok { - err = ErrMalformedRequest - } - } - - default: - if onHeader := u.OnHeader; onHeader != nil { - err = onHeader(k, v) - } - } - } - switch { - case err == nil && headerSeen != headerSeenAll: - switch { - case headerSeen&headerSeenHost == 0: - // As RFC2616 says: - // A client MUST include a Host header field in all HTTP/1.1 - // request messages. If the requested URI does not include an - // Internet host name for the service being requested, then the - // Host header field MUST be given with an empty value. An - // HTTP/1.1 proxy MUST ensure that any request message it - // forwards does contain an appropriate Host header field that - // identifies the service being requested by the proxy. All - // Internet-based HTTP/1.1 servers MUST respond with a 400 (Bad - // Request) status code to any HTTP/1.1 request message which - // lacks a Host header field. - err = ErrHandshakeBadHost - case headerSeen&headerSeenUpgrade == 0: - err = ErrHandshakeBadUpgrade - case headerSeen&headerSeenConnection == 0: - err = ErrHandshakeBadConnection - case headerSeen&headerSeenSecVersion == 0: - // In case of empty or not present version we do not send 426 status, - // because it does not meet the ABNF rules of RFC6455: - // - // version = DIGIT | (NZDIGIT DIGIT) | - // ("1" DIGIT DIGIT) | ("2" DIGIT DIGIT) - // ; Limited to 0-255 range, with no leading zeros - // - // That is, if version is really invalid – we sent 426 status as above, if it - // not present – it is 400. - err = ErrHandshakeBadSecVersion - case headerSeen&headerSeenSecKey == 0: - err = ErrHandshakeBadSecKey - default: - panic("unknown headers state") - } - - case err == nil && u.OnBeforeUpgrade != nil: - header[1], err = u.OnBeforeUpgrade() - } - if err != nil { - var code int - if rej, ok := err.(*rejectConnectionError); ok { - code = rej.code - header[1] = rej.header - } - if code == 0 { - code = http.StatusInternalServerError - } - httpWriteResponseError(bw, err, code, header.WriteTo) - // Do not store Flush() error to not override already existing one. - bw.Flush() - return - } - - httpWriteResponseUpgrade(bw, nonce, hs, header.WriteTo) - err = bw.Flush() - - return -} - -type handshakeHeader [2]HandshakeHeader - -func (hs handshakeHeader) WriteTo(w io.Writer) (n int64, err error) { - for i := 0; i < len(hs) && err == nil; i++ { - if h := hs[i]; h != nil { - var m int64 - m, err = h.WriteTo(w) - n += m - } - } - return n, err -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/server_test.s b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/server_test.s deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/stub.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/stub.go new file mode 100644 index 00000000000..0d00bc949fb --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/stub.go @@ -0,0 +1,54 @@ +// Code generated by depstubber. DO NOT EDIT. +// This is a simple stub for github.com/gobwas/ws, strictly for use in testing. + +// See the LICENSE file for information about the licensing of the original library. +// Source: github.com/gobwas/ws (exports: Dialer; functions: Dial) + +// Package ws is a stub of github.com/gobwas/ws, generated by depstubber. +package ws + +import ( + bufio "bufio" + context "context" + tls "crypto/tls" + io "io" + net "net" + url "net/url" + time "time" +) + +func Dial(_ context.Context, _ string) (net.Conn, *bufio.Reader, Handshake, error) { + return nil, nil, Handshake{}, nil +} + +type Dialer struct { + ReadBufferSize int + WriteBufferSize int + Timeout time.Duration + Protocols []string + Extensions []interface{} + Header HandshakeHeader + OnStatusError func(int, []byte, io.Reader) + OnHeader func([]byte, []byte) error + NetDial func(context.Context, string, string) (net.Conn, error) + TLSClient func(net.Conn, string) net.Conn + TLSConfig *tls.Config + WrapConn func(net.Conn) net.Conn +} + +func (_ Dialer) Dial(_ context.Context, _ string) (net.Conn, *bufio.Reader, Handshake, error) { + return nil, nil, Handshake{}, nil +} + +func (_ Dialer) Upgrade(_ io.ReadWriter, _ *url.URL) (*bufio.Reader, Handshake, error) { + return nil, Handshake{}, nil +} + +type Handshake struct { + Protocol string + Extensions []interface{} +} + +type HandshakeHeader interface { + WriteTo(_ io.Writer) (int64, error) +} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/util.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/util.go deleted file mode 100644 index 67ad906e5d2..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/util.go +++ /dev/null @@ -1,214 +0,0 @@ -package ws - -import ( - "bufio" - "bytes" - "fmt" - "reflect" - "unsafe" - - "github.com/gobwas/httphead" -) - -// SelectFromSlice creates accept function that could be used as Protocol/Extension -// select during upgrade. -func SelectFromSlice(accept []string) func(string) bool { - if len(accept) > 16 { - mp := make(map[string]struct{}, len(accept)) - for _, p := range accept { - mp[p] = struct{}{} - } - return func(p string) bool { - _, ok := mp[p] - return ok - } - } - return func(p string) bool { - for _, ok := range accept { - if p == ok { - return true - } - } - return false - } -} - -// SelectEqual creates accept function that could be used as Protocol/Extension -// select during upgrade. -func SelectEqual(v string) func(string) bool { - return func(p string) bool { - return v == p - } -} - -func strToBytes(str string) (bts []byte) { - s := (*reflect.StringHeader)(unsafe.Pointer(&str)) - b := (*reflect.SliceHeader)(unsafe.Pointer(&bts)) - b.Data = s.Data - b.Len = s.Len - b.Cap = s.Len - return -} - -func btsToString(bts []byte) (str string) { - return *(*string)(unsafe.Pointer(&bts)) -} - -// asciiToInt converts bytes to int. -func asciiToInt(bts []byte) (ret int, err error) { - // ASCII numbers all start with the high-order bits 0011. - // If you see that, and the next bits are 0-9 (0000 - 1001) you can grab those - // bits and interpret them directly as an integer. - var n int - if n = len(bts); n < 1 { - return 0, fmt.Errorf("converting empty bytes to int") - } - for i := 0; i < n; i++ { - if bts[i]&0xf0 != 0x30 { - return 0, fmt.Errorf("%s is not a numeric character", string(bts[i])) - } - ret += int(bts[i]&0xf) * pow(10, n-i-1) - } - return ret, nil -} - -// pow for integers implementation. -// See Donald Knuth, The Art of Computer Programming, Volume 2, Section 4.6.3 -func pow(a, b int) int { - p := 1 - for b > 0 { - if b&1 != 0 { - p *= a - } - b >>= 1 - a *= a - } - return p -} - -func bsplit3(bts []byte, sep byte) (b1, b2, b3 []byte) { - a := bytes.IndexByte(bts, sep) - b := bytes.IndexByte(bts[a+1:], sep) - if a == -1 || b == -1 { - return bts, nil, nil - } - b += a + 1 - return bts[:a], bts[a+1 : b], bts[b+1:] -} - -func btrim(bts []byte) []byte { - var i, j int - for i = 0; i < len(bts) && (bts[i] == ' ' || bts[i] == '\t'); { - i++ - } - for j = len(bts); j > i && (bts[j-1] == ' ' || bts[j-1] == '\t'); { - j-- - } - return bts[i:j] -} - -func strHasToken(header, token string) (has bool) { - return btsHasToken(strToBytes(header), strToBytes(token)) -} - -func btsHasToken(header, token []byte) (has bool) { - httphead.ScanTokens(header, func(v []byte) bool { - has = bytes.EqualFold(v, token) - return !has - }) - return -} - -const ( - toLower = 'a' - 'A' // for use with OR. - toUpper = ^byte(toLower) // for use with AND. - toLower8 = uint64(toLower) | - uint64(toLower)<<8 | - uint64(toLower)<<16 | - uint64(toLower)<<24 | - uint64(toLower)<<32 | - uint64(toLower)<<40 | - uint64(toLower)<<48 | - uint64(toLower)<<56 -) - -// Algorithm below is like standard textproto/CanonicalMIMEHeaderKey, except -// that it operates with slice of bytes and modifies it inplace without copying. -func canonicalizeHeaderKey(k []byte) { - upper := true - for i, c := range k { - if upper && 'a' <= c && c <= 'z' { - k[i] &= toUpper - } else if !upper && 'A' <= c && c <= 'Z' { - k[i] |= toLower - } - upper = c == '-' - } -} - -// readLine reads line from br. It reads until '\n' and returns bytes without -// '\n' or '\r\n' at the end. -// It returns err if and only if line does not end in '\n'. Note that read -// bytes returned in any case of error. -// -// It is much like the textproto/Reader.ReadLine() except the thing that it -// returns raw bytes, instead of string. That is, it avoids copying bytes read -// from br. -// -// textproto/Reader.ReadLineBytes() is also makes copy of resulting bytes to be -// safe with future I/O operations on br. -// -// We could control I/O operations on br and do not need to make additional -// copy for safety. -// -// NOTE: it may return copied flag to notify that returned buffer is safe to -// use. -func readLine(br *bufio.Reader) ([]byte, error) { - var line []byte - for { - bts, err := br.ReadSlice('\n') - if err == bufio.ErrBufferFull { - // Copy bytes because next read will discard them. - line = append(line, bts...) - continue - } - - // Avoid copy of single read. - if line == nil { - line = bts - } else { - line = append(line, bts...) - } - - if err != nil { - return line, err - } - - // Size of line is at least 1. - // In other case bufio.ReadSlice() returns error. - n := len(line) - - // Cut '\n' or '\r\n'. - if n > 1 && line[n-2] == '\r' { - line = line[:n-2] - } else { - line = line[:n-1] - } - - return line, nil - } -} - -func min(a, b int) int { - if a < b { - return a - } - return b -} - -func nonZero(a, b int) int { - if a != 0 { - return a - } - return b -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/write.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/write.go deleted file mode 100644 index 94557c69639..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gobwas/ws/write.go +++ /dev/null @@ -1,104 +0,0 @@ -package ws - -import ( - "encoding/binary" - "io" -) - -// Header size length bounds in bytes. -const ( - MaxHeaderSize = 14 - MinHeaderSize = 2 -) - -const ( - bit0 = 0x80 - bit1 = 0x40 - bit2 = 0x20 - bit3 = 0x10 - bit4 = 0x08 - bit5 = 0x04 - bit6 = 0x02 - bit7 = 0x01 - - len7 = int64(125) - len16 = int64(^(uint16(0))) - len64 = int64(^(uint64(0)) >> 1) -) - -// HeaderSize returns number of bytes that are needed to encode given header. -// It returns -1 if header is malformed. -func HeaderSize(h Header) (n int) { - switch { - case h.Length < 126: - n = 2 - case h.Length <= len16: - n = 4 - case h.Length <= len64: - n = 10 - default: - return -1 - } - if h.Masked { - n += len(h.Mask) - } - return n -} - -// WriteHeader writes header binary representation into w. -func WriteHeader(w io.Writer, h Header) error { - // Make slice of bytes with capacity 14 that could hold any header. - bts := make([]byte, MaxHeaderSize) - - if h.Fin { - bts[0] |= bit0 - } - bts[0] |= h.Rsv << 4 - bts[0] |= byte(h.OpCode) - - var n int - switch { - case h.Length <= len7: - bts[1] = byte(h.Length) - n = 2 - - case h.Length <= len16: - bts[1] = 126 - binary.BigEndian.PutUint16(bts[2:4], uint16(h.Length)) - n = 4 - - case h.Length <= len64: - bts[1] = 127 - binary.BigEndian.PutUint64(bts[2:10], uint64(h.Length)) - n = 10 - - default: - return ErrHeaderLengthUnexpected - } - - if h.Masked { - bts[1] |= bit0 - n += copy(bts[n:], h.Mask[:]) - } - - _, err := w.Write(bts[:n]) - - return err -} - -// WriteFrame writes frame binary representation into w. -func WriteFrame(w io.Writer, f Frame) error { - err := WriteHeader(w, f.Header) - if err != nil { - return err - } - _, err = w.Write(f.Payload) - return err -} - -// MustWriteFrame is like WriteFrame but panics if frame can not be read. -func MustWriteFrame(w io.Writer, f Frame) { - if err := WriteFrame(w, f); err != nil { - panic(err) - } -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/.gitignore b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/.gitignore deleted file mode 100644 index cd3fcd1ef72..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/.gitignore +++ /dev/null @@ -1,25 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe - -.idea/ -*.iml diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/AUTHORS b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/AUTHORS deleted file mode 100644 index 1931f400682..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/AUTHORS +++ /dev/null @@ -1,9 +0,0 @@ -# This is the official list of Gorilla WebSocket authors for copyright -# purposes. -# -# Please keep the list sorted. - -Gary Burd -Google LLC (https://opensource.google.com/) -Joachim Bauch - diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/README.md b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/README.md deleted file mode 100644 index 19aa2e75c82..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/README.md +++ /dev/null @@ -1,64 +0,0 @@ -# Gorilla WebSocket - -[![GoDoc](https://godoc.org/github.com/gorilla/websocket?status.svg)](https://godoc.org/github.com/gorilla/websocket) -[![CircleCI](https://circleci.com/gh/gorilla/websocket.svg?style=svg)](https://circleci.com/gh/gorilla/websocket) - -Gorilla WebSocket is a [Go](http://golang.org/) implementation of the -[WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. - -### Documentation - -* [API Reference](https://pkg.go.dev/github.com/gorilla/websocket?tab=doc) -* [Chat example](https://github.com/gorilla/websocket/tree/master/examples/chat) -* [Command example](https://github.com/gorilla/websocket/tree/master/examples/command) -* [Client and server example](https://github.com/gorilla/websocket/tree/master/examples/echo) -* [File watch example](https://github.com/gorilla/websocket/tree/master/examples/filewatch) - -### Status - -The Gorilla WebSocket package provides a complete and tested implementation of -the [WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. The -package API is stable. - -### Installation - - go get github.com/gorilla/websocket - -### Protocol Compliance - -The Gorilla WebSocket package passes the server tests in the [Autobahn Test -Suite](https://github.com/crossbario/autobahn-testsuite) using the application in the [examples/autobahn -subdirectory](https://github.com/gorilla/websocket/tree/master/examples/autobahn). - -### Gorilla WebSocket compared with other packages - - - - - - - - - - - - - - - - - - -
github.com/gorillagolang.org/x/net
RFC 6455 Features
Passes Autobahn Test SuiteYesNo
Receive fragmented messageYesNo, see note 1
Send close messageYesNo
Send pings and receive pongsYesNo
Get the type of a received data messageYesYes, see note 2
Other Features
Compression ExtensionsExperimentalNo
Read message using io.ReaderYesNo, see note 3
Write message using io.WriteCloserYesNo, see note 3
- -Notes: - -1. Large messages are fragmented in [Chrome's new WebSocket implementation](http://www.ietf.org/mail-archive/web/hybi/current/msg10503.html). -2. The application can get the type of a received data message by implementing - a [Codec marshal](http://godoc.org/golang.org/x/net/websocket#Codec.Marshal) - function. -3. The go.net io.Reader and io.Writer operate across WebSocket frame boundaries. - Read returns when the input buffer is full or a frame boundary is - encountered. Each call to Write sends a single frame message. The Gorilla - io.Reader and io.WriteCloser operate on a single WebSocket message. - diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/client.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/client.go deleted file mode 100644 index 962c06a391c..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/client.go +++ /dev/null @@ -1,395 +0,0 @@ -// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -import ( - "bytes" - "context" - "crypto/tls" - "errors" - "io" - "io/ioutil" - "net" - "net/http" - "net/http/httptrace" - "net/url" - "strings" - "time" -) - -// ErrBadHandshake is returned when the server response to opening handshake is -// invalid. -var ErrBadHandshake = errors.New("websocket: bad handshake") - -var errInvalidCompression = errors.New("websocket: invalid compression negotiation") - -// NewClient creates a new client connection using the given net connection. -// The URL u specifies the host and request URI. Use requestHeader to specify -// the origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies -// (Cookie). Use the response.Header to get the selected subprotocol -// (Sec-WebSocket-Protocol) and cookies (Set-Cookie). -// -// If the WebSocket handshake fails, ErrBadHandshake is returned along with a -// non-nil *http.Response so that callers can handle redirects, authentication, -// etc. -// -// Deprecated: Use Dialer instead. -func NewClient(netConn net.Conn, u *url.URL, requestHeader http.Header, readBufSize, writeBufSize int) (c *Conn, response *http.Response, err error) { - d := Dialer{ - ReadBufferSize: readBufSize, - WriteBufferSize: writeBufSize, - NetDial: func(net, addr string) (net.Conn, error) { - return netConn, nil - }, - } - return d.Dial(u.String(), requestHeader) -} - -// A Dialer contains options for connecting to WebSocket server. -type Dialer struct { - // NetDial specifies the dial function for creating TCP connections. If - // NetDial is nil, net.Dial is used. - NetDial func(network, addr string) (net.Conn, error) - - // NetDialContext specifies the dial function for creating TCP connections. If - // NetDialContext is nil, net.DialContext is used. - NetDialContext func(ctx context.Context, network, addr string) (net.Conn, error) - - // Proxy specifies a function to return a proxy for a given - // Request. If the function returns a non-nil error, the - // request is aborted with the provided error. - // If Proxy is nil or returns a nil *URL, no proxy is used. - Proxy func(*http.Request) (*url.URL, error) - - // TLSClientConfig specifies the TLS configuration to use with tls.Client. - // If nil, the default configuration is used. - TLSClientConfig *tls.Config - - // HandshakeTimeout specifies the duration for the handshake to complete. - HandshakeTimeout time.Duration - - // ReadBufferSize and WriteBufferSize specify I/O buffer sizes in bytes. If a buffer - // size is zero, then a useful default size is used. The I/O buffer sizes - // do not limit the size of the messages that can be sent or received. - ReadBufferSize, WriteBufferSize int - - // WriteBufferPool is a pool of buffers for write operations. If the value - // is not set, then write buffers are allocated to the connection for the - // lifetime of the connection. - // - // A pool is most useful when the application has a modest volume of writes - // across a large number of connections. - // - // Applications should use a single pool for each unique value of - // WriteBufferSize. - WriteBufferPool BufferPool - - // Subprotocols specifies the client's requested subprotocols. - Subprotocols []string - - // EnableCompression specifies if the client should attempt to negotiate - // per message compression (RFC 7692). Setting this value to true does not - // guarantee that compression will be supported. Currently only "no context - // takeover" modes are supported. - EnableCompression bool - - // Jar specifies the cookie jar. - // If Jar is nil, cookies are not sent in requests and ignored - // in responses. - Jar http.CookieJar -} - -// Dial creates a new client connection by calling DialContext with a background context. -func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) { - return d.DialContext(context.Background(), urlStr, requestHeader) -} - -var errMalformedURL = errors.New("malformed ws or wss URL") - -func hostPortNoPort(u *url.URL) (hostPort, hostNoPort string) { - hostPort = u.Host - hostNoPort = u.Host - if i := strings.LastIndex(u.Host, ":"); i > strings.LastIndex(u.Host, "]") { - hostNoPort = hostNoPort[:i] - } else { - switch u.Scheme { - case "wss": - hostPort += ":443" - case "https": - hostPort += ":443" - default: - hostPort += ":80" - } - } - return hostPort, hostNoPort -} - -// DefaultDialer is a dialer with all fields set to the default values. -var DefaultDialer = &Dialer{ - Proxy: http.ProxyFromEnvironment, - HandshakeTimeout: 45 * time.Second, -} - -// nilDialer is dialer to use when receiver is nil. -var nilDialer = *DefaultDialer - -// DialContext creates a new client connection. Use requestHeader to specify the -// origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies (Cookie). -// Use the response.Header to get the selected subprotocol -// (Sec-WebSocket-Protocol) and cookies (Set-Cookie). -// -// The context will be used in the request and in the Dialer. -// -// If the WebSocket handshake fails, ErrBadHandshake is returned along with a -// non-nil *http.Response so that callers can handle redirects, authentication, -// etcetera. The response body may not contain the entire response and does not -// need to be closed by the application. -func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) { - if d == nil { - d = &nilDialer - } - - challengeKey, err := generateChallengeKey() - if err != nil { - return nil, nil, err - } - - u, err := url.Parse(urlStr) - if err != nil { - return nil, nil, err - } - - switch u.Scheme { - case "ws": - u.Scheme = "http" - case "wss": - u.Scheme = "https" - default: - return nil, nil, errMalformedURL - } - - if u.User != nil { - // User name and password are not allowed in websocket URIs. - return nil, nil, errMalformedURL - } - - req := &http.Request{ - Method: "GET", - URL: u, - Proto: "HTTP/1.1", - ProtoMajor: 1, - ProtoMinor: 1, - Header: make(http.Header), - Host: u.Host, - } - req = req.WithContext(ctx) - - // Set the cookies present in the cookie jar of the dialer - if d.Jar != nil { - for _, cookie := range d.Jar.Cookies(u) { - req.AddCookie(cookie) - } - } - - // Set the request headers using the capitalization for names and values in - // RFC examples. Although the capitalization shouldn't matter, there are - // servers that depend on it. The Header.Set method is not used because the - // method canonicalizes the header names. - req.Header["Upgrade"] = []string{"websocket"} - req.Header["Connection"] = []string{"Upgrade"} - req.Header["Sec-WebSocket-Key"] = []string{challengeKey} - req.Header["Sec-WebSocket-Version"] = []string{"13"} - if len(d.Subprotocols) > 0 { - req.Header["Sec-WebSocket-Protocol"] = []string{strings.Join(d.Subprotocols, ", ")} - } - for k, vs := range requestHeader { - switch { - case k == "Host": - if len(vs) > 0 { - req.Host = vs[0] - } - case k == "Upgrade" || - k == "Connection" || - k == "Sec-Websocket-Key" || - k == "Sec-Websocket-Version" || - k == "Sec-Websocket-Extensions" || - (k == "Sec-Websocket-Protocol" && len(d.Subprotocols) > 0): - return nil, nil, errors.New("websocket: duplicate header not allowed: " + k) - case k == "Sec-Websocket-Protocol": - req.Header["Sec-WebSocket-Protocol"] = vs - default: - req.Header[k] = vs - } - } - - if d.EnableCompression { - req.Header["Sec-WebSocket-Extensions"] = []string{"permessage-deflate; server_no_context_takeover; client_no_context_takeover"} - } - - if d.HandshakeTimeout != 0 { - var cancel func() - ctx, cancel = context.WithTimeout(ctx, d.HandshakeTimeout) - defer cancel() - } - - // Get network dial function. - var netDial func(network, add string) (net.Conn, error) - - if d.NetDialContext != nil { - netDial = func(network, addr string) (net.Conn, error) { - return d.NetDialContext(ctx, network, addr) - } - } else if d.NetDial != nil { - netDial = d.NetDial - } else { - netDialer := &net.Dialer{} - netDial = func(network, addr string) (net.Conn, error) { - return netDialer.DialContext(ctx, network, addr) - } - } - - // If needed, wrap the dial function to set the connection deadline. - if deadline, ok := ctx.Deadline(); ok { - forwardDial := netDial - netDial = func(network, addr string) (net.Conn, error) { - c, err := forwardDial(network, addr) - if err != nil { - return nil, err - } - err = c.SetDeadline(deadline) - if err != nil { - c.Close() - return nil, err - } - return c, nil - } - } - - // If needed, wrap the dial function to connect through a proxy. - if d.Proxy != nil { - proxyURL, err := d.Proxy(req) - if err != nil { - return nil, nil, err - } - if proxyURL != nil { - dialer, err := proxy_FromURL(proxyURL, netDialerFunc(netDial)) - if err != nil { - return nil, nil, err - } - netDial = dialer.Dial - } - } - - hostPort, hostNoPort := hostPortNoPort(u) - trace := httptrace.ContextClientTrace(ctx) - if trace != nil && trace.GetConn != nil { - trace.GetConn(hostPort) - } - - netConn, err := netDial("tcp", hostPort) - if trace != nil && trace.GotConn != nil { - trace.GotConn(httptrace.GotConnInfo{ - Conn: netConn, - }) - } - if err != nil { - return nil, nil, err - } - - defer func() { - if netConn != nil { - netConn.Close() - } - }() - - if u.Scheme == "https" { - cfg := cloneTLSConfig(d.TLSClientConfig) - if cfg.ServerName == "" { - cfg.ServerName = hostNoPort - } - tlsConn := tls.Client(netConn, cfg) - netConn = tlsConn - - var err error - if trace != nil { - err = doHandshakeWithTrace(trace, tlsConn, cfg) - } else { - err = doHandshake(tlsConn, cfg) - } - - if err != nil { - return nil, nil, err - } - } - - conn := newConn(netConn, false, d.ReadBufferSize, d.WriteBufferSize, d.WriteBufferPool, nil, nil) - - if err := req.Write(netConn); err != nil { - return nil, nil, err - } - - if trace != nil && trace.GotFirstResponseByte != nil { - if peek, err := conn.br.Peek(1); err == nil && len(peek) == 1 { - trace.GotFirstResponseByte() - } - } - - resp, err := http.ReadResponse(conn.br, req) - if err != nil { - return nil, nil, err - } - - if d.Jar != nil { - if rc := resp.Cookies(); len(rc) > 0 { - d.Jar.SetCookies(u, rc) - } - } - - if resp.StatusCode != 101 || - !strings.EqualFold(resp.Header.Get("Upgrade"), "websocket") || - !strings.EqualFold(resp.Header.Get("Connection"), "upgrade") || - resp.Header.Get("Sec-Websocket-Accept") != computeAcceptKey(challengeKey) { - // Before closing the network connection on return from this - // function, slurp up some of the response to aid application - // debugging. - buf := make([]byte, 1024) - n, _ := io.ReadFull(resp.Body, buf) - resp.Body = ioutil.NopCloser(bytes.NewReader(buf[:n])) - return nil, resp, ErrBadHandshake - } - - for _, ext := range parseExtensions(resp.Header) { - if ext[""] != "permessage-deflate" { - continue - } - _, snct := ext["server_no_context_takeover"] - _, cnct := ext["client_no_context_takeover"] - if !snct || !cnct { - return nil, resp, errInvalidCompression - } - conn.newCompressionWriter = compressNoContextTakeover - conn.newDecompressionReader = decompressNoContextTakeover - break - } - - resp.Body = ioutil.NopCloser(bytes.NewReader([]byte{})) - conn.subprotocol = resp.Header.Get("Sec-Websocket-Protocol") - - netConn.SetDeadline(time.Time{}) - netConn = nil // to avoid close in defer. - return conn, resp, nil -} - -func doHandshake(tlsConn *tls.Conn, cfg *tls.Config) error { - if err := tlsConn.Handshake(); err != nil { - return err - } - if !cfg.InsecureSkipVerify { - if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil { - return err - } - } - return nil -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/client_clone.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/client_clone.go deleted file mode 100644 index 4f0d943723a..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/client_clone.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.8 - -package websocket - -import "crypto/tls" - -func cloneTLSConfig(cfg *tls.Config) *tls.Config { - if cfg == nil { - return &tls.Config{} - } - return cfg.Clone() -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/client_clone_legacy.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/client_clone_legacy.go deleted file mode 100644 index babb007fb41..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/client_clone_legacy.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !go1.8 - -package websocket - -import "crypto/tls" - -// cloneTLSConfig clones all public fields except the fields -// SessionTicketsDisabled and SessionTicketKey. This avoids copying the -// sync.Mutex in the sync.Once and makes it safe to call cloneTLSConfig on a -// config in active use. -func cloneTLSConfig(cfg *tls.Config) *tls.Config { - if cfg == nil { - return &tls.Config{} - } - return &tls.Config{ - Rand: cfg.Rand, - Time: cfg.Time, - Certificates: cfg.Certificates, - NameToCertificate: cfg.NameToCertificate, - GetCertificate: cfg.GetCertificate, - RootCAs: cfg.RootCAs, - NextProtos: cfg.NextProtos, - ServerName: cfg.ServerName, - ClientAuth: cfg.ClientAuth, - ClientCAs: cfg.ClientCAs, - InsecureSkipVerify: cfg.InsecureSkipVerify, - CipherSuites: cfg.CipherSuites, - PreferServerCipherSuites: cfg.PreferServerCipherSuites, - ClientSessionCache: cfg.ClientSessionCache, - MinVersion: cfg.MinVersion, - MaxVersion: cfg.MaxVersion, - CurvePreferences: cfg.CurvePreferences, - } -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/compression.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/compression.go deleted file mode 100644 index 813ffb1e843..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/compression.go +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -import ( - "compress/flate" - "errors" - "io" - "strings" - "sync" -) - -const ( - minCompressionLevel = -2 // flate.HuffmanOnly not defined in Go < 1.6 - maxCompressionLevel = flate.BestCompression - defaultCompressionLevel = 1 -) - -var ( - flateWriterPools [maxCompressionLevel - minCompressionLevel + 1]sync.Pool - flateReaderPool = sync.Pool{New: func() interface{} { - return flate.NewReader(nil) - }} -) - -func decompressNoContextTakeover(r io.Reader) io.ReadCloser { - const tail = - // Add four bytes as specified in RFC - "\x00\x00\xff\xff" + - // Add final block to squelch unexpected EOF error from flate reader. - "\x01\x00\x00\xff\xff" - - fr, _ := flateReaderPool.Get().(io.ReadCloser) - fr.(flate.Resetter).Reset(io.MultiReader(r, strings.NewReader(tail)), nil) - return &flateReadWrapper{fr} -} - -func isValidCompressionLevel(level int) bool { - return minCompressionLevel <= level && level <= maxCompressionLevel -} - -func compressNoContextTakeover(w io.WriteCloser, level int) io.WriteCloser { - p := &flateWriterPools[level-minCompressionLevel] - tw := &truncWriter{w: w} - fw, _ := p.Get().(*flate.Writer) - if fw == nil { - fw, _ = flate.NewWriter(tw, level) - } else { - fw.Reset(tw) - } - return &flateWriteWrapper{fw: fw, tw: tw, p: p} -} - -// truncWriter is an io.Writer that writes all but the last four bytes of the -// stream to another io.Writer. -type truncWriter struct { - w io.WriteCloser - n int - p [4]byte -} - -func (w *truncWriter) Write(p []byte) (int, error) { - n := 0 - - // fill buffer first for simplicity. - if w.n < len(w.p) { - n = copy(w.p[w.n:], p) - p = p[n:] - w.n += n - if len(p) == 0 { - return n, nil - } - } - - m := len(p) - if m > len(w.p) { - m = len(w.p) - } - - if nn, err := w.w.Write(w.p[:m]); err != nil { - return n + nn, err - } - - copy(w.p[:], w.p[m:]) - copy(w.p[len(w.p)-m:], p[len(p)-m:]) - nn, err := w.w.Write(p[:len(p)-m]) - return n + nn, err -} - -type flateWriteWrapper struct { - fw *flate.Writer - tw *truncWriter - p *sync.Pool -} - -func (w *flateWriteWrapper) Write(p []byte) (int, error) { - if w.fw == nil { - return 0, errWriteClosed - } - return w.fw.Write(p) -} - -func (w *flateWriteWrapper) Close() error { - if w.fw == nil { - return errWriteClosed - } - err1 := w.fw.Flush() - w.p.Put(w.fw) - w.fw = nil - if w.tw.p != [4]byte{0, 0, 0xff, 0xff} { - return errors.New("websocket: internal error, unexpected bytes at end of flate stream") - } - err2 := w.tw.w.Close() - if err1 != nil { - return err1 - } - return err2 -} - -type flateReadWrapper struct { - fr io.ReadCloser -} - -func (r *flateReadWrapper) Read(p []byte) (int, error) { - if r.fr == nil { - return 0, io.ErrClosedPipe - } - n, err := r.fr.Read(p) - if err == io.EOF { - // Preemptively place the reader back in the pool. This helps with - // scenarios where the application does not call NextReader() soon after - // this final read. - r.Close() - } - return n, err -} - -func (r *flateReadWrapper) Close() error { - if r.fr == nil { - return io.ErrClosedPipe - } - err := r.fr.Close() - flateReaderPool.Put(r.fr) - r.fr = nil - return err -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/conn.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/conn.go deleted file mode 100644 index ca46d2f793c..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/conn.go +++ /dev/null @@ -1,1201 +0,0 @@ -// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -import ( - "bufio" - "encoding/binary" - "errors" - "io" - "io/ioutil" - "math/rand" - "net" - "strconv" - "sync" - "time" - "unicode/utf8" -) - -const ( - // Frame header byte 0 bits from Section 5.2 of RFC 6455 - finalBit = 1 << 7 - rsv1Bit = 1 << 6 - rsv2Bit = 1 << 5 - rsv3Bit = 1 << 4 - - // Frame header byte 1 bits from Section 5.2 of RFC 6455 - maskBit = 1 << 7 - - maxFrameHeaderSize = 2 + 8 + 4 // Fixed header + length + mask - maxControlFramePayloadSize = 125 - - writeWait = time.Second - - defaultReadBufferSize = 4096 - defaultWriteBufferSize = 4096 - - continuationFrame = 0 - noFrame = -1 -) - -// Close codes defined in RFC 6455, section 11.7. -const ( - CloseNormalClosure = 1000 - CloseGoingAway = 1001 - CloseProtocolError = 1002 - CloseUnsupportedData = 1003 - CloseNoStatusReceived = 1005 - CloseAbnormalClosure = 1006 - CloseInvalidFramePayloadData = 1007 - ClosePolicyViolation = 1008 - CloseMessageTooBig = 1009 - CloseMandatoryExtension = 1010 - CloseInternalServerErr = 1011 - CloseServiceRestart = 1012 - CloseTryAgainLater = 1013 - CloseTLSHandshake = 1015 -) - -// The message types are defined in RFC 6455, section 11.8. -const ( - // TextMessage denotes a text data message. The text message payload is - // interpreted as UTF-8 encoded text data. - TextMessage = 1 - - // BinaryMessage denotes a binary data message. - BinaryMessage = 2 - - // CloseMessage denotes a close control message. The optional message - // payload contains a numeric code and text. Use the FormatCloseMessage - // function to format a close message payload. - CloseMessage = 8 - - // PingMessage denotes a ping control message. The optional message payload - // is UTF-8 encoded text. - PingMessage = 9 - - // PongMessage denotes a pong control message. The optional message payload - // is UTF-8 encoded text. - PongMessage = 10 -) - -// ErrCloseSent is returned when the application writes a message to the -// connection after sending a close message. -var ErrCloseSent = errors.New("websocket: close sent") - -// ErrReadLimit is returned when reading a message that is larger than the -// read limit set for the connection. -var ErrReadLimit = errors.New("websocket: read limit exceeded") - -// netError satisfies the net Error interface. -type netError struct { - msg string - temporary bool - timeout bool -} - -func (e *netError) Error() string { return e.msg } -func (e *netError) Temporary() bool { return e.temporary } -func (e *netError) Timeout() bool { return e.timeout } - -// CloseError represents a close message. -type CloseError struct { - // Code is defined in RFC 6455, section 11.7. - Code int - - // Text is the optional text payload. - Text string -} - -func (e *CloseError) Error() string { - s := []byte("websocket: close ") - s = strconv.AppendInt(s, int64(e.Code), 10) - switch e.Code { - case CloseNormalClosure: - s = append(s, " (normal)"...) - case CloseGoingAway: - s = append(s, " (going away)"...) - case CloseProtocolError: - s = append(s, " (protocol error)"...) - case CloseUnsupportedData: - s = append(s, " (unsupported data)"...) - case CloseNoStatusReceived: - s = append(s, " (no status)"...) - case CloseAbnormalClosure: - s = append(s, " (abnormal closure)"...) - case CloseInvalidFramePayloadData: - s = append(s, " (invalid payload data)"...) - case ClosePolicyViolation: - s = append(s, " (policy violation)"...) - case CloseMessageTooBig: - s = append(s, " (message too big)"...) - case CloseMandatoryExtension: - s = append(s, " (mandatory extension missing)"...) - case CloseInternalServerErr: - s = append(s, " (internal server error)"...) - case CloseTLSHandshake: - s = append(s, " (TLS handshake error)"...) - } - if e.Text != "" { - s = append(s, ": "...) - s = append(s, e.Text...) - } - return string(s) -} - -// IsCloseError returns boolean indicating whether the error is a *CloseError -// with one of the specified codes. -func IsCloseError(err error, codes ...int) bool { - if e, ok := err.(*CloseError); ok { - for _, code := range codes { - if e.Code == code { - return true - } - } - } - return false -} - -// IsUnexpectedCloseError returns boolean indicating whether the error is a -// *CloseError with a code not in the list of expected codes. -func IsUnexpectedCloseError(err error, expectedCodes ...int) bool { - if e, ok := err.(*CloseError); ok { - for _, code := range expectedCodes { - if e.Code == code { - return false - } - } - return true - } - return false -} - -var ( - errWriteTimeout = &netError{msg: "websocket: write timeout", timeout: true, temporary: true} - errUnexpectedEOF = &CloseError{Code: CloseAbnormalClosure, Text: io.ErrUnexpectedEOF.Error()} - errBadWriteOpCode = errors.New("websocket: bad write message type") - errWriteClosed = errors.New("websocket: write closed") - errInvalidControlFrame = errors.New("websocket: invalid control frame") -) - -func newMaskKey() [4]byte { - n := rand.Uint32() - return [4]byte{byte(n), byte(n >> 8), byte(n >> 16), byte(n >> 24)} -} - -func hideTempErr(err error) error { - if e, ok := err.(net.Error); ok && e.Temporary() { - err = &netError{msg: e.Error(), timeout: e.Timeout()} - } - return err -} - -func isControl(frameType int) bool { - return frameType == CloseMessage || frameType == PingMessage || frameType == PongMessage -} - -func isData(frameType int) bool { - return frameType == TextMessage || frameType == BinaryMessage -} - -var validReceivedCloseCodes = map[int]bool{ - // see http://www.iana.org/assignments/websocket/websocket.xhtml#close-code-number - - CloseNormalClosure: true, - CloseGoingAway: true, - CloseProtocolError: true, - CloseUnsupportedData: true, - CloseNoStatusReceived: false, - CloseAbnormalClosure: false, - CloseInvalidFramePayloadData: true, - ClosePolicyViolation: true, - CloseMessageTooBig: true, - CloseMandatoryExtension: true, - CloseInternalServerErr: true, - CloseServiceRestart: true, - CloseTryAgainLater: true, - CloseTLSHandshake: false, -} - -func isValidReceivedCloseCode(code int) bool { - return validReceivedCloseCodes[code] || (code >= 3000 && code <= 4999) -} - -// BufferPool represents a pool of buffers. The *sync.Pool type satisfies this -// interface. The type of the value stored in a pool is not specified. -type BufferPool interface { - // Get gets a value from the pool or returns nil if the pool is empty. - Get() interface{} - // Put adds a value to the pool. - Put(interface{}) -} - -// writePoolData is the type added to the write buffer pool. This wrapper is -// used to prevent applications from peeking at and depending on the values -// added to the pool. -type writePoolData struct{ buf []byte } - -// The Conn type represents a WebSocket connection. -type Conn struct { - conn net.Conn - isServer bool - subprotocol string - - // Write fields - mu chan struct{} // used as mutex to protect write to conn - writeBuf []byte // frame is constructed in this buffer. - writePool BufferPool - writeBufSize int - writeDeadline time.Time - writer io.WriteCloser // the current writer returned to the application - isWriting bool // for best-effort concurrent write detection - - writeErrMu sync.Mutex - writeErr error - - enableWriteCompression bool - compressionLevel int - newCompressionWriter func(io.WriteCloser, int) io.WriteCloser - - // Read fields - reader io.ReadCloser // the current reader returned to the application - readErr error - br *bufio.Reader - // bytes remaining in current frame. - // set setReadRemaining to safely update this value and prevent overflow - readRemaining int64 - readFinal bool // true the current message has more frames. - readLength int64 // Message size. - readLimit int64 // Maximum message size. - readMaskPos int - readMaskKey [4]byte - handlePong func(string) error - handlePing func(string) error - handleClose func(int, string) error - readErrCount int - messageReader *messageReader // the current low-level reader - - readDecompress bool // whether last read frame had RSV1 set - newDecompressionReader func(io.Reader) io.ReadCloser -} - -func newConn(conn net.Conn, isServer bool, readBufferSize, writeBufferSize int, writeBufferPool BufferPool, br *bufio.Reader, writeBuf []byte) *Conn { - - if br == nil { - if readBufferSize == 0 { - readBufferSize = defaultReadBufferSize - } else if readBufferSize < maxControlFramePayloadSize { - // must be large enough for control frame - readBufferSize = maxControlFramePayloadSize - } - br = bufio.NewReaderSize(conn, readBufferSize) - } - - if writeBufferSize <= 0 { - writeBufferSize = defaultWriteBufferSize - } - writeBufferSize += maxFrameHeaderSize - - if writeBuf == nil && writeBufferPool == nil { - writeBuf = make([]byte, writeBufferSize) - } - - mu := make(chan struct{}, 1) - mu <- struct{}{} - c := &Conn{ - isServer: isServer, - br: br, - conn: conn, - mu: mu, - readFinal: true, - writeBuf: writeBuf, - writePool: writeBufferPool, - writeBufSize: writeBufferSize, - enableWriteCompression: true, - compressionLevel: defaultCompressionLevel, - } - c.SetCloseHandler(nil) - c.SetPingHandler(nil) - c.SetPongHandler(nil) - return c -} - -// setReadRemaining tracks the number of bytes remaining on the connection. If n -// overflows, an ErrReadLimit is returned. -func (c *Conn) setReadRemaining(n int64) error { - if n < 0 { - return ErrReadLimit - } - - c.readRemaining = n - return nil -} - -// Subprotocol returns the negotiated protocol for the connection. -func (c *Conn) Subprotocol() string { - return c.subprotocol -} - -// Close closes the underlying network connection without sending or waiting -// for a close message. -func (c *Conn) Close() error { - return c.conn.Close() -} - -// LocalAddr returns the local network address. -func (c *Conn) LocalAddr() net.Addr { - return c.conn.LocalAddr() -} - -// RemoteAddr returns the remote network address. -func (c *Conn) RemoteAddr() net.Addr { - return c.conn.RemoteAddr() -} - -// Write methods - -func (c *Conn) writeFatal(err error) error { - err = hideTempErr(err) - c.writeErrMu.Lock() - if c.writeErr == nil { - c.writeErr = err - } - c.writeErrMu.Unlock() - return err -} - -func (c *Conn) read(n int) ([]byte, error) { - p, err := c.br.Peek(n) - if err == io.EOF { - err = errUnexpectedEOF - } - c.br.Discard(len(p)) - return p, err -} - -func (c *Conn) write(frameType int, deadline time.Time, buf0, buf1 []byte) error { - <-c.mu - defer func() { c.mu <- struct{}{} }() - - c.writeErrMu.Lock() - err := c.writeErr - c.writeErrMu.Unlock() - if err != nil { - return err - } - - c.conn.SetWriteDeadline(deadline) - if len(buf1) == 0 { - _, err = c.conn.Write(buf0) - } else { - err = c.writeBufs(buf0, buf1) - } - if err != nil { - return c.writeFatal(err) - } - if frameType == CloseMessage { - c.writeFatal(ErrCloseSent) - } - return nil -} - -// WriteControl writes a control message with the given deadline. The allowed -// message types are CloseMessage, PingMessage and PongMessage. -func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) error { - if !isControl(messageType) { - return errBadWriteOpCode - } - if len(data) > maxControlFramePayloadSize { - return errInvalidControlFrame - } - - b0 := byte(messageType) | finalBit - b1 := byte(len(data)) - if !c.isServer { - b1 |= maskBit - } - - buf := make([]byte, 0, maxFrameHeaderSize+maxControlFramePayloadSize) - buf = append(buf, b0, b1) - - if c.isServer { - buf = append(buf, data...) - } else { - key := newMaskKey() - buf = append(buf, key[:]...) - buf = append(buf, data...) - maskBytes(key, 0, buf[6:]) - } - - d := 1000 * time.Hour - if !deadline.IsZero() { - d = deadline.Sub(time.Now()) - if d < 0 { - return errWriteTimeout - } - } - - timer := time.NewTimer(d) - select { - case <-c.mu: - timer.Stop() - case <-timer.C: - return errWriteTimeout - } - defer func() { c.mu <- struct{}{} }() - - c.writeErrMu.Lock() - err := c.writeErr - c.writeErrMu.Unlock() - if err != nil { - return err - } - - c.conn.SetWriteDeadline(deadline) - _, err = c.conn.Write(buf) - if err != nil { - return c.writeFatal(err) - } - if messageType == CloseMessage { - c.writeFatal(ErrCloseSent) - } - return err -} - -// beginMessage prepares a connection and message writer for a new message. -func (c *Conn) beginMessage(mw *messageWriter, messageType int) error { - // Close previous writer if not already closed by the application. It's - // probably better to return an error in this situation, but we cannot - // change this without breaking existing applications. - if c.writer != nil { - c.writer.Close() - c.writer = nil - } - - if !isControl(messageType) && !isData(messageType) { - return errBadWriteOpCode - } - - c.writeErrMu.Lock() - err := c.writeErr - c.writeErrMu.Unlock() - if err != nil { - return err - } - - mw.c = c - mw.frameType = messageType - mw.pos = maxFrameHeaderSize - - if c.writeBuf == nil { - wpd, ok := c.writePool.Get().(writePoolData) - if ok { - c.writeBuf = wpd.buf - } else { - c.writeBuf = make([]byte, c.writeBufSize) - } - } - return nil -} - -// NextWriter returns a writer for the next message to send. The writer's Close -// method flushes the complete message to the network. -// -// There can be at most one open writer on a connection. NextWriter closes the -// previous writer if the application has not already done so. -// -// All message types (TextMessage, BinaryMessage, CloseMessage, PingMessage and -// PongMessage) are supported. -func (c *Conn) NextWriter(messageType int) (io.WriteCloser, error) { - var mw messageWriter - if err := c.beginMessage(&mw, messageType); err != nil { - return nil, err - } - c.writer = &mw - if c.newCompressionWriter != nil && c.enableWriteCompression && isData(messageType) { - w := c.newCompressionWriter(c.writer, c.compressionLevel) - mw.compress = true - c.writer = w - } - return c.writer, nil -} - -type messageWriter struct { - c *Conn - compress bool // whether next call to flushFrame should set RSV1 - pos int // end of data in writeBuf. - frameType int // type of the current frame. - err error -} - -func (w *messageWriter) endMessage(err error) error { - if w.err != nil { - return err - } - c := w.c - w.err = err - c.writer = nil - if c.writePool != nil { - c.writePool.Put(writePoolData{buf: c.writeBuf}) - c.writeBuf = nil - } - return err -} - -// flushFrame writes buffered data and extra as a frame to the network. The -// final argument indicates that this is the last frame in the message. -func (w *messageWriter) flushFrame(final bool, extra []byte) error { - c := w.c - length := w.pos - maxFrameHeaderSize + len(extra) - - // Check for invalid control frames. - if isControl(w.frameType) && - (!final || length > maxControlFramePayloadSize) { - return w.endMessage(errInvalidControlFrame) - } - - b0 := byte(w.frameType) - if final { - b0 |= finalBit - } - if w.compress { - b0 |= rsv1Bit - } - w.compress = false - - b1 := byte(0) - if !c.isServer { - b1 |= maskBit - } - - // Assume that the frame starts at beginning of c.writeBuf. - framePos := 0 - if c.isServer { - // Adjust up if mask not included in the header. - framePos = 4 - } - - switch { - case length >= 65536: - c.writeBuf[framePos] = b0 - c.writeBuf[framePos+1] = b1 | 127 - binary.BigEndian.PutUint64(c.writeBuf[framePos+2:], uint64(length)) - case length > 125: - framePos += 6 - c.writeBuf[framePos] = b0 - c.writeBuf[framePos+1] = b1 | 126 - binary.BigEndian.PutUint16(c.writeBuf[framePos+2:], uint16(length)) - default: - framePos += 8 - c.writeBuf[framePos] = b0 - c.writeBuf[framePos+1] = b1 | byte(length) - } - - if !c.isServer { - key := newMaskKey() - copy(c.writeBuf[maxFrameHeaderSize-4:], key[:]) - maskBytes(key, 0, c.writeBuf[maxFrameHeaderSize:w.pos]) - if len(extra) > 0 { - return w.endMessage(c.writeFatal(errors.New("websocket: internal error, extra used in client mode"))) - } - } - - // Write the buffers to the connection with best-effort detection of - // concurrent writes. See the concurrency section in the package - // documentation for more info. - - if c.isWriting { - panic("concurrent write to websocket connection") - } - c.isWriting = true - - err := c.write(w.frameType, c.writeDeadline, c.writeBuf[framePos:w.pos], extra) - - if !c.isWriting { - panic("concurrent write to websocket connection") - } - c.isWriting = false - - if err != nil { - return w.endMessage(err) - } - - if final { - w.endMessage(errWriteClosed) - return nil - } - - // Setup for next frame. - w.pos = maxFrameHeaderSize - w.frameType = continuationFrame - return nil -} - -func (w *messageWriter) ncopy(max int) (int, error) { - n := len(w.c.writeBuf) - w.pos - if n <= 0 { - if err := w.flushFrame(false, nil); err != nil { - return 0, err - } - n = len(w.c.writeBuf) - w.pos - } - if n > max { - n = max - } - return n, nil -} - -func (w *messageWriter) Write(p []byte) (int, error) { - if w.err != nil { - return 0, w.err - } - - if len(p) > 2*len(w.c.writeBuf) && w.c.isServer { - // Don't buffer large messages. - err := w.flushFrame(false, p) - if err != nil { - return 0, err - } - return len(p), nil - } - - nn := len(p) - for len(p) > 0 { - n, err := w.ncopy(len(p)) - if err != nil { - return 0, err - } - copy(w.c.writeBuf[w.pos:], p[:n]) - w.pos += n - p = p[n:] - } - return nn, nil -} - -func (w *messageWriter) WriteString(p string) (int, error) { - if w.err != nil { - return 0, w.err - } - - nn := len(p) - for len(p) > 0 { - n, err := w.ncopy(len(p)) - if err != nil { - return 0, err - } - copy(w.c.writeBuf[w.pos:], p[:n]) - w.pos += n - p = p[n:] - } - return nn, nil -} - -func (w *messageWriter) ReadFrom(r io.Reader) (nn int64, err error) { - if w.err != nil { - return 0, w.err - } - for { - if w.pos == len(w.c.writeBuf) { - err = w.flushFrame(false, nil) - if err != nil { - break - } - } - var n int - n, err = r.Read(w.c.writeBuf[w.pos:]) - w.pos += n - nn += int64(n) - if err != nil { - if err == io.EOF { - err = nil - } - break - } - } - return nn, err -} - -func (w *messageWriter) Close() error { - if w.err != nil { - return w.err - } - return w.flushFrame(true, nil) -} - -// WritePreparedMessage writes prepared message into connection. -func (c *Conn) WritePreparedMessage(pm *PreparedMessage) error { - frameType, frameData, err := pm.frame(prepareKey{ - isServer: c.isServer, - compress: c.newCompressionWriter != nil && c.enableWriteCompression && isData(pm.messageType), - compressionLevel: c.compressionLevel, - }) - if err != nil { - return err - } - if c.isWriting { - panic("concurrent write to websocket connection") - } - c.isWriting = true - err = c.write(frameType, c.writeDeadline, frameData, nil) - if !c.isWriting { - panic("concurrent write to websocket connection") - } - c.isWriting = false - return err -} - -// WriteMessage is a helper method for getting a writer using NextWriter, -// writing the message and closing the writer. -func (c *Conn) WriteMessage(messageType int, data []byte) error { - - if c.isServer && (c.newCompressionWriter == nil || !c.enableWriteCompression) { - // Fast path with no allocations and single frame. - - var mw messageWriter - if err := c.beginMessage(&mw, messageType); err != nil { - return err - } - n := copy(c.writeBuf[mw.pos:], data) - mw.pos += n - data = data[n:] - return mw.flushFrame(true, data) - } - - w, err := c.NextWriter(messageType) - if err != nil { - return err - } - if _, err = w.Write(data); err != nil { - return err - } - return w.Close() -} - -// SetWriteDeadline sets the write deadline on the underlying network -// connection. After a write has timed out, the websocket state is corrupt and -// all future writes will return an error. A zero value for t means writes will -// not time out. -func (c *Conn) SetWriteDeadline(t time.Time) error { - c.writeDeadline = t - return nil -} - -// Read methods - -func (c *Conn) advanceFrame() (int, error) { - // 1. Skip remainder of previous frame. - - if c.readRemaining > 0 { - if _, err := io.CopyN(ioutil.Discard, c.br, c.readRemaining); err != nil { - return noFrame, err - } - } - - // 2. Read and parse first two bytes of frame header. - - p, err := c.read(2) - if err != nil { - return noFrame, err - } - - final := p[0]&finalBit != 0 - frameType := int(p[0] & 0xf) - mask := p[1]&maskBit != 0 - c.setReadRemaining(int64(p[1] & 0x7f)) - - c.readDecompress = false - if c.newDecompressionReader != nil && (p[0]&rsv1Bit) != 0 { - c.readDecompress = true - p[0] &^= rsv1Bit - } - - if rsv := p[0] & (rsv1Bit | rsv2Bit | rsv3Bit); rsv != 0 { - return noFrame, c.handleProtocolError("unexpected reserved bits 0x" + strconv.FormatInt(int64(rsv), 16)) - } - - switch frameType { - case CloseMessage, PingMessage, PongMessage: - if c.readRemaining > maxControlFramePayloadSize { - return noFrame, c.handleProtocolError("control frame length > 125") - } - if !final { - return noFrame, c.handleProtocolError("control frame not final") - } - case TextMessage, BinaryMessage: - if !c.readFinal { - return noFrame, c.handleProtocolError("message start before final message frame") - } - c.readFinal = final - case continuationFrame: - if c.readFinal { - return noFrame, c.handleProtocolError("continuation after final message frame") - } - c.readFinal = final - default: - return noFrame, c.handleProtocolError("unknown opcode " + strconv.Itoa(frameType)) - } - - // 3. Read and parse frame length as per - // https://tools.ietf.org/html/rfc6455#section-5.2 - // - // The length of the "Payload data", in bytes: if 0-125, that is the payload - // length. - // - If 126, the following 2 bytes interpreted as a 16-bit unsigned - // integer are the payload length. - // - If 127, the following 8 bytes interpreted as - // a 64-bit unsigned integer (the most significant bit MUST be 0) are the - // payload length. Multibyte length quantities are expressed in network byte - // order. - - switch c.readRemaining { - case 126: - p, err := c.read(2) - if err != nil { - return noFrame, err - } - - if err := c.setReadRemaining(int64(binary.BigEndian.Uint16(p))); err != nil { - return noFrame, err - } - case 127: - p, err := c.read(8) - if err != nil { - return noFrame, err - } - - if err := c.setReadRemaining(int64(binary.BigEndian.Uint64(p))); err != nil { - return noFrame, err - } - } - - // 4. Handle frame masking. - - if mask != c.isServer { - return noFrame, c.handleProtocolError("incorrect mask flag") - } - - if mask { - c.readMaskPos = 0 - p, err := c.read(len(c.readMaskKey)) - if err != nil { - return noFrame, err - } - copy(c.readMaskKey[:], p) - } - - // 5. For text and binary messages, enforce read limit and return. - - if frameType == continuationFrame || frameType == TextMessage || frameType == BinaryMessage { - - c.readLength += c.readRemaining - // Don't allow readLength to overflow in the presence of a large readRemaining - // counter. - if c.readLength < 0 { - return noFrame, ErrReadLimit - } - - if c.readLimit > 0 && c.readLength > c.readLimit { - c.WriteControl(CloseMessage, FormatCloseMessage(CloseMessageTooBig, ""), time.Now().Add(writeWait)) - return noFrame, ErrReadLimit - } - - return frameType, nil - } - - // 6. Read control frame payload. - - var payload []byte - if c.readRemaining > 0 { - payload, err = c.read(int(c.readRemaining)) - c.setReadRemaining(0) - if err != nil { - return noFrame, err - } - if c.isServer { - maskBytes(c.readMaskKey, 0, payload) - } - } - - // 7. Process control frame payload. - - switch frameType { - case PongMessage: - if err := c.handlePong(string(payload)); err != nil { - return noFrame, err - } - case PingMessage: - if err := c.handlePing(string(payload)); err != nil { - return noFrame, err - } - case CloseMessage: - closeCode := CloseNoStatusReceived - closeText := "" - if len(payload) >= 2 { - closeCode = int(binary.BigEndian.Uint16(payload)) - if !isValidReceivedCloseCode(closeCode) { - return noFrame, c.handleProtocolError("invalid close code") - } - closeText = string(payload[2:]) - if !utf8.ValidString(closeText) { - return noFrame, c.handleProtocolError("invalid utf8 payload in close frame") - } - } - if err := c.handleClose(closeCode, closeText); err != nil { - return noFrame, err - } - return noFrame, &CloseError{Code: closeCode, Text: closeText} - } - - return frameType, nil -} - -func (c *Conn) handleProtocolError(message string) error { - c.WriteControl(CloseMessage, FormatCloseMessage(CloseProtocolError, message), time.Now().Add(writeWait)) - return errors.New("websocket: " + message) -} - -// NextReader returns the next data message received from the peer. The -// returned messageType is either TextMessage or BinaryMessage. -// -// There can be at most one open reader on a connection. NextReader discards -// the previous message if the application has not already consumed it. -// -// Applications must break out of the application's read loop when this method -// returns a non-nil error value. Errors returned from this method are -// permanent. Once this method returns a non-nil error, all subsequent calls to -// this method return the same error. -func (c *Conn) NextReader() (messageType int, r io.Reader, err error) { - // Close previous reader, only relevant for decompression. - if c.reader != nil { - c.reader.Close() - c.reader = nil - } - - c.messageReader = nil - c.readLength = 0 - - for c.readErr == nil { - frameType, err := c.advanceFrame() - if err != nil { - c.readErr = hideTempErr(err) - break - } - - if frameType == TextMessage || frameType == BinaryMessage { - c.messageReader = &messageReader{c} - c.reader = c.messageReader - if c.readDecompress { - c.reader = c.newDecompressionReader(c.reader) - } - return frameType, c.reader, nil - } - } - - // Applications that do handle the error returned from this method spin in - // tight loop on connection failure. To help application developers detect - // this error, panic on repeated reads to the failed connection. - c.readErrCount++ - if c.readErrCount >= 1000 { - panic("repeated read on failed websocket connection") - } - - return noFrame, nil, c.readErr -} - -type messageReader struct{ c *Conn } - -func (r *messageReader) Read(b []byte) (int, error) { - c := r.c - if c.messageReader != r { - return 0, io.EOF - } - - for c.readErr == nil { - - if c.readRemaining > 0 { - if int64(len(b)) > c.readRemaining { - b = b[:c.readRemaining] - } - n, err := c.br.Read(b) - c.readErr = hideTempErr(err) - if c.isServer { - c.readMaskPos = maskBytes(c.readMaskKey, c.readMaskPos, b[:n]) - } - rem := c.readRemaining - rem -= int64(n) - c.setReadRemaining(rem) - if c.readRemaining > 0 && c.readErr == io.EOF { - c.readErr = errUnexpectedEOF - } - return n, c.readErr - } - - if c.readFinal { - c.messageReader = nil - return 0, io.EOF - } - - frameType, err := c.advanceFrame() - switch { - case err != nil: - c.readErr = hideTempErr(err) - case frameType == TextMessage || frameType == BinaryMessage: - c.readErr = errors.New("websocket: internal error, unexpected text or binary in Reader") - } - } - - err := c.readErr - if err == io.EOF && c.messageReader == r { - err = errUnexpectedEOF - } - return 0, err -} - -func (r *messageReader) Close() error { - return nil -} - -// ReadMessage is a helper method for getting a reader using NextReader and -// reading from that reader to a buffer. -func (c *Conn) ReadMessage() (messageType int, p []byte, err error) { - var r io.Reader - messageType, r, err = c.NextReader() - if err != nil { - return messageType, nil, err - } - p, err = ioutil.ReadAll(r) - return messageType, p, err -} - -// SetReadDeadline sets the read deadline on the underlying network connection. -// After a read has timed out, the websocket connection state is corrupt and -// all future reads will return an error. A zero value for t means reads will -// not time out. -func (c *Conn) SetReadDeadline(t time.Time) error { - return c.conn.SetReadDeadline(t) -} - -// SetReadLimit sets the maximum size in bytes for a message read from the peer. If a -// message exceeds the limit, the connection sends a close message to the peer -// and returns ErrReadLimit to the application. -func (c *Conn) SetReadLimit(limit int64) { - c.readLimit = limit -} - -// CloseHandler returns the current close handler -func (c *Conn) CloseHandler() func(code int, text string) error { - return c.handleClose -} - -// SetCloseHandler sets the handler for close messages received from the peer. -// The code argument to h is the received close code or CloseNoStatusReceived -// if the close message is empty. The default close handler sends a close -// message back to the peer. -// -// The handler function is called from the NextReader, ReadMessage and message -// reader Read methods. The application must read the connection to process -// close messages as described in the section on Control Messages above. -// -// The connection read methods return a CloseError when a close message is -// received. Most applications should handle close messages as part of their -// normal error handling. Applications should only set a close handler when the -// application must perform some action before sending a close message back to -// the peer. -func (c *Conn) SetCloseHandler(h func(code int, text string) error) { - if h == nil { - h = func(code int, text string) error { - message := FormatCloseMessage(code, "") - c.WriteControl(CloseMessage, message, time.Now().Add(writeWait)) - return nil - } - } - c.handleClose = h -} - -// PingHandler returns the current ping handler -func (c *Conn) PingHandler() func(appData string) error { - return c.handlePing -} - -// SetPingHandler sets the handler for ping messages received from the peer. -// The appData argument to h is the PING message application data. The default -// ping handler sends a pong to the peer. -// -// The handler function is called from the NextReader, ReadMessage and message -// reader Read methods. The application must read the connection to process -// ping messages as described in the section on Control Messages above. -func (c *Conn) SetPingHandler(h func(appData string) error) { - if h == nil { - h = func(message string) error { - err := c.WriteControl(PongMessage, []byte(message), time.Now().Add(writeWait)) - if err == ErrCloseSent { - return nil - } else if e, ok := err.(net.Error); ok && e.Temporary() { - return nil - } - return err - } - } - c.handlePing = h -} - -// PongHandler returns the current pong handler -func (c *Conn) PongHandler() func(appData string) error { - return c.handlePong -} - -// SetPongHandler sets the handler for pong messages received from the peer. -// The appData argument to h is the PONG message application data. The default -// pong handler does nothing. -// -// The handler function is called from the NextReader, ReadMessage and message -// reader Read methods. The application must read the connection to process -// pong messages as described in the section on Control Messages above. -func (c *Conn) SetPongHandler(h func(appData string) error) { - if h == nil { - h = func(string) error { return nil } - } - c.handlePong = h -} - -// UnderlyingConn returns the internal net.Conn. This can be used to further -// modifications to connection specific flags. -func (c *Conn) UnderlyingConn() net.Conn { - return c.conn -} - -// EnableWriteCompression enables and disables write compression of -// subsequent text and binary messages. This function is a noop if -// compression was not negotiated with the peer. -func (c *Conn) EnableWriteCompression(enable bool) { - c.enableWriteCompression = enable -} - -// SetCompressionLevel sets the flate compression level for subsequent text and -// binary messages. This function is a noop if compression was not negotiated -// with the peer. See the compress/flate package for a description of -// compression levels. -func (c *Conn) SetCompressionLevel(level int) error { - if !isValidCompressionLevel(level) { - return errors.New("websocket: invalid compression level") - } - c.compressionLevel = level - return nil -} - -// FormatCloseMessage formats closeCode and text as a WebSocket close message. -// An empty message is returned for code CloseNoStatusReceived. -func FormatCloseMessage(closeCode int, text string) []byte { - if closeCode == CloseNoStatusReceived { - // Return empty message because it's illegal to send - // CloseNoStatusReceived. Return non-nil value in case application - // checks for nil. - return []byte{} - } - buf := make([]byte, 2+len(text)) - binary.BigEndian.PutUint16(buf, uint16(closeCode)) - copy(buf[2:], text) - return buf -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/conn_write.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/conn_write.go deleted file mode 100644 index a509a21f87a..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/conn_write.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.8 - -package websocket - -import "net" - -func (c *Conn) writeBufs(bufs ...[]byte) error { - b := net.Buffers(bufs) - _, err := b.WriteTo(c.conn) - return err -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/conn_write_legacy.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/conn_write_legacy.go deleted file mode 100644 index 37edaff5a57..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/conn_write_legacy.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !go1.8 - -package websocket - -func (c *Conn) writeBufs(bufs ...[]byte) error { - for _, buf := range bufs { - if len(buf) > 0 { - if _, err := c.conn.Write(buf); err != nil { - return err - } - } - } - return nil -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/doc.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/doc.go deleted file mode 100644 index 8db0cef95a2..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/doc.go +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package websocket implements the WebSocket protocol defined in RFC 6455. -// -// Overview -// -// The Conn type represents a WebSocket connection. A server application calls -// the Upgrader.Upgrade method from an HTTP request handler to get a *Conn: -// -// var upgrader = websocket.Upgrader{ -// ReadBufferSize: 1024, -// WriteBufferSize: 1024, -// } -// -// func handler(w http.ResponseWriter, r *http.Request) { -// conn, err := upgrader.Upgrade(w, r, nil) -// if err != nil { -// log.Println(err) -// return -// } -// ... Use conn to send and receive messages. -// } -// -// Call the connection's WriteMessage and ReadMessage methods to send and -// receive messages as a slice of bytes. This snippet of code shows how to echo -// messages using these methods: -// -// for { -// messageType, p, err := conn.ReadMessage() -// if err != nil { -// log.Println(err) -// return -// } -// if err := conn.WriteMessage(messageType, p); err != nil { -// log.Println(err) -// return -// } -// } -// -// In above snippet of code, p is a []byte and messageType is an int with value -// websocket.BinaryMessage or websocket.TextMessage. -// -// An application can also send and receive messages using the io.WriteCloser -// and io.Reader interfaces. To send a message, call the connection NextWriter -// method to get an io.WriteCloser, write the message to the writer and close -// the writer when done. To receive a message, call the connection NextReader -// method to get an io.Reader and read until io.EOF is returned. This snippet -// shows how to echo messages using the NextWriter and NextReader methods: -// -// for { -// messageType, r, err := conn.NextReader() -// if err != nil { -// return -// } -// w, err := conn.NextWriter(messageType) -// if err != nil { -// return err -// } -// if _, err := io.Copy(w, r); err != nil { -// return err -// } -// if err := w.Close(); err != nil { -// return err -// } -// } -// -// Data Messages -// -// The WebSocket protocol distinguishes between text and binary data messages. -// Text messages are interpreted as UTF-8 encoded text. The interpretation of -// binary messages is left to the application. -// -// This package uses the TextMessage and BinaryMessage integer constants to -// identify the two data message types. The ReadMessage and NextReader methods -// return the type of the received message. The messageType argument to the -// WriteMessage and NextWriter methods specifies the type of a sent message. -// -// It is the application's responsibility to ensure that text messages are -// valid UTF-8 encoded text. -// -// Control Messages -// -// The WebSocket protocol defines three types of control messages: close, ping -// and pong. Call the connection WriteControl, WriteMessage or NextWriter -// methods to send a control message to the peer. -// -// Connections handle received close messages by calling the handler function -// set with the SetCloseHandler method and by returning a *CloseError from the -// NextReader, ReadMessage or the message Read method. The default close -// handler sends a close message to the peer. -// -// Connections handle received ping messages by calling the handler function -// set with the SetPingHandler method. The default ping handler sends a pong -// message to the peer. -// -// Connections handle received pong messages by calling the handler function -// set with the SetPongHandler method. The default pong handler does nothing. -// If an application sends ping messages, then the application should set a -// pong handler to receive the corresponding pong. -// -// The control message handler functions are called from the NextReader, -// ReadMessage and message reader Read methods. The default close and ping -// handlers can block these methods for a short time when the handler writes to -// the connection. -// -// The application must read the connection to process close, ping and pong -// messages sent from the peer. If the application is not otherwise interested -// in messages from the peer, then the application should start a goroutine to -// read and discard messages from the peer. A simple example is: -// -// func readLoop(c *websocket.Conn) { -// for { -// if _, _, err := c.NextReader(); err != nil { -// c.Close() -// break -// } -// } -// } -// -// Concurrency -// -// Connections support one concurrent reader and one concurrent writer. -// -// Applications are responsible for ensuring that no more than one goroutine -// calls the write methods (NextWriter, SetWriteDeadline, WriteMessage, -// WriteJSON, EnableWriteCompression, SetCompressionLevel) concurrently and -// that no more than one goroutine calls the read methods (NextReader, -// SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler, SetPingHandler) -// concurrently. -// -// The Close and WriteControl methods can be called concurrently with all other -// methods. -// -// Origin Considerations -// -// Web browsers allow Javascript applications to open a WebSocket connection to -// any host. It's up to the server to enforce an origin policy using the Origin -// request header sent by the browser. -// -// The Upgrader calls the function specified in the CheckOrigin field to check -// the origin. If the CheckOrigin function returns false, then the Upgrade -// method fails the WebSocket handshake with HTTP status 403. -// -// If the CheckOrigin field is nil, then the Upgrader uses a safe default: fail -// the handshake if the Origin request header is present and the Origin host is -// not equal to the Host request header. -// -// The deprecated package-level Upgrade function does not perform origin -// checking. The application is responsible for checking the Origin header -// before calling the Upgrade function. -// -// Buffers -// -// Connections buffer network input and output to reduce the number -// of system calls when reading or writing messages. -// -// Write buffers are also used for constructing WebSocket frames. See RFC 6455, -// Section 5 for a discussion of message framing. A WebSocket frame header is -// written to the network each time a write buffer is flushed to the network. -// Decreasing the size of the write buffer can increase the amount of framing -// overhead on the connection. -// -// The buffer sizes in bytes are specified by the ReadBufferSize and -// WriteBufferSize fields in the Dialer and Upgrader. The Dialer uses a default -// size of 4096 when a buffer size field is set to zero. The Upgrader reuses -// buffers created by the HTTP server when a buffer size field is set to zero. -// The HTTP server buffers have a size of 4096 at the time of this writing. -// -// The buffer sizes do not limit the size of a message that can be read or -// written by a connection. -// -// Buffers are held for the lifetime of the connection by default. If the -// Dialer or Upgrader WriteBufferPool field is set, then a connection holds the -// write buffer only when writing a message. -// -// Applications should tune the buffer sizes to balance memory use and -// performance. Increasing the buffer size uses more memory, but can reduce the -// number of system calls to read or write the network. In the case of writing, -// increasing the buffer size can reduce the number of frame headers written to -// the network. -// -// Some guidelines for setting buffer parameters are: -// -// Limit the buffer sizes to the maximum expected message size. Buffers larger -// than the largest message do not provide any benefit. -// -// Depending on the distribution of message sizes, setting the buffer size to -// a value less than the maximum expected message size can greatly reduce memory -// use with a small impact on performance. Here's an example: If 99% of the -// messages are smaller than 256 bytes and the maximum message size is 512 -// bytes, then a buffer size of 256 bytes will result in 1.01 more system calls -// than a buffer size of 512 bytes. The memory savings is 50%. -// -// A write buffer pool is useful when the application has a modest number -// writes over a large number of connections. when buffers are pooled, a larger -// buffer size has a reduced impact on total memory use and has the benefit of -// reducing system calls and frame overhead. -// -// Compression EXPERIMENTAL -// -// Per message compression extensions (RFC 7692) are experimentally supported -// by this package in a limited capacity. Setting the EnableCompression option -// to true in Dialer or Upgrader will attempt to negotiate per message deflate -// support. -// -// var upgrader = websocket.Upgrader{ -// EnableCompression: true, -// } -// -// If compression was successfully negotiated with the connection's peer, any -// message received in compressed form will be automatically decompressed. -// All Read methods will return uncompressed bytes. -// -// Per message compression of messages written to a connection can be enabled -// or disabled by calling the corresponding Conn method: -// -// conn.EnableWriteCompression(false) -// -// Currently this package does not support compression with "context takeover". -// This means that messages must be compressed and decompressed in isolation, -// without retaining sliding window or dictionary state across messages. For -// more details refer to RFC 7692. -// -// Use of compression is experimental and may result in decreased performance. -package websocket diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/go.mod b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/go.mod deleted file mode 100644 index 1a7afd5028a..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/go.mod +++ /dev/null @@ -1,3 +0,0 @@ -module github.com/gorilla/websocket - -go 1.12 diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/join.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/join.go deleted file mode 100644 index c64f8c82901..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/join.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2019 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -import ( - "io" - "strings" -) - -// JoinMessages concatenates received messages to create a single io.Reader. -// The string term is appended to each message. The returned reader does not -// support concurrent calls to the Read method. -func JoinMessages(c *Conn, term string) io.Reader { - return &joinReader{c: c, term: term} -} - -type joinReader struct { - c *Conn - term string - r io.Reader -} - -func (r *joinReader) Read(p []byte) (int, error) { - if r.r == nil { - var err error - _, r.r, err = r.c.NextReader() - if err != nil { - return 0, err - } - if r.term != "" { - r.r = io.MultiReader(r.r, strings.NewReader(r.term)) - } - } - n, err := r.r.Read(p) - if err == io.EOF { - err = nil - r.r = nil - } - return n, err -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/json.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/json.go deleted file mode 100644 index dc2c1f6415f..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/json.go +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -import ( - "encoding/json" - "io" -) - -// WriteJSON writes the JSON encoding of v as a message. -// -// Deprecated: Use c.WriteJSON instead. -func WriteJSON(c *Conn, v interface{}) error { - return c.WriteJSON(v) -} - -// WriteJSON writes the JSON encoding of v as a message. -// -// See the documentation for encoding/json Marshal for details about the -// conversion of Go values to JSON. -func (c *Conn) WriteJSON(v interface{}) error { - w, err := c.NextWriter(TextMessage) - if err != nil { - return err - } - err1 := json.NewEncoder(w).Encode(v) - err2 := w.Close() - if err1 != nil { - return err1 - } - return err2 -} - -// ReadJSON reads the next JSON-encoded message from the connection and stores -// it in the value pointed to by v. -// -// Deprecated: Use c.ReadJSON instead. -func ReadJSON(c *Conn, v interface{}) error { - return c.ReadJSON(v) -} - -// ReadJSON reads the next JSON-encoded message from the connection and stores -// it in the value pointed to by v. -// -// See the documentation for the encoding/json Unmarshal function for details -// about the conversion of JSON to a Go value. -func (c *Conn) ReadJSON(v interface{}) error { - _, r, err := c.NextReader() - if err != nil { - return err - } - err = json.NewDecoder(r).Decode(v) - if err == io.EOF { - // One value is expected in the message. - err = io.ErrUnexpectedEOF - } - return err -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/mask.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/mask.go deleted file mode 100644 index 577fce9efd7..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/mask.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. Use of -// this source code is governed by a BSD-style license that can be found in the -// LICENSE file. - -// +build !appengine - -package websocket - -import "unsafe" - -const wordSize = int(unsafe.Sizeof(uintptr(0))) - -func maskBytes(key [4]byte, pos int, b []byte) int { - // Mask one byte at a time for small buffers. - if len(b) < 2*wordSize { - for i := range b { - b[i] ^= key[pos&3] - pos++ - } - return pos & 3 - } - - // Mask one byte at a time to word boundary. - if n := int(uintptr(unsafe.Pointer(&b[0]))) % wordSize; n != 0 { - n = wordSize - n - for i := range b[:n] { - b[i] ^= key[pos&3] - pos++ - } - b = b[n:] - } - - // Create aligned word size key. - var k [wordSize]byte - for i := range k { - k[i] = key[(pos+i)&3] - } - kw := *(*uintptr)(unsafe.Pointer(&k)) - - // Mask one word at a time. - n := (len(b) / wordSize) * wordSize - for i := 0; i < n; i += wordSize { - *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&b[0])) + uintptr(i))) ^= kw - } - - // Mask one byte at a time for remaining bytes. - b = b[n:] - for i := range b { - b[i] ^= key[pos&3] - pos++ - } - - return pos & 3 -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/mask_safe.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/mask_safe.go deleted file mode 100644 index 2aac060e52e..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/mask_safe.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. Use of -// this source code is governed by a BSD-style license that can be found in the -// LICENSE file. - -// +build appengine - -package websocket - -func maskBytes(key [4]byte, pos int, b []byte) int { - for i := range b { - b[i] ^= key[pos&3] - pos++ - } - return pos & 3 -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/prepared.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/prepared.go deleted file mode 100644 index c854225e967..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/prepared.go +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -import ( - "bytes" - "net" - "sync" - "time" -) - -// PreparedMessage caches on the wire representations of a message payload. -// Use PreparedMessage to efficiently send a message payload to multiple -// connections. PreparedMessage is especially useful when compression is used -// because the CPU and memory expensive compression operation can be executed -// once for a given set of compression options. -type PreparedMessage struct { - messageType int - data []byte - mu sync.Mutex - frames map[prepareKey]*preparedFrame -} - -// prepareKey defines a unique set of options to cache prepared frames in PreparedMessage. -type prepareKey struct { - isServer bool - compress bool - compressionLevel int -} - -// preparedFrame contains data in wire representation. -type preparedFrame struct { - once sync.Once - data []byte -} - -// NewPreparedMessage returns an initialized PreparedMessage. You can then send -// it to connection using WritePreparedMessage method. Valid wire -// representation will be calculated lazily only once for a set of current -// connection options. -func NewPreparedMessage(messageType int, data []byte) (*PreparedMessage, error) { - pm := &PreparedMessage{ - messageType: messageType, - frames: make(map[prepareKey]*preparedFrame), - data: data, - } - - // Prepare a plain server frame. - _, frameData, err := pm.frame(prepareKey{isServer: true, compress: false}) - if err != nil { - return nil, err - } - - // To protect against caller modifying the data argument, remember the data - // copied to the plain server frame. - pm.data = frameData[len(frameData)-len(data):] - return pm, nil -} - -func (pm *PreparedMessage) frame(key prepareKey) (int, []byte, error) { - pm.mu.Lock() - frame, ok := pm.frames[key] - if !ok { - frame = &preparedFrame{} - pm.frames[key] = frame - } - pm.mu.Unlock() - - var err error - frame.once.Do(func() { - // Prepare a frame using a 'fake' connection. - // TODO: Refactor code in conn.go to allow more direct construction of - // the frame. - mu := make(chan struct{}, 1) - mu <- struct{}{} - var nc prepareConn - c := &Conn{ - conn: &nc, - mu: mu, - isServer: key.isServer, - compressionLevel: key.compressionLevel, - enableWriteCompression: true, - writeBuf: make([]byte, defaultWriteBufferSize+maxFrameHeaderSize), - } - if key.compress { - c.newCompressionWriter = compressNoContextTakeover - } - err = c.WriteMessage(pm.messageType, pm.data) - frame.data = nc.buf.Bytes() - }) - return pm.messageType, frame.data, err -} - -type prepareConn struct { - buf bytes.Buffer - net.Conn -} - -func (pc *prepareConn) Write(p []byte) (int, error) { return pc.buf.Write(p) } -func (pc *prepareConn) SetWriteDeadline(t time.Time) error { return nil } diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/proxy.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/proxy.go deleted file mode 100644 index e87a8c9f0c9..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/proxy.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -import ( - "bufio" - "encoding/base64" - "errors" - "net" - "net/http" - "net/url" - "strings" -) - -type netDialerFunc func(network, addr string) (net.Conn, error) - -func (fn netDialerFunc) Dial(network, addr string) (net.Conn, error) { - return fn(network, addr) -} - -func init() { - proxy_RegisterDialerType("http", func(proxyURL *url.URL, forwardDialer proxy_Dialer) (proxy_Dialer, error) { - return &httpProxyDialer{proxyURL: proxyURL, forwardDial: forwardDialer.Dial}, nil - }) -} - -type httpProxyDialer struct { - proxyURL *url.URL - forwardDial func(network, addr string) (net.Conn, error) -} - -func (hpd *httpProxyDialer) Dial(network string, addr string) (net.Conn, error) { - hostPort, _ := hostPortNoPort(hpd.proxyURL) - conn, err := hpd.forwardDial(network, hostPort) - if err != nil { - return nil, err - } - - connectHeader := make(http.Header) - if user := hpd.proxyURL.User; user != nil { - proxyUser := user.Username() - if proxyPassword, passwordSet := user.Password(); passwordSet { - credential := base64.StdEncoding.EncodeToString([]byte(proxyUser + ":" + proxyPassword)) - connectHeader.Set("Proxy-Authorization", "Basic "+credential) - } - } - - connectReq := &http.Request{ - Method: "CONNECT", - URL: &url.URL{Opaque: addr}, - Host: addr, - Header: connectHeader, - } - - if err := connectReq.Write(conn); err != nil { - conn.Close() - return nil, err - } - - // Read response. It's OK to use and discard buffered reader here becaue - // the remote server does not speak until spoken to. - br := bufio.NewReader(conn) - resp, err := http.ReadResponse(br, connectReq) - if err != nil { - conn.Close() - return nil, err - } - - if resp.StatusCode != 200 { - conn.Close() - f := strings.SplitN(resp.Status, " ", 2) - return nil, errors.New(f[1]) - } - return conn, nil -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/server.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/server.go deleted file mode 100644 index 887d558918c..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/server.go +++ /dev/null @@ -1,363 +0,0 @@ -// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -import ( - "bufio" - "errors" - "io" - "net/http" - "net/url" - "strings" - "time" -) - -// HandshakeError describes an error with the handshake from the peer. -type HandshakeError struct { - message string -} - -func (e HandshakeError) Error() string { return e.message } - -// Upgrader specifies parameters for upgrading an HTTP connection to a -// WebSocket connection. -type Upgrader struct { - // HandshakeTimeout specifies the duration for the handshake to complete. - HandshakeTimeout time.Duration - - // ReadBufferSize and WriteBufferSize specify I/O buffer sizes in bytes. If a buffer - // size is zero, then buffers allocated by the HTTP server are used. The - // I/O buffer sizes do not limit the size of the messages that can be sent - // or received. - ReadBufferSize, WriteBufferSize int - - // WriteBufferPool is a pool of buffers for write operations. If the value - // is not set, then write buffers are allocated to the connection for the - // lifetime of the connection. - // - // A pool is most useful when the application has a modest volume of writes - // across a large number of connections. - // - // Applications should use a single pool for each unique value of - // WriteBufferSize. - WriteBufferPool BufferPool - - // Subprotocols specifies the server's supported protocols in order of - // preference. If this field is not nil, then the Upgrade method negotiates a - // subprotocol by selecting the first match in this list with a protocol - // requested by the client. If there's no match, then no protocol is - // negotiated (the Sec-Websocket-Protocol header is not included in the - // handshake response). - Subprotocols []string - - // Error specifies the function for generating HTTP error responses. If Error - // is nil, then http.Error is used to generate the HTTP response. - Error func(w http.ResponseWriter, r *http.Request, status int, reason error) - - // CheckOrigin returns true if the request Origin header is acceptable. If - // CheckOrigin is nil, then a safe default is used: return false if the - // Origin request header is present and the origin host is not equal to - // request Host header. - // - // A CheckOrigin function should carefully validate the request origin to - // prevent cross-site request forgery. - CheckOrigin func(r *http.Request) bool - - // EnableCompression specify if the server should attempt to negotiate per - // message compression (RFC 7692). Setting this value to true does not - // guarantee that compression will be supported. Currently only "no context - // takeover" modes are supported. - EnableCompression bool -} - -func (u *Upgrader) returnError(w http.ResponseWriter, r *http.Request, status int, reason string) (*Conn, error) { - err := HandshakeError{reason} - if u.Error != nil { - u.Error(w, r, status, err) - } else { - w.Header().Set("Sec-Websocket-Version", "13") - http.Error(w, http.StatusText(status), status) - } - return nil, err -} - -// checkSameOrigin returns true if the origin is not set or is equal to the request host. -func checkSameOrigin(r *http.Request) bool { - origin := r.Header["Origin"] - if len(origin) == 0 { - return true - } - u, err := url.Parse(origin[0]) - if err != nil { - return false - } - return equalASCIIFold(u.Host, r.Host) -} - -func (u *Upgrader) selectSubprotocol(r *http.Request, responseHeader http.Header) string { - if u.Subprotocols != nil { - clientProtocols := Subprotocols(r) - for _, serverProtocol := range u.Subprotocols { - for _, clientProtocol := range clientProtocols { - if clientProtocol == serverProtocol { - return clientProtocol - } - } - } - } else if responseHeader != nil { - return responseHeader.Get("Sec-Websocket-Protocol") - } - return "" -} - -// Upgrade upgrades the HTTP server connection to the WebSocket protocol. -// -// The responseHeader is included in the response to the client's upgrade -// request. Use the responseHeader to specify cookies (Set-Cookie) and the -// application negotiated subprotocol (Sec-WebSocket-Protocol). -// -// If the upgrade fails, then Upgrade replies to the client with an HTTP error -// response. -func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header) (*Conn, error) { - const badHandshake = "websocket: the client is not using the websocket protocol: " - - if !tokenListContainsValue(r.Header, "Connection", "upgrade") { - return u.returnError(w, r, http.StatusBadRequest, badHandshake+"'upgrade' token not found in 'Connection' header") - } - - if !tokenListContainsValue(r.Header, "Upgrade", "websocket") { - return u.returnError(w, r, http.StatusBadRequest, badHandshake+"'websocket' token not found in 'Upgrade' header") - } - - if r.Method != "GET" { - return u.returnError(w, r, http.StatusMethodNotAllowed, badHandshake+"request method is not GET") - } - - if !tokenListContainsValue(r.Header, "Sec-Websocket-Version", "13") { - return u.returnError(w, r, http.StatusBadRequest, "websocket: unsupported version: 13 not found in 'Sec-Websocket-Version' header") - } - - if _, ok := responseHeader["Sec-Websocket-Extensions"]; ok { - return u.returnError(w, r, http.StatusInternalServerError, "websocket: application specific 'Sec-WebSocket-Extensions' headers are unsupported") - } - - checkOrigin := u.CheckOrigin - if checkOrigin == nil { - checkOrigin = checkSameOrigin - } - if !checkOrigin(r) { - return u.returnError(w, r, http.StatusForbidden, "websocket: request origin not allowed by Upgrader.CheckOrigin") - } - - challengeKey := r.Header.Get("Sec-Websocket-Key") - if challengeKey == "" { - return u.returnError(w, r, http.StatusBadRequest, "websocket: not a websocket handshake: 'Sec-WebSocket-Key' header is missing or blank") - } - - subprotocol := u.selectSubprotocol(r, responseHeader) - - // Negotiate PMCE - var compress bool - if u.EnableCompression { - for _, ext := range parseExtensions(r.Header) { - if ext[""] != "permessage-deflate" { - continue - } - compress = true - break - } - } - - h, ok := w.(http.Hijacker) - if !ok { - return u.returnError(w, r, http.StatusInternalServerError, "websocket: response does not implement http.Hijacker") - } - var brw *bufio.ReadWriter - netConn, brw, err := h.Hijack() - if err != nil { - return u.returnError(w, r, http.StatusInternalServerError, err.Error()) - } - - if brw.Reader.Buffered() > 0 { - netConn.Close() - return nil, errors.New("websocket: client sent data before handshake is complete") - } - - var br *bufio.Reader - if u.ReadBufferSize == 0 && bufioReaderSize(netConn, brw.Reader) > 256 { - // Reuse hijacked buffered reader as connection reader. - br = brw.Reader - } - - buf := bufioWriterBuffer(netConn, brw.Writer) - - var writeBuf []byte - if u.WriteBufferPool == nil && u.WriteBufferSize == 0 && len(buf) >= maxFrameHeaderSize+256 { - // Reuse hijacked write buffer as connection buffer. - writeBuf = buf - } - - c := newConn(netConn, true, u.ReadBufferSize, u.WriteBufferSize, u.WriteBufferPool, br, writeBuf) - c.subprotocol = subprotocol - - if compress { - c.newCompressionWriter = compressNoContextTakeover - c.newDecompressionReader = decompressNoContextTakeover - } - - // Use larger of hijacked buffer and connection write buffer for header. - p := buf - if len(c.writeBuf) > len(p) { - p = c.writeBuf - } - p = p[:0] - - p = append(p, "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "...) - p = append(p, computeAcceptKey(challengeKey)...) - p = append(p, "\r\n"...) - if c.subprotocol != "" { - p = append(p, "Sec-WebSocket-Protocol: "...) - p = append(p, c.subprotocol...) - p = append(p, "\r\n"...) - } - if compress { - p = append(p, "Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover\r\n"...) - } - for k, vs := range responseHeader { - if k == "Sec-Websocket-Protocol" { - continue - } - for _, v := range vs { - p = append(p, k...) - p = append(p, ": "...) - for i := 0; i < len(v); i++ { - b := v[i] - if b <= 31 { - // prevent response splitting. - b = ' ' - } - p = append(p, b) - } - p = append(p, "\r\n"...) - } - } - p = append(p, "\r\n"...) - - // Clear deadlines set by HTTP server. - netConn.SetDeadline(time.Time{}) - - if u.HandshakeTimeout > 0 { - netConn.SetWriteDeadline(time.Now().Add(u.HandshakeTimeout)) - } - if _, err = netConn.Write(p); err != nil { - netConn.Close() - return nil, err - } - if u.HandshakeTimeout > 0 { - netConn.SetWriteDeadline(time.Time{}) - } - - return c, nil -} - -// Upgrade upgrades the HTTP server connection to the WebSocket protocol. -// -// Deprecated: Use websocket.Upgrader instead. -// -// Upgrade does not perform origin checking. The application is responsible for -// checking the Origin header before calling Upgrade. An example implementation -// of the same origin policy check is: -// -// if req.Header.Get("Origin") != "http://"+req.Host { -// http.Error(w, "Origin not allowed", http.StatusForbidden) -// return -// } -// -// If the endpoint supports subprotocols, then the application is responsible -// for negotiating the protocol used on the connection. Use the Subprotocols() -// function to get the subprotocols requested by the client. Use the -// Sec-Websocket-Protocol response header to specify the subprotocol selected -// by the application. -// -// The responseHeader is included in the response to the client's upgrade -// request. Use the responseHeader to specify cookies (Set-Cookie) and the -// negotiated subprotocol (Sec-Websocket-Protocol). -// -// The connection buffers IO to the underlying network connection. The -// readBufSize and writeBufSize parameters specify the size of the buffers to -// use. Messages can be larger than the buffers. -// -// If the request is not a valid WebSocket handshake, then Upgrade returns an -// error of type HandshakeError. Applications should handle this error by -// replying to the client with an HTTP error response. -func Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header, readBufSize, writeBufSize int) (*Conn, error) { - u := Upgrader{ReadBufferSize: readBufSize, WriteBufferSize: writeBufSize} - u.Error = func(w http.ResponseWriter, r *http.Request, status int, reason error) { - // don't return errors to maintain backwards compatibility - } - u.CheckOrigin = func(r *http.Request) bool { - // allow all connections by default - return true - } - return u.Upgrade(w, r, responseHeader) -} - -// Subprotocols returns the subprotocols requested by the client in the -// Sec-Websocket-Protocol header. -func Subprotocols(r *http.Request) []string { - h := strings.TrimSpace(r.Header.Get("Sec-Websocket-Protocol")) - if h == "" { - return nil - } - protocols := strings.Split(h, ",") - for i := range protocols { - protocols[i] = strings.TrimSpace(protocols[i]) - } - return protocols -} - -// IsWebSocketUpgrade returns true if the client requested upgrade to the -// WebSocket protocol. -func IsWebSocketUpgrade(r *http.Request) bool { - return tokenListContainsValue(r.Header, "Connection", "upgrade") && - tokenListContainsValue(r.Header, "Upgrade", "websocket") -} - -// bufioReaderSize size returns the size of a bufio.Reader. -func bufioReaderSize(originalReader io.Reader, br *bufio.Reader) int { - // This code assumes that peek on a reset reader returns - // bufio.Reader.buf[:0]. - // TODO: Use bufio.Reader.Size() after Go 1.10 - br.Reset(originalReader) - if p, err := br.Peek(0); err == nil { - return cap(p) - } - return 0 -} - -// writeHook is an io.Writer that records the last slice passed to it vio -// io.Writer.Write. -type writeHook struct { - p []byte -} - -func (wh *writeHook) Write(p []byte) (int, error) { - wh.p = p - return len(p), nil -} - -// bufioWriterBuffer grabs the buffer from a bufio.Writer. -func bufioWriterBuffer(originalWriter io.Writer, bw *bufio.Writer) []byte { - // This code assumes that bufio.Writer.buf[:1] is passed to the - // bufio.Writer's underlying writer. - var wh writeHook - bw.Reset(&wh) - bw.WriteByte(0) - bw.Flush() - - bw.Reset(originalWriter) - - return wh.p[:cap(wh.p)] -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/stub.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/stub.go new file mode 100644 index 00000000000..0be1589cca9 --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/stub.go @@ -0,0 +1,135 @@ +// Code generated by depstubber. DO NOT EDIT. +// This is a simple stub for github.com/gorilla/websocket, strictly for use in testing. + +// See the LICENSE file for information about the licensing of the original library. +// Source: github.com/gorilla/websocket (exports: Dialer; functions: ) + +// Package websocket is a stub of github.com/gorilla/websocket, generated by depstubber. +package websocket + +import ( + context "context" + tls "crypto/tls" + io "io" + net "net" + http "net/http" + url "net/url" + time "time" +) + +type BufferPool interface { + Get() interface{} + Put(_ interface{}) +} + +type Conn struct{} + +func (_ *Conn) Close() error { + return nil +} + +func (_ *Conn) CloseHandler() func(int, string) error { + return nil +} + +func (_ *Conn) EnableWriteCompression(_ bool) {} + +func (_ *Conn) LocalAddr() net.Addr { + return nil +} + +func (_ *Conn) NextReader() (int, io.Reader, error) { + return 0, nil, nil +} + +func (_ *Conn) NextWriter(_ int) (io.WriteCloser, error) { + return nil, nil +} + +func (_ *Conn) PingHandler() func(string) error { + return nil +} + +func (_ *Conn) PongHandler() func(string) error { + return nil +} + +func (_ *Conn) ReadJSON(_ interface{}) error { + return nil +} + +func (_ *Conn) ReadMessage() (int, []byte, error) { + return 0, nil, nil +} + +func (_ *Conn) RemoteAddr() net.Addr { + return nil +} + +func (_ *Conn) SetCloseHandler(_ func(int, string) error) {} + +func (_ *Conn) SetCompressionLevel(_ int) error { + return nil +} + +func (_ *Conn) SetPingHandler(_ func(string) error) {} + +func (_ *Conn) SetPongHandler(_ func(string) error) {} + +func (_ *Conn) SetReadDeadline(_ time.Time) error { + return nil +} + +func (_ *Conn) SetReadLimit(_ int64) {} + +func (_ *Conn) SetWriteDeadline(_ time.Time) error { + return nil +} + +func (_ *Conn) Subprotocol() string { + return "" +} + +func (_ *Conn) UnderlyingConn() net.Conn { + return nil +} + +func (_ *Conn) WriteControl(_ int, _ []byte, _ time.Time) error { + return nil +} + +func (_ *Conn) WriteJSON(_ interface{}) error { + return nil +} + +func (_ *Conn) WriteMessage(_ int, _ []byte) error { + return nil +} + +func (_ *Conn) WritePreparedMessage(_ *PreparedMessage) error { + return nil +} + +type Dialer struct { + NetDial func(string, string) (net.Conn, error) + NetDialContext func(context.Context, string, string) (net.Conn, error) + Proxy func(*http.Request) (*url.URL, error) + TLSClientConfig *tls.Config + HandshakeTimeout time.Duration + ReadBufferSize int + WriteBufferSize int + WriteBufferPool BufferPool + Subprotocols []string + EnableCompression bool + Jar http.CookieJar +} + +func (_ *Dialer) Dial(_ string, _ http.Header) (*Conn, *http.Response, error) { + return nil, nil, nil +} + +func (_ *Dialer) DialContext(_ context.Context, _ string, _ http.Header) (*Conn, *http.Response, error) { + return nil, nil, nil +} + +type PreparedMessage struct{} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/trace.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/trace.go deleted file mode 100644 index 834f122a00d..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/trace.go +++ /dev/null @@ -1,19 +0,0 @@ -// +build go1.8 - -package websocket - -import ( - "crypto/tls" - "net/http/httptrace" -) - -func doHandshakeWithTrace(trace *httptrace.ClientTrace, tlsConn *tls.Conn, cfg *tls.Config) error { - if trace.TLSHandshakeStart != nil { - trace.TLSHandshakeStart() - } - err := doHandshake(tlsConn, cfg) - if trace.TLSHandshakeDone != nil { - trace.TLSHandshakeDone(tlsConn.ConnectionState(), err) - } - return err -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/trace_17.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/trace_17.go deleted file mode 100644 index 77d05a0b574..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/trace_17.go +++ /dev/null @@ -1,12 +0,0 @@ -// +build !go1.8 - -package websocket - -import ( - "crypto/tls" - "net/http/httptrace" -) - -func doHandshakeWithTrace(trace *httptrace.ClientTrace, tlsConn *tls.Conn, cfg *tls.Config) error { - return doHandshake(tlsConn, cfg) -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/util.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/util.go deleted file mode 100644 index 7bf2f66c674..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/util.go +++ /dev/null @@ -1,283 +0,0 @@ -// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -import ( - "crypto/rand" - "crypto/sha1" - "encoding/base64" - "io" - "net/http" - "strings" - "unicode/utf8" -) - -var keyGUID = []byte("258EAFA5-E914-47DA-95CA-C5AB0DC85B11") - -func computeAcceptKey(challengeKey string) string { - h := sha1.New() - h.Write([]byte(challengeKey)) - h.Write(keyGUID) - return base64.StdEncoding.EncodeToString(h.Sum(nil)) -} - -func generateChallengeKey() (string, error) { - p := make([]byte, 16) - if _, err := io.ReadFull(rand.Reader, p); err != nil { - return "", err - } - return base64.StdEncoding.EncodeToString(p), nil -} - -// Token octets per RFC 2616. -var isTokenOctet = [256]bool{ - '!': true, - '#': true, - '$': true, - '%': true, - '&': true, - '\'': true, - '*': true, - '+': true, - '-': true, - '.': true, - '0': true, - '1': true, - '2': true, - '3': true, - '4': true, - '5': true, - '6': true, - '7': true, - '8': true, - '9': true, - 'A': true, - 'B': true, - 'C': true, - 'D': true, - 'E': true, - 'F': true, - 'G': true, - 'H': true, - 'I': true, - 'J': true, - 'K': true, - 'L': true, - 'M': true, - 'N': true, - 'O': true, - 'P': true, - 'Q': true, - 'R': true, - 'S': true, - 'T': true, - 'U': true, - 'W': true, - 'V': true, - 'X': true, - 'Y': true, - 'Z': true, - '^': true, - '_': true, - '`': true, - 'a': true, - 'b': true, - 'c': true, - 'd': true, - 'e': true, - 'f': true, - 'g': true, - 'h': true, - 'i': true, - 'j': true, - 'k': true, - 'l': true, - 'm': true, - 'n': true, - 'o': true, - 'p': true, - 'q': true, - 'r': true, - 's': true, - 't': true, - 'u': true, - 'v': true, - 'w': true, - 'x': true, - 'y': true, - 'z': true, - '|': true, - '~': true, -} - -// skipSpace returns a slice of the string s with all leading RFC 2616 linear -// whitespace removed. -func skipSpace(s string) (rest string) { - i := 0 - for ; i < len(s); i++ { - if b := s[i]; b != ' ' && b != '\t' { - break - } - } - return s[i:] -} - -// nextToken returns the leading RFC 2616 token of s and the string following -// the token. -func nextToken(s string) (token, rest string) { - i := 0 - for ; i < len(s); i++ { - if !isTokenOctet[s[i]] { - break - } - } - return s[:i], s[i:] -} - -// nextTokenOrQuoted returns the leading token or quoted string per RFC 2616 -// and the string following the token or quoted string. -func nextTokenOrQuoted(s string) (value string, rest string) { - if !strings.HasPrefix(s, "\"") { - return nextToken(s) - } - s = s[1:] - for i := 0; i < len(s); i++ { - switch s[i] { - case '"': - return s[:i], s[i+1:] - case '\\': - p := make([]byte, len(s)-1) - j := copy(p, s[:i]) - escape := true - for i = i + 1; i < len(s); i++ { - b := s[i] - switch { - case escape: - escape = false - p[j] = b - j++ - case b == '\\': - escape = true - case b == '"': - return string(p[:j]), s[i+1:] - default: - p[j] = b - j++ - } - } - return "", "" - } - } - return "", "" -} - -// equalASCIIFold returns true if s is equal to t with ASCII case folding as -// defined in RFC 4790. -func equalASCIIFold(s, t string) bool { - for s != "" && t != "" { - sr, size := utf8.DecodeRuneInString(s) - s = s[size:] - tr, size := utf8.DecodeRuneInString(t) - t = t[size:] - if sr == tr { - continue - } - if 'A' <= sr && sr <= 'Z' { - sr = sr + 'a' - 'A' - } - if 'A' <= tr && tr <= 'Z' { - tr = tr + 'a' - 'A' - } - if sr != tr { - return false - } - } - return s == t -} - -// tokenListContainsValue returns true if the 1#token header with the given -// name contains a token equal to value with ASCII case folding. -func tokenListContainsValue(header http.Header, name string, value string) bool { -headers: - for _, s := range header[name] { - for { - var t string - t, s = nextToken(skipSpace(s)) - if t == "" { - continue headers - } - s = skipSpace(s) - if s != "" && s[0] != ',' { - continue headers - } - if equalASCIIFold(t, value) { - return true - } - if s == "" { - continue headers - } - s = s[1:] - } - } - return false -} - -// parseExtensions parses WebSocket extensions from a header. -func parseExtensions(header http.Header) []map[string]string { - // From RFC 6455: - // - // Sec-WebSocket-Extensions = extension-list - // extension-list = 1#extension - // extension = extension-token *( ";" extension-param ) - // extension-token = registered-token - // registered-token = token - // extension-param = token [ "=" (token | quoted-string) ] - // ;When using the quoted-string syntax variant, the value - // ;after quoted-string unescaping MUST conform to the - // ;'token' ABNF. - - var result []map[string]string -headers: - for _, s := range header["Sec-Websocket-Extensions"] { - for { - var t string - t, s = nextToken(skipSpace(s)) - if t == "" { - continue headers - } - ext := map[string]string{"": t} - for { - s = skipSpace(s) - if !strings.HasPrefix(s, ";") { - break - } - var k string - k, s = nextToken(skipSpace(s[1:])) - if k == "" { - continue headers - } - s = skipSpace(s) - var v string - if strings.HasPrefix(s, "=") { - v, s = nextTokenOrQuoted(skipSpace(s[1:])) - s = skipSpace(s) - } - if s != "" && s[0] != ',' && s[0] != ';' { - continue headers - } - ext[k] = v - } - if s != "" && s[0] != ',' { - continue headers - } - result = append(result, ext) - if s == "" { - continue headers - } - s = s[1:] - } - } - return result -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/x_net_proxy.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/x_net_proxy.go deleted file mode 100644 index 2e668f6b882..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/gorilla/websocket/x_net_proxy.go +++ /dev/null @@ -1,473 +0,0 @@ -// Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT. -//go:generate bundle -o x_net_proxy.go golang.org/x/net/proxy - -// Package proxy provides support for a variety of protocols to proxy network -// data. -// - -package websocket - -import ( - "errors" - "io" - "net" - "net/url" - "os" - "strconv" - "strings" - "sync" -) - -type proxy_direct struct{} - -// Direct is a direct proxy: one that makes network connections directly. -var proxy_Direct = proxy_direct{} - -func (proxy_direct) Dial(network, addr string) (net.Conn, error) { - return net.Dial(network, addr) -} - -// A PerHost directs connections to a default Dialer unless the host name -// requested matches one of a number of exceptions. -type proxy_PerHost struct { - def, bypass proxy_Dialer - - bypassNetworks []*net.IPNet - bypassIPs []net.IP - bypassZones []string - bypassHosts []string -} - -// NewPerHost returns a PerHost Dialer that directs connections to either -// defaultDialer or bypass, depending on whether the connection matches one of -// the configured rules. -func proxy_NewPerHost(defaultDialer, bypass proxy_Dialer) *proxy_PerHost { - return &proxy_PerHost{ - def: defaultDialer, - bypass: bypass, - } -} - -// Dial connects to the address addr on the given network through either -// defaultDialer or bypass. -func (p *proxy_PerHost) Dial(network, addr string) (c net.Conn, err error) { - host, _, err := net.SplitHostPort(addr) - if err != nil { - return nil, err - } - - return p.dialerForRequest(host).Dial(network, addr) -} - -func (p *proxy_PerHost) dialerForRequest(host string) proxy_Dialer { - if ip := net.ParseIP(host); ip != nil { - for _, net := range p.bypassNetworks { - if net.Contains(ip) { - return p.bypass - } - } - for _, bypassIP := range p.bypassIPs { - if bypassIP.Equal(ip) { - return p.bypass - } - } - return p.def - } - - for _, zone := range p.bypassZones { - if strings.HasSuffix(host, zone) { - return p.bypass - } - if host == zone[1:] { - // For a zone ".example.com", we match "example.com" - // too. - return p.bypass - } - } - for _, bypassHost := range p.bypassHosts { - if bypassHost == host { - return p.bypass - } - } - return p.def -} - -// AddFromString parses a string that contains comma-separated values -// specifying hosts that should use the bypass proxy. Each value is either an -// IP address, a CIDR range, a zone (*.example.com) or a host name -// (localhost). A best effort is made to parse the string and errors are -// ignored. -func (p *proxy_PerHost) AddFromString(s string) { - hosts := strings.Split(s, ",") - for _, host := range hosts { - host = strings.TrimSpace(host) - if len(host) == 0 { - continue - } - if strings.Contains(host, "/") { - // We assume that it's a CIDR address like 127.0.0.0/8 - if _, net, err := net.ParseCIDR(host); err == nil { - p.AddNetwork(net) - } - continue - } - if ip := net.ParseIP(host); ip != nil { - p.AddIP(ip) - continue - } - if strings.HasPrefix(host, "*.") { - p.AddZone(host[1:]) - continue - } - p.AddHost(host) - } -} - -// AddIP specifies an IP address that will use the bypass proxy. Note that -// this will only take effect if a literal IP address is dialed. A connection -// to a named host will never match an IP. -func (p *proxy_PerHost) AddIP(ip net.IP) { - p.bypassIPs = append(p.bypassIPs, ip) -} - -// AddNetwork specifies an IP range that will use the bypass proxy. Note that -// this will only take effect if a literal IP address is dialed. A connection -// to a named host will never match. -func (p *proxy_PerHost) AddNetwork(net *net.IPNet) { - p.bypassNetworks = append(p.bypassNetworks, net) -} - -// AddZone specifies a DNS suffix that will use the bypass proxy. A zone of -// "example.com" matches "example.com" and all of its subdomains. -func (p *proxy_PerHost) AddZone(zone string) { - if strings.HasSuffix(zone, ".") { - zone = zone[:len(zone)-1] - } - if !strings.HasPrefix(zone, ".") { - zone = "." + zone - } - p.bypassZones = append(p.bypassZones, zone) -} - -// AddHost specifies a host name that will use the bypass proxy. -func (p *proxy_PerHost) AddHost(host string) { - if strings.HasSuffix(host, ".") { - host = host[:len(host)-1] - } - p.bypassHosts = append(p.bypassHosts, host) -} - -// A Dialer is a means to establish a connection. -type proxy_Dialer interface { - // Dial connects to the given address via the proxy. - Dial(network, addr string) (c net.Conn, err error) -} - -// Auth contains authentication parameters that specific Dialers may require. -type proxy_Auth struct { - User, Password string -} - -// FromEnvironment returns the dialer specified by the proxy related variables in -// the environment. -func proxy_FromEnvironment() proxy_Dialer { - allProxy := proxy_allProxyEnv.Get() - if len(allProxy) == 0 { - return proxy_Direct - } - - proxyURL, err := url.Parse(allProxy) - if err != nil { - return proxy_Direct - } - proxy, err := proxy_FromURL(proxyURL, proxy_Direct) - if err != nil { - return proxy_Direct - } - - noProxy := proxy_noProxyEnv.Get() - if len(noProxy) == 0 { - return proxy - } - - perHost := proxy_NewPerHost(proxy, proxy_Direct) - perHost.AddFromString(noProxy) - return perHost -} - -// proxySchemes is a map from URL schemes to a function that creates a Dialer -// from a URL with such a scheme. -var proxy_proxySchemes map[string]func(*url.URL, proxy_Dialer) (proxy_Dialer, error) - -// RegisterDialerType takes a URL scheme and a function to generate Dialers from -// a URL with that scheme and a forwarding Dialer. Registered schemes are used -// by FromURL. -func proxy_RegisterDialerType(scheme string, f func(*url.URL, proxy_Dialer) (proxy_Dialer, error)) { - if proxy_proxySchemes == nil { - proxy_proxySchemes = make(map[string]func(*url.URL, proxy_Dialer) (proxy_Dialer, error)) - } - proxy_proxySchemes[scheme] = f -} - -// FromURL returns a Dialer given a URL specification and an underlying -// Dialer for it to make network requests. -func proxy_FromURL(u *url.URL, forward proxy_Dialer) (proxy_Dialer, error) { - var auth *proxy_Auth - if u.User != nil { - auth = new(proxy_Auth) - auth.User = u.User.Username() - if p, ok := u.User.Password(); ok { - auth.Password = p - } - } - - switch u.Scheme { - case "socks5": - return proxy_SOCKS5("tcp", u.Host, auth, forward) - } - - // If the scheme doesn't match any of the built-in schemes, see if it - // was registered by another package. - if proxy_proxySchemes != nil { - if f, ok := proxy_proxySchemes[u.Scheme]; ok { - return f(u, forward) - } - } - - return nil, errors.New("proxy: unknown scheme: " + u.Scheme) -} - -var ( - proxy_allProxyEnv = &proxy_envOnce{ - names: []string{"ALL_PROXY", "all_proxy"}, - } - proxy_noProxyEnv = &proxy_envOnce{ - names: []string{"NO_PROXY", "no_proxy"}, - } -) - -// envOnce looks up an environment variable (optionally by multiple -// names) once. It mitigates expensive lookups on some platforms -// (e.g. Windows). -// (Borrowed from net/http/transport.go) -type proxy_envOnce struct { - names []string - once sync.Once - val string -} - -func (e *proxy_envOnce) Get() string { - e.once.Do(e.init) - return e.val -} - -func (e *proxy_envOnce) init() { - for _, n := range e.names { - e.val = os.Getenv(n) - if e.val != "" { - return - } - } -} - -// SOCKS5 returns a Dialer that makes SOCKSv5 connections to the given address -// with an optional username and password. See RFC 1928 and RFC 1929. -func proxy_SOCKS5(network, addr string, auth *proxy_Auth, forward proxy_Dialer) (proxy_Dialer, error) { - s := &proxy_socks5{ - network: network, - addr: addr, - forward: forward, - } - if auth != nil { - s.user = auth.User - s.password = auth.Password - } - - return s, nil -} - -type proxy_socks5 struct { - user, password string - network, addr string - forward proxy_Dialer -} - -const proxy_socks5Version = 5 - -const ( - proxy_socks5AuthNone = 0 - proxy_socks5AuthPassword = 2 -) - -const proxy_socks5Connect = 1 - -const ( - proxy_socks5IP4 = 1 - proxy_socks5Domain = 3 - proxy_socks5IP6 = 4 -) - -var proxy_socks5Errors = []string{ - "", - "general failure", - "connection forbidden", - "network unreachable", - "host unreachable", - "connection refused", - "TTL expired", - "command not supported", - "address type not supported", -} - -// Dial connects to the address addr on the given network via the SOCKS5 proxy. -func (s *proxy_socks5) Dial(network, addr string) (net.Conn, error) { - switch network { - case "tcp", "tcp6", "tcp4": - default: - return nil, errors.New("proxy: no support for SOCKS5 proxy connections of type " + network) - } - - conn, err := s.forward.Dial(s.network, s.addr) - if err != nil { - return nil, err - } - if err := s.connect(conn, addr); err != nil { - conn.Close() - return nil, err - } - return conn, nil -} - -// connect takes an existing connection to a socks5 proxy server, -// and commands the server to extend that connection to target, -// which must be a canonical address with a host and port. -func (s *proxy_socks5) connect(conn net.Conn, target string) error { - host, portStr, err := net.SplitHostPort(target) - if err != nil { - return err - } - - port, err := strconv.Atoi(portStr) - if err != nil { - return errors.New("proxy: failed to parse port number: " + portStr) - } - if port < 1 || port > 0xffff { - return errors.New("proxy: port number out of range: " + portStr) - } - - // the size here is just an estimate - buf := make([]byte, 0, 6+len(host)) - - buf = append(buf, proxy_socks5Version) - if len(s.user) > 0 && len(s.user) < 256 && len(s.password) < 256 { - buf = append(buf, 2 /* num auth methods */, proxy_socks5AuthNone, proxy_socks5AuthPassword) - } else { - buf = append(buf, 1 /* num auth methods */, proxy_socks5AuthNone) - } - - if _, err := conn.Write(buf); err != nil { - return errors.New("proxy: failed to write greeting to SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - - if _, err := io.ReadFull(conn, buf[:2]); err != nil { - return errors.New("proxy: failed to read greeting from SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - if buf[0] != 5 { - return errors.New("proxy: SOCKS5 proxy at " + s.addr + " has unexpected version " + strconv.Itoa(int(buf[0]))) - } - if buf[1] == 0xff { - return errors.New("proxy: SOCKS5 proxy at " + s.addr + " requires authentication") - } - - // See RFC 1929 - if buf[1] == proxy_socks5AuthPassword { - buf = buf[:0] - buf = append(buf, 1 /* password protocol version */) - buf = append(buf, uint8(len(s.user))) - buf = append(buf, s.user...) - buf = append(buf, uint8(len(s.password))) - buf = append(buf, s.password...) - - if _, err := conn.Write(buf); err != nil { - return errors.New("proxy: failed to write authentication request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - - if _, err := io.ReadFull(conn, buf[:2]); err != nil { - return errors.New("proxy: failed to read authentication reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - - if buf[1] != 0 { - return errors.New("proxy: SOCKS5 proxy at " + s.addr + " rejected username/password") - } - } - - buf = buf[:0] - buf = append(buf, proxy_socks5Version, proxy_socks5Connect, 0 /* reserved */) - - if ip := net.ParseIP(host); ip != nil { - if ip4 := ip.To4(); ip4 != nil { - buf = append(buf, proxy_socks5IP4) - ip = ip4 - } else { - buf = append(buf, proxy_socks5IP6) - } - buf = append(buf, ip...) - } else { - if len(host) > 255 { - return errors.New("proxy: destination host name too long: " + host) - } - buf = append(buf, proxy_socks5Domain) - buf = append(buf, byte(len(host))) - buf = append(buf, host...) - } - buf = append(buf, byte(port>>8), byte(port)) - - if _, err := conn.Write(buf); err != nil { - return errors.New("proxy: failed to write connect request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - - if _, err := io.ReadFull(conn, buf[:4]); err != nil { - return errors.New("proxy: failed to read connect reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - - failure := "unknown error" - if int(buf[1]) < len(proxy_socks5Errors) { - failure = proxy_socks5Errors[buf[1]] - } - - if len(failure) > 0 { - return errors.New("proxy: SOCKS5 proxy at " + s.addr + " failed to connect: " + failure) - } - - bytesToDiscard := 0 - switch buf[3] { - case proxy_socks5IP4: - bytesToDiscard = net.IPv4len - case proxy_socks5IP6: - bytesToDiscard = net.IPv6len - case proxy_socks5Domain: - _, err := io.ReadFull(conn, buf[:1]) - if err != nil { - return errors.New("proxy: failed to read domain length from SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - bytesToDiscard = int(buf[0]) - default: - return errors.New("proxy: got unknown address type " + strconv.Itoa(int(buf[3])) + " from SOCKS5 proxy at " + s.addr) - } - - if cap(buf) < bytesToDiscard { - buf = make([]byte, bytesToDiscard) - } else { - buf = buf[:bytesToDiscard] - } - if _, err := io.ReadFull(conn, buf); err != nil { - return errors.New("proxy: failed to read address from SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - - // Also need to discard the port number - if _, err := io.ReadFull(conn, buf[:2]); err != nil { - return errors.New("proxy: failed to read port from SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - - return nil -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/LICENSE b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/LICENSE deleted file mode 100644 index 1eb75ef68e4..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -Copyright (c) 2012 The Go Authors. All rights reserved. -Copyright (c) 2019 Klaus Post. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/deflate.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/deflate.go deleted file mode 100644 index 2b101d26b25..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/deflate.go +++ /dev/null @@ -1,819 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Copyright (c) 2015 Klaus Post -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flate - -import ( - "fmt" - "io" - "math" -) - -const ( - NoCompression = 0 - BestSpeed = 1 - BestCompression = 9 - DefaultCompression = -1 - - // HuffmanOnly disables Lempel-Ziv match searching and only performs Huffman - // entropy encoding. This mode is useful in compressing data that has - // already been compressed with an LZ style algorithm (e.g. Snappy or LZ4) - // that lacks an entropy encoder. Compression gains are achieved when - // certain bytes in the input stream occur more frequently than others. - // - // Note that HuffmanOnly produces a compressed output that is - // RFC 1951 compliant. That is, any valid DEFLATE decompressor will - // continue to be able to decompress this output. - HuffmanOnly = -2 - ConstantCompression = HuffmanOnly // compatibility alias. - - logWindowSize = 15 - windowSize = 1 << logWindowSize - windowMask = windowSize - 1 - logMaxOffsetSize = 15 // Standard DEFLATE - minMatchLength = 4 // The smallest match that the compressor looks for - maxMatchLength = 258 // The longest match for the compressor - minOffsetSize = 1 // The shortest offset that makes any sense - - // The maximum number of tokens we put into a single flat block, just too - // stop things from getting too large. - maxFlateBlockTokens = 1 << 14 - maxStoreBlockSize = 65535 - hashBits = 17 // After 17 performance degrades - hashSize = 1 << hashBits - hashMask = (1 << hashBits) - 1 - hashShift = (hashBits + minMatchLength - 1) / minMatchLength - maxHashOffset = 1 << 24 - - skipNever = math.MaxInt32 - - debugDeflate = false -) - -type compressionLevel struct { - good, lazy, nice, chain, fastSkipHashing, level int -} - -// Compression levels have been rebalanced from zlib deflate defaults -// to give a bigger spread in speed and compression. -// See https://blog.klauspost.com/rebalancing-deflate-compression-levels/ -var levels = []compressionLevel{ - {}, // 0 - // Level 1-6 uses specialized algorithm - values not used - {0, 0, 0, 0, 0, 1}, - {0, 0, 0, 0, 0, 2}, - {0, 0, 0, 0, 0, 3}, - {0, 0, 0, 0, 0, 4}, - {0, 0, 0, 0, 0, 5}, - {0, 0, 0, 0, 0, 6}, - // Levels 7-9 use increasingly more lazy matching - // and increasingly stringent conditions for "good enough". - {8, 8, 24, 16, skipNever, 7}, - {10, 16, 24, 64, skipNever, 8}, - {32, 258, 258, 4096, skipNever, 9}, -} - -// advancedState contains state for the advanced levels, with bigger hash tables, etc. -type advancedState struct { - // deflate state - length int - offset int - hash uint32 - maxInsertIndex int - ii uint16 // position of last match, intended to overflow to reset. - - // Input hash chains - // hashHead[hashValue] contains the largest inputIndex with the specified hash value - // If hashHead[hashValue] is within the current window, then - // hashPrev[hashHead[hashValue] & windowMask] contains the previous index - // with the same hash value. - chainHead int - hashHead [hashSize]uint32 - hashPrev [windowSize]uint32 - hashOffset int - - // input window: unprocessed data is window[index:windowEnd] - index int - hashMatch [maxMatchLength + minMatchLength]uint32 -} - -type compressor struct { - compressionLevel - - w *huffmanBitWriter - - // compression algorithm - fill func(*compressor, []byte) int // copy data to window - step func(*compressor) // process window - sync bool // requesting flush - - window []byte - windowEnd int - blockStart int // window index where current tokens start - byteAvailable bool // if true, still need to process window[index-1]. - err error - - // queued output tokens - tokens tokens - fast fastEnc - state *advancedState -} - -func (d *compressor) fillDeflate(b []byte) int { - s := d.state - if s.index >= 2*windowSize-(minMatchLength+maxMatchLength) { - // shift the window by windowSize - copy(d.window[:], d.window[windowSize:2*windowSize]) - s.index -= windowSize - d.windowEnd -= windowSize - if d.blockStart >= windowSize { - d.blockStart -= windowSize - } else { - d.blockStart = math.MaxInt32 - } - s.hashOffset += windowSize - if s.hashOffset > maxHashOffset { - delta := s.hashOffset - 1 - s.hashOffset -= delta - s.chainHead -= delta - // Iterate over slices instead of arrays to avoid copying - // the entire table onto the stack (Issue #18625). - for i, v := range s.hashPrev[:] { - if int(v) > delta { - s.hashPrev[i] = uint32(int(v) - delta) - } else { - s.hashPrev[i] = 0 - } - } - for i, v := range s.hashHead[:] { - if int(v) > delta { - s.hashHead[i] = uint32(int(v) - delta) - } else { - s.hashHead[i] = 0 - } - } - } - } - n := copy(d.window[d.windowEnd:], b) - d.windowEnd += n - return n -} - -func (d *compressor) writeBlock(tok *tokens, index int, eof bool) error { - if index > 0 || eof { - var window []byte - if d.blockStart <= index { - window = d.window[d.blockStart:index] - } - d.blockStart = index - d.w.writeBlock(tok, eof, window) - return d.w.err - } - return nil -} - -// writeBlockSkip writes the current block and uses the number of tokens -// to determine if the block should be stored on no matches, or -// only huffman encoded. -func (d *compressor) writeBlockSkip(tok *tokens, index int, eof bool) error { - if index > 0 || eof { - if d.blockStart <= index { - window := d.window[d.blockStart:index] - // If we removed less than a 64th of all literals - // we huffman compress the block. - if int(tok.n) > len(window)-int(tok.n>>6) { - d.w.writeBlockHuff(eof, window, d.sync) - } else { - // Write a dynamic huffman block. - d.w.writeBlockDynamic(tok, eof, window, d.sync) - } - } else { - d.w.writeBlock(tok, eof, nil) - } - d.blockStart = index - return d.w.err - } - return nil -} - -// fillWindow will fill the current window with the supplied -// dictionary and calculate all hashes. -// This is much faster than doing a full encode. -// Should only be used after a start/reset. -func (d *compressor) fillWindow(b []byte) { - // Do not fill window if we are in store-only or huffman mode. - if d.level <= 0 { - return - } - if d.fast != nil { - // encode the last data, but discard the result - if len(b) > maxMatchOffset { - b = b[len(b)-maxMatchOffset:] - } - d.fast.Encode(&d.tokens, b) - d.tokens.Reset() - return - } - s := d.state - // If we are given too much, cut it. - if len(b) > windowSize { - b = b[len(b)-windowSize:] - } - // Add all to window. - n := copy(d.window[d.windowEnd:], b) - - // Calculate 256 hashes at the time (more L1 cache hits) - loops := (n + 256 - minMatchLength) / 256 - for j := 0; j < loops; j++ { - startindex := j * 256 - end := startindex + 256 + minMatchLength - 1 - if end > n { - end = n - } - tocheck := d.window[startindex:end] - dstSize := len(tocheck) - minMatchLength + 1 - - if dstSize <= 0 { - continue - } - - dst := s.hashMatch[:dstSize] - bulkHash4(tocheck, dst) - var newH uint32 - for i, val := range dst { - di := i + startindex - newH = val & hashMask - // Get previous value with the same hash. - // Our chain should point to the previous value. - s.hashPrev[di&windowMask] = s.hashHead[newH] - // Set the head of the hash chain to us. - s.hashHead[newH] = uint32(di + s.hashOffset) - } - s.hash = newH - } - // Update window information. - d.windowEnd += n - s.index = n -} - -// Try to find a match starting at index whose length is greater than prevSize. -// We only look at chainCount possibilities before giving up. -// pos = s.index, prevHead = s.chainHead-s.hashOffset, prevLength=minMatchLength-1, lookahead -func (d *compressor) findMatch(pos int, prevHead int, prevLength int, lookahead int) (length, offset int, ok bool) { - minMatchLook := maxMatchLength - if lookahead < minMatchLook { - minMatchLook = lookahead - } - - win := d.window[0 : pos+minMatchLook] - - // We quit when we get a match that's at least nice long - nice := len(win) - pos - if d.nice < nice { - nice = d.nice - } - - // If we've got a match that's good enough, only look in 1/4 the chain. - tries := d.chain - length = prevLength - if length >= d.good { - tries >>= 2 - } - - wEnd := win[pos+length] - wPos := win[pos:] - minIndex := pos - windowSize - - for i := prevHead; tries > 0; tries-- { - if wEnd == win[i+length] { - n := matchLen(win[i:i+minMatchLook], wPos) - - if n > length && (n > minMatchLength || pos-i <= 4096) { - length = n - offset = pos - i - ok = true - if n >= nice { - // The match is good enough that we don't try to find a better one. - break - } - wEnd = win[pos+n] - } - } - if i == minIndex { - // hashPrev[i & windowMask] has already been overwritten, so stop now. - break - } - i = int(d.state.hashPrev[i&windowMask]) - d.state.hashOffset - if i < minIndex || i < 0 { - break - } - } - return -} - -func (d *compressor) writeStoredBlock(buf []byte) error { - if d.w.writeStoredHeader(len(buf), false); d.w.err != nil { - return d.w.err - } - d.w.writeBytes(buf) - return d.w.err -} - -// hash4 returns a hash representation of the first 4 bytes -// of the supplied slice. -// The caller must ensure that len(b) >= 4. -func hash4(b []byte) uint32 { - b = b[:4] - return hash4u(uint32(b[3])|uint32(b[2])<<8|uint32(b[1])<<16|uint32(b[0])<<24, hashBits) -} - -// bulkHash4 will compute hashes using the same -// algorithm as hash4 -func bulkHash4(b []byte, dst []uint32) { - if len(b) < 4 { - return - } - hb := uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24 - dst[0] = hash4u(hb, hashBits) - end := len(b) - 4 + 1 - for i := 1; i < end; i++ { - hb = (hb << 8) | uint32(b[i+3]) - dst[i] = hash4u(hb, hashBits) - } -} - -func (d *compressor) initDeflate() { - d.window = make([]byte, 2*windowSize) - d.byteAvailable = false - d.err = nil - if d.state == nil { - return - } - s := d.state - s.index = 0 - s.hashOffset = 1 - s.length = minMatchLength - 1 - s.offset = 0 - s.hash = 0 - s.chainHead = -1 -} - -// deflateLazy is the same as deflate, but with d.fastSkipHashing == skipNever, -// meaning it always has lazy matching on. -func (d *compressor) deflateLazy() { - s := d.state - // Sanity enables additional runtime tests. - // It's intended to be used during development - // to supplement the currently ad-hoc unit tests. - const sanity = debugDeflate - - if d.windowEnd-s.index < minMatchLength+maxMatchLength && !d.sync { - return - } - - s.maxInsertIndex = d.windowEnd - (minMatchLength - 1) - if s.index < s.maxInsertIndex { - s.hash = hash4(d.window[s.index : s.index+minMatchLength]) - } - - for { - if sanity && s.index > d.windowEnd { - panic("index > windowEnd") - } - lookahead := d.windowEnd - s.index - if lookahead < minMatchLength+maxMatchLength { - if !d.sync { - return - } - if sanity && s.index > d.windowEnd { - panic("index > windowEnd") - } - if lookahead == 0 { - // Flush current output block if any. - if d.byteAvailable { - // There is still one pending token that needs to be flushed - d.tokens.AddLiteral(d.window[s.index-1]) - d.byteAvailable = false - } - if d.tokens.n > 0 { - if d.err = d.writeBlock(&d.tokens, s.index, false); d.err != nil { - return - } - d.tokens.Reset() - } - return - } - } - if s.index < s.maxInsertIndex { - // Update the hash - s.hash = hash4(d.window[s.index : s.index+minMatchLength]) - ch := s.hashHead[s.hash&hashMask] - s.chainHead = int(ch) - s.hashPrev[s.index&windowMask] = ch - s.hashHead[s.hash&hashMask] = uint32(s.index + s.hashOffset) - } - prevLength := s.length - prevOffset := s.offset - s.length = minMatchLength - 1 - s.offset = 0 - minIndex := s.index - windowSize - if minIndex < 0 { - minIndex = 0 - } - - if s.chainHead-s.hashOffset >= minIndex && lookahead > prevLength && prevLength < d.lazy { - if newLength, newOffset, ok := d.findMatch(s.index, s.chainHead-s.hashOffset, minMatchLength-1, lookahead); ok { - s.length = newLength - s.offset = newOffset - } - } - if prevLength >= minMatchLength && s.length <= prevLength { - // There was a match at the previous step, and the current match is - // not better. Output the previous match. - d.tokens.AddMatch(uint32(prevLength-3), uint32(prevOffset-minOffsetSize)) - - // Insert in the hash table all strings up to the end of the match. - // index and index-1 are already inserted. If there is not enough - // lookahead, the last two strings are not inserted into the hash - // table. - var newIndex int - newIndex = s.index + prevLength - 1 - // Calculate missing hashes - end := newIndex - if end > s.maxInsertIndex { - end = s.maxInsertIndex - } - end += minMatchLength - 1 - startindex := s.index + 1 - if startindex > s.maxInsertIndex { - startindex = s.maxInsertIndex - } - tocheck := d.window[startindex:end] - dstSize := len(tocheck) - minMatchLength + 1 - if dstSize > 0 { - dst := s.hashMatch[:dstSize] - bulkHash4(tocheck, dst) - var newH uint32 - for i, val := range dst { - di := i + startindex - newH = val & hashMask - // Get previous value with the same hash. - // Our chain should point to the previous value. - s.hashPrev[di&windowMask] = s.hashHead[newH] - // Set the head of the hash chain to us. - s.hashHead[newH] = uint32(di + s.hashOffset) - } - s.hash = newH - } - - s.index = newIndex - d.byteAvailable = false - s.length = minMatchLength - 1 - if d.tokens.n == maxFlateBlockTokens { - // The block includes the current character - if d.err = d.writeBlock(&d.tokens, s.index, false); d.err != nil { - return - } - d.tokens.Reset() - } - } else { - // Reset, if we got a match this run. - if s.length >= minMatchLength { - s.ii = 0 - } - // We have a byte waiting. Emit it. - if d.byteAvailable { - s.ii++ - d.tokens.AddLiteral(d.window[s.index-1]) - if d.tokens.n == maxFlateBlockTokens { - if d.err = d.writeBlock(&d.tokens, s.index, false); d.err != nil { - return - } - d.tokens.Reset() - } - s.index++ - - // If we have a long run of no matches, skip additional bytes - // Resets when s.ii overflows after 64KB. - if s.ii > 31 { - n := int(s.ii >> 5) - for j := 0; j < n; j++ { - if s.index >= d.windowEnd-1 { - break - } - - d.tokens.AddLiteral(d.window[s.index-1]) - if d.tokens.n == maxFlateBlockTokens { - if d.err = d.writeBlock(&d.tokens, s.index, false); d.err != nil { - return - } - d.tokens.Reset() - } - s.index++ - } - // Flush last byte - d.tokens.AddLiteral(d.window[s.index-1]) - d.byteAvailable = false - // s.length = minMatchLength - 1 // not needed, since s.ii is reset above, so it should never be > minMatchLength - if d.tokens.n == maxFlateBlockTokens { - if d.err = d.writeBlock(&d.tokens, s.index, false); d.err != nil { - return - } - d.tokens.Reset() - } - } - } else { - s.index++ - d.byteAvailable = true - } - } - } -} - -func (d *compressor) store() { - if d.windowEnd > 0 && (d.windowEnd == maxStoreBlockSize || d.sync) { - d.err = d.writeStoredBlock(d.window[:d.windowEnd]) - d.windowEnd = 0 - } -} - -// fillWindow will fill the buffer with data for huffman-only compression. -// The number of bytes copied is returned. -func (d *compressor) fillBlock(b []byte) int { - n := copy(d.window[d.windowEnd:], b) - d.windowEnd += n - return n -} - -// storeHuff will compress and store the currently added data, -// if enough has been accumulated or we at the end of the stream. -// Any error that occurred will be in d.err -func (d *compressor) storeHuff() { - if d.windowEnd < len(d.window) && !d.sync || d.windowEnd == 0 { - return - } - d.w.writeBlockHuff(false, d.window[:d.windowEnd], d.sync) - d.err = d.w.err - d.windowEnd = 0 -} - -// storeFast will compress and store the currently added data, -// if enough has been accumulated or we at the end of the stream. -// Any error that occurred will be in d.err -func (d *compressor) storeFast() { - // We only compress if we have maxStoreBlockSize. - if d.windowEnd < len(d.window) { - if !d.sync { - return - } - // Handle extremely small sizes. - if d.windowEnd < 128 { - if d.windowEnd == 0 { - return - } - if d.windowEnd <= 32 { - d.err = d.writeStoredBlock(d.window[:d.windowEnd]) - } else { - d.w.writeBlockHuff(false, d.window[:d.windowEnd], true) - d.err = d.w.err - } - d.tokens.Reset() - d.windowEnd = 0 - d.fast.Reset() - return - } - } - - d.fast.Encode(&d.tokens, d.window[:d.windowEnd]) - // If we made zero matches, store the block as is. - if d.tokens.n == 0 { - d.err = d.writeStoredBlock(d.window[:d.windowEnd]) - // If we removed less than 1/16th, huffman compress the block. - } else if int(d.tokens.n) > d.windowEnd-(d.windowEnd>>4) { - d.w.writeBlockHuff(false, d.window[:d.windowEnd], d.sync) - d.err = d.w.err - } else { - d.w.writeBlockDynamic(&d.tokens, false, d.window[:d.windowEnd], d.sync) - d.err = d.w.err - } - d.tokens.Reset() - d.windowEnd = 0 -} - -// write will add input byte to the stream. -// Unless an error occurs all bytes will be consumed. -func (d *compressor) write(b []byte) (n int, err error) { - if d.err != nil { - return 0, d.err - } - n = len(b) - for len(b) > 0 { - d.step(d) - b = b[d.fill(d, b):] - if d.err != nil { - return 0, d.err - } - } - return n, d.err -} - -func (d *compressor) syncFlush() error { - d.sync = true - if d.err != nil { - return d.err - } - d.step(d) - if d.err == nil { - d.w.writeStoredHeader(0, false) - d.w.flush() - d.err = d.w.err - } - d.sync = false - return d.err -} - -func (d *compressor) init(w io.Writer, level int) (err error) { - d.w = newHuffmanBitWriter(w) - - switch { - case level == NoCompression: - d.window = make([]byte, maxStoreBlockSize) - d.fill = (*compressor).fillBlock - d.step = (*compressor).store - case level == ConstantCompression: - d.w.logNewTablePenalty = 4 - d.window = make([]byte, maxStoreBlockSize) - d.fill = (*compressor).fillBlock - d.step = (*compressor).storeHuff - case level == DefaultCompression: - level = 5 - fallthrough - case level >= 1 && level <= 6: - d.w.logNewTablePenalty = 6 - d.fast = newFastEnc(level) - d.window = make([]byte, maxStoreBlockSize) - d.fill = (*compressor).fillBlock - d.step = (*compressor).storeFast - case 7 <= level && level <= 9: - d.w.logNewTablePenalty = 10 - d.state = &advancedState{} - d.compressionLevel = levels[level] - d.initDeflate() - d.fill = (*compressor).fillDeflate - d.step = (*compressor).deflateLazy - default: - return fmt.Errorf("flate: invalid compression level %d: want value in range [-2, 9]", level) - } - d.level = level - return nil -} - -// reset the state of the compressor. -func (d *compressor) reset(w io.Writer) { - d.w.reset(w) - d.sync = false - d.err = nil - // We only need to reset a few things for Snappy. - if d.fast != nil { - d.fast.Reset() - d.windowEnd = 0 - d.tokens.Reset() - return - } - switch d.compressionLevel.chain { - case 0: - // level was NoCompression or ConstantCompresssion. - d.windowEnd = 0 - default: - s := d.state - s.chainHead = -1 - for i := range s.hashHead { - s.hashHead[i] = 0 - } - for i := range s.hashPrev { - s.hashPrev[i] = 0 - } - s.hashOffset = 1 - s.index, d.windowEnd = 0, 0 - d.blockStart, d.byteAvailable = 0, false - d.tokens.Reset() - s.length = minMatchLength - 1 - s.offset = 0 - s.hash = 0 - s.ii = 0 - s.maxInsertIndex = 0 - } -} - -func (d *compressor) close() error { - if d.err != nil { - return d.err - } - d.sync = true - d.step(d) - if d.err != nil { - return d.err - } - if d.w.writeStoredHeader(0, true); d.w.err != nil { - return d.w.err - } - d.w.flush() - d.w.reset(nil) - return d.w.err -} - -// NewWriter returns a new Writer compressing data at the given level. -// Following zlib, levels range from 1 (BestSpeed) to 9 (BestCompression); -// higher levels typically run slower but compress more. -// Level 0 (NoCompression) does not attempt any compression; it only adds the -// necessary DEFLATE framing. -// Level -1 (DefaultCompression) uses the default compression level. -// Level -2 (ConstantCompression) will use Huffman compression only, giving -// a very fast compression for all types of input, but sacrificing considerable -// compression efficiency. -// -// If level is in the range [-2, 9] then the error returned will be nil. -// Otherwise the error returned will be non-nil. -func NewWriter(w io.Writer, level int) (*Writer, error) { - var dw Writer - if err := dw.d.init(w, level); err != nil { - return nil, err - } - return &dw, nil -} - -// NewWriterDict is like NewWriter but initializes the new -// Writer with a preset dictionary. The returned Writer behaves -// as if the dictionary had been written to it without producing -// any compressed output. The compressed data written to w -// can only be decompressed by a Reader initialized with the -// same dictionary. -func NewWriterDict(w io.Writer, level int, dict []byte) (*Writer, error) { - zw, err := NewWriter(w, level) - if err != nil { - return nil, err - } - zw.d.fillWindow(dict) - zw.dict = append(zw.dict, dict...) // duplicate dictionary for Reset method. - return zw, err -} - -// A Writer takes data written to it and writes the compressed -// form of that data to an underlying writer (see NewWriter). -type Writer struct { - d compressor - dict []byte -} - -// Write writes data to w, which will eventually write the -// compressed form of data to its underlying writer. -func (w *Writer) Write(data []byte) (n int, err error) { - return w.d.write(data) -} - -// Flush flushes any pending data to the underlying writer. -// It is useful mainly in compressed network protocols, to ensure that -// a remote reader has enough data to reconstruct a packet. -// Flush does not return until the data has been written. -// Calling Flush when there is no pending data still causes the Writer -// to emit a sync marker of at least 4 bytes. -// If the underlying writer returns an error, Flush returns that error. -// -// In the terminology of the zlib library, Flush is equivalent to Z_SYNC_FLUSH. -func (w *Writer) Flush() error { - // For more about flushing: - // http://www.bolet.org/~pornin/deflate-flush.html - return w.d.syncFlush() -} - -// Close flushes and closes the writer. -func (w *Writer) Close() error { - return w.d.close() -} - -// Reset discards the writer's state and makes it equivalent to -// the result of NewWriter or NewWriterDict called with dst -// and w's level and dictionary. -func (w *Writer) Reset(dst io.Writer) { - if len(w.dict) > 0 { - // w was created with NewWriterDict - w.d.reset(dst) - if dst != nil { - w.d.fillWindow(w.dict) - } - } else { - // w was created with NewWriter - w.d.reset(dst) - } -} - -// ResetDict discards the writer's state and makes it equivalent to -// the result of NewWriter or NewWriterDict called with dst -// and w's level, but sets a specific dictionary. -func (w *Writer) ResetDict(dst io.Writer, dict []byte) { - w.dict = dict - w.d.reset(dst) - w.d.fillWindow(w.dict) -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/dict_decoder.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/dict_decoder.go deleted file mode 100644 index 71c75a065ea..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/dict_decoder.go +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flate - -// dictDecoder implements the LZ77 sliding dictionary as used in decompression. -// LZ77 decompresses data through sequences of two forms of commands: -// -// * Literal insertions: Runs of one or more symbols are inserted into the data -// stream as is. This is accomplished through the writeByte method for a -// single symbol, or combinations of writeSlice/writeMark for multiple symbols. -// Any valid stream must start with a literal insertion if no preset dictionary -// is used. -// -// * Backward copies: Runs of one or more symbols are copied from previously -// emitted data. Backward copies come as the tuple (dist, length) where dist -// determines how far back in the stream to copy from and length determines how -// many bytes to copy. Note that it is valid for the length to be greater than -// the distance. Since LZ77 uses forward copies, that situation is used to -// perform a form of run-length encoding on repeated runs of symbols. -// The writeCopy and tryWriteCopy are used to implement this command. -// -// For performance reasons, this implementation performs little to no sanity -// checks about the arguments. As such, the invariants documented for each -// method call must be respected. -type dictDecoder struct { - hist []byte // Sliding window history - - // Invariant: 0 <= rdPos <= wrPos <= len(hist) - wrPos int // Current output position in buffer - rdPos int // Have emitted hist[:rdPos] already - full bool // Has a full window length been written yet? -} - -// init initializes dictDecoder to have a sliding window dictionary of the given -// size. If a preset dict is provided, it will initialize the dictionary with -// the contents of dict. -func (dd *dictDecoder) init(size int, dict []byte) { - *dd = dictDecoder{hist: dd.hist} - - if cap(dd.hist) < size { - dd.hist = make([]byte, size) - } - dd.hist = dd.hist[:size] - - if len(dict) > len(dd.hist) { - dict = dict[len(dict)-len(dd.hist):] - } - dd.wrPos = copy(dd.hist, dict) - if dd.wrPos == len(dd.hist) { - dd.wrPos = 0 - dd.full = true - } - dd.rdPos = dd.wrPos -} - -// histSize reports the total amount of historical data in the dictionary. -func (dd *dictDecoder) histSize() int { - if dd.full { - return len(dd.hist) - } - return dd.wrPos -} - -// availRead reports the number of bytes that can be flushed by readFlush. -func (dd *dictDecoder) availRead() int { - return dd.wrPos - dd.rdPos -} - -// availWrite reports the available amount of output buffer space. -func (dd *dictDecoder) availWrite() int { - return len(dd.hist) - dd.wrPos -} - -// writeSlice returns a slice of the available buffer to write data to. -// -// This invariant will be kept: len(s) <= availWrite() -func (dd *dictDecoder) writeSlice() []byte { - return dd.hist[dd.wrPos:] -} - -// writeMark advances the writer pointer by cnt. -// -// This invariant must be kept: 0 <= cnt <= availWrite() -func (dd *dictDecoder) writeMark(cnt int) { - dd.wrPos += cnt -} - -// writeByte writes a single byte to the dictionary. -// -// This invariant must be kept: 0 < availWrite() -func (dd *dictDecoder) writeByte(c byte) { - dd.hist[dd.wrPos] = c - dd.wrPos++ -} - -// writeCopy copies a string at a given (dist, length) to the output. -// This returns the number of bytes copied and may be less than the requested -// length if the available space in the output buffer is too small. -// -// This invariant must be kept: 0 < dist <= histSize() -func (dd *dictDecoder) writeCopy(dist, length int) int { - dstBase := dd.wrPos - dstPos := dstBase - srcPos := dstPos - dist - endPos := dstPos + length - if endPos > len(dd.hist) { - endPos = len(dd.hist) - } - - // Copy non-overlapping section after destination position. - // - // This section is non-overlapping in that the copy length for this section - // is always less than or equal to the backwards distance. This can occur - // if a distance refers to data that wraps-around in the buffer. - // Thus, a backwards copy is performed here; that is, the exact bytes in - // the source prior to the copy is placed in the destination. - if srcPos < 0 { - srcPos += len(dd.hist) - dstPos += copy(dd.hist[dstPos:endPos], dd.hist[srcPos:]) - srcPos = 0 - } - - // Copy possibly overlapping section before destination position. - // - // This section can overlap if the copy length for this section is larger - // than the backwards distance. This is allowed by LZ77 so that repeated - // strings can be succinctly represented using (dist, length) pairs. - // Thus, a forwards copy is performed here; that is, the bytes copied is - // possibly dependent on the resulting bytes in the destination as the copy - // progresses along. This is functionally equivalent to the following: - // - // for i := 0; i < endPos-dstPos; i++ { - // dd.hist[dstPos+i] = dd.hist[srcPos+i] - // } - // dstPos = endPos - // - for dstPos < endPos { - dstPos += copy(dd.hist[dstPos:endPos], dd.hist[srcPos:dstPos]) - } - - dd.wrPos = dstPos - return dstPos - dstBase -} - -// tryWriteCopy tries to copy a string at a given (distance, length) to the -// output. This specialized version is optimized for short distances. -// -// This method is designed to be inlined for performance reasons. -// -// This invariant must be kept: 0 < dist <= histSize() -func (dd *dictDecoder) tryWriteCopy(dist, length int) int { - dstPos := dd.wrPos - endPos := dstPos + length - if dstPos < dist || endPos > len(dd.hist) { - return 0 - } - dstBase := dstPos - srcPos := dstPos - dist - - // Copy possibly overlapping section before destination position. -loop: - dstPos += copy(dd.hist[dstPos:endPos], dd.hist[srcPos:dstPos]) - if dstPos < endPos { - goto loop // Avoid for-loop so that this function can be inlined - } - - dd.wrPos = dstPos - return dstPos - dstBase -} - -// readFlush returns a slice of the historical buffer that is ready to be -// emitted to the user. The data returned by readFlush must be fully consumed -// before calling any other dictDecoder methods. -func (dd *dictDecoder) readFlush() []byte { - toRead := dd.hist[dd.rdPos:dd.wrPos] - dd.rdPos = dd.wrPos - if dd.wrPos == len(dd.hist) { - dd.wrPos, dd.rdPos = 0, 0 - dd.full = true - } - return toRead -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/fast_encoder.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/fast_encoder.go deleted file mode 100644 index 6d4c1e98bc5..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/fast_encoder.go +++ /dev/null @@ -1,254 +0,0 @@ -// Copyright 2011 The Snappy-Go Authors. All rights reserved. -// Modified for deflate by Klaus Post (c) 2015. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flate - -import ( - "fmt" - "math/bits" -) - -type fastEnc interface { - Encode(dst *tokens, src []byte) - Reset() -} - -func newFastEnc(level int) fastEnc { - switch level { - case 1: - return &fastEncL1{fastGen: fastGen{cur: maxStoreBlockSize}} - case 2: - return &fastEncL2{fastGen: fastGen{cur: maxStoreBlockSize}} - case 3: - return &fastEncL3{fastGen: fastGen{cur: maxStoreBlockSize}} - case 4: - return &fastEncL4{fastGen: fastGen{cur: maxStoreBlockSize}} - case 5: - return &fastEncL5{fastGen: fastGen{cur: maxStoreBlockSize}} - case 6: - return &fastEncL6{fastGen: fastGen{cur: maxStoreBlockSize}} - default: - panic("invalid level specified") - } -} - -const ( - tableBits = 15 // Bits used in the table - tableSize = 1 << tableBits // Size of the table - tableShift = 32 - tableBits // Right-shift to get the tableBits most significant bits of a uint32. - baseMatchOffset = 1 // The smallest match offset - baseMatchLength = 3 // The smallest match length per the RFC section 3.2.5 - maxMatchOffset = 1 << 15 // The largest match offset - - bTableBits = 17 // Bits used in the big tables - bTableSize = 1 << bTableBits // Size of the table - allocHistory = maxStoreBlockSize * 10 // Size to preallocate for history. - bufferReset = (1 << 31) - allocHistory - maxStoreBlockSize - 1 // Reset the buffer offset when reaching this. -) - -const ( - prime3bytes = 506832829 - prime4bytes = 2654435761 - prime5bytes = 889523592379 - prime6bytes = 227718039650203 - prime7bytes = 58295818150454627 - prime8bytes = 0xcf1bbcdcb7a56463 -) - -func load32(b []byte, i int) uint32 { - // Help the compiler eliminate bounds checks on the read so it can be done in a single read. - b = b[i:] - b = b[:4] - return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 -} - -func load64(b []byte, i int) uint64 { - // Help the compiler eliminate bounds checks on the read so it can be done in a single read. - b = b[i:] - b = b[:8] - return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | - uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 -} - -func load3232(b []byte, i int32) uint32 { - // Help the compiler eliminate bounds checks on the read so it can be done in a single read. - b = b[i:] - b = b[:4] - return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 -} - -func load6432(b []byte, i int32) uint64 { - // Help the compiler eliminate bounds checks on the read so it can be done in a single read. - b = b[i:] - b = b[:8] - return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | - uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 -} - -func hash(u uint32) uint32 { - return (u * 0x1e35a7bd) >> tableShift -} - -type tableEntry struct { - offset int32 -} - -// fastGen maintains the table for matches, -// and the previous byte block for level 2. -// This is the generic implementation. -type fastGen struct { - hist []byte - cur int32 -} - -func (e *fastGen) addBlock(src []byte) int32 { - // check if we have space already - if len(e.hist)+len(src) > cap(e.hist) { - if cap(e.hist) == 0 { - e.hist = make([]byte, 0, allocHistory) - } else { - if cap(e.hist) < maxMatchOffset*2 { - panic("unexpected buffer size") - } - // Move down - offset := int32(len(e.hist)) - maxMatchOffset - copy(e.hist[0:maxMatchOffset], e.hist[offset:]) - e.cur += offset - e.hist = e.hist[:maxMatchOffset] - } - } - s := int32(len(e.hist)) - e.hist = append(e.hist, src...) - return s -} - -// hash4 returns the hash of u to fit in a hash table with h bits. -// Preferably h should be a constant and should always be <32. -func hash4u(u uint32, h uint8) uint32 { - return (u * prime4bytes) >> ((32 - h) & 31) -} - -type tableEntryPrev struct { - Cur tableEntry - Prev tableEntry -} - -// hash4x64 returns the hash of the lowest 4 bytes of u to fit in a hash table with h bits. -// Preferably h should be a constant and should always be <32. -func hash4x64(u uint64, h uint8) uint32 { - return (uint32(u) * prime4bytes) >> ((32 - h) & 31) -} - -// hash7 returns the hash of the lowest 7 bytes of u to fit in a hash table with h bits. -// Preferably h should be a constant and should always be <64. -func hash7(u uint64, h uint8) uint32 { - return uint32(((u << (64 - 56)) * prime7bytes) >> ((64 - h) & 63)) -} - -// hash8 returns the hash of u to fit in a hash table with h bits. -// Preferably h should be a constant and should always be <64. -func hash8(u uint64, h uint8) uint32 { - return uint32((u * prime8bytes) >> ((64 - h) & 63)) -} - -// hash6 returns the hash of the lowest 6 bytes of u to fit in a hash table with h bits. -// Preferably h should be a constant and should always be <64. -func hash6(u uint64, h uint8) uint32 { - return uint32(((u << (64 - 48)) * prime6bytes) >> ((64 - h) & 63)) -} - -// matchlen will return the match length between offsets and t in src. -// The maximum length returned is maxMatchLength - 4. -// It is assumed that s > t, that t >=0 and s < len(src). -func (e *fastGen) matchlen(s, t int32, src []byte) int32 { - if debugDecode { - if t >= s { - panic(fmt.Sprint("t >=s:", t, s)) - } - if int(s) >= len(src) { - panic(fmt.Sprint("s >= len(src):", s, len(src))) - } - if t < 0 { - panic(fmt.Sprint("t < 0:", t)) - } - if s-t > maxMatchOffset { - panic(fmt.Sprint(s, "-", t, "(", s-t, ") > maxMatchLength (", maxMatchOffset, ")")) - } - } - s1 := int(s) + maxMatchLength - 4 - if s1 > len(src) { - s1 = len(src) - } - - // Extend the match to be as long as possible. - return int32(matchLen(src[s:s1], src[t:])) -} - -// matchlenLong will return the match length between offsets and t in src. -// It is assumed that s > t, that t >=0 and s < len(src). -func (e *fastGen) matchlenLong(s, t int32, src []byte) int32 { - if debugDecode { - if t >= s { - panic(fmt.Sprint("t >=s:", t, s)) - } - if int(s) >= len(src) { - panic(fmt.Sprint("s >= len(src):", s, len(src))) - } - if t < 0 { - panic(fmt.Sprint("t < 0:", t)) - } - if s-t > maxMatchOffset { - panic(fmt.Sprint(s, "-", t, "(", s-t, ") > maxMatchLength (", maxMatchOffset, ")")) - } - } - // Extend the match to be as long as possible. - return int32(matchLen(src[s:], src[t:])) -} - -// Reset the encoding table. -func (e *fastGen) Reset() { - if cap(e.hist) < allocHistory { - e.hist = make([]byte, 0, allocHistory) - } - // We offset current position so everything will be out of reach. - // If we are above the buffer reset it will be cleared anyway since len(hist) == 0. - if e.cur <= bufferReset { - e.cur += maxMatchOffset + int32(len(e.hist)) - } - e.hist = e.hist[:0] -} - -// matchLen returns the maximum length. -// 'a' must be the shortest of the two. -func matchLen(a, b []byte) int { - b = b[:len(a)] - var checked int - if len(a) > 4 { - // Try 4 bytes first - if diff := load32(a, 0) ^ load32(b, 0); diff != 0 { - return bits.TrailingZeros32(diff) >> 3 - } - // Switch to 8 byte matching. - checked = 4 - a = a[4:] - b = b[4:] - for len(a) >= 8 { - b = b[:len(a)] - if diff := load64(a, 0) ^ load64(b, 0); diff != 0 { - return checked + (bits.TrailingZeros64(diff) >> 3) - } - checked += 8 - a = a[8:] - b = b[8:] - } - } - b = b[:len(a)] - for i := range a { - if a[i] != b[i] { - return int(i) + checked - } - } - return len(a) + checked -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/gen_inflate.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/gen_inflate.go deleted file mode 100644 index c74a95fe7f6..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/gen_inflate.go +++ /dev/null @@ -1,274 +0,0 @@ -// +build generate - -//go:generate go run $GOFILE && gofmt -w inflate_gen.go - -package main - -import ( - "os" - "strings" -) - -func main() { - f, err := os.Create("inflate_gen.go") - if err != nil { - panic(err) - } - defer f.Close() - types := []string{"*bytes.Buffer", "*bytes.Reader", "*bufio.Reader", "*strings.Reader"} - names := []string{"BytesBuffer", "BytesReader", "BufioReader", "StringsReader"} - imports := []string{"bytes", "bufio", "io", "strings", "math/bits"} - f.WriteString(`// Code generated by go generate gen_inflate.go. DO NOT EDIT. - -package flate - -import ( -`) - - for _, imp := range imports { - f.WriteString("\t\"" + imp + "\"\n") - } - f.WriteString(")\n\n") - - template := ` - -// Decode a single Huffman block from f. -// hl and hd are the Huffman states for the lit/length values -// and the distance values, respectively. If hd == nil, using the -// fixed distance encoding associated with fixed Huffman blocks. -func (f *decompressor) $FUNCNAME$() { - const ( - stateInit = iota // Zero value must be stateInit - stateDict - ) - fr := f.r.($TYPE$) - moreBits := func() error { - c, err := fr.ReadByte() - if err != nil { - return noEOF(err) - } - f.roffset++ - f.b |= uint32(c) << f.nb - f.nb += 8 - return nil - } - - switch f.stepState { - case stateInit: - goto readLiteral - case stateDict: - goto copyHistory - } - -readLiteral: - // Read literal and/or (length, distance) according to RFC section 3.2.3. - { - var v int - { - // Inlined v, err := f.huffSym(f.hl) - // Since a huffmanDecoder can be empty or be composed of a degenerate tree - // with single element, huffSym must error on these two edge cases. In both - // cases, the chunks slice will be 0 for the invalid sequence, leading it - // satisfy the n == 0 check below. - n := uint(f.hl.maxRead) - // Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers, - // but is smart enough to keep local variables in registers, so use nb and b, - // inline call to moreBits and reassign b,nb back to f on return. - nb, b := f.nb, f.b - for { - for nb < n { - c, err := fr.ReadByte() - if err != nil { - f.b = b - f.nb = nb - f.err = noEOF(err) - return - } - f.roffset++ - b |= uint32(c) << (nb & 31) - nb += 8 - } - chunk := f.hl.chunks[b&(huffmanNumChunks-1)] - n = uint(chunk & huffmanCountMask) - if n > huffmanChunkBits { - chunk = f.hl.links[chunk>>huffmanValueShift][(b>>huffmanChunkBits)&f.hl.linkMask] - n = uint(chunk & huffmanCountMask) - } - if n <= nb { - if n == 0 { - f.b = b - f.nb = nb - if debugDecode { - fmt.Println("huffsym: n==0") - } - f.err = CorruptInputError(f.roffset) - return - } - f.b = b >> (n & 31) - f.nb = nb - n - v = int(chunk >> huffmanValueShift) - break - } - } - } - - var n uint // number of bits extra - var length int - var err error - switch { - case v < 256: - f.dict.writeByte(byte(v)) - if f.dict.availWrite() == 0 { - f.toRead = f.dict.readFlush() - f.step = (*decompressor).$FUNCNAME$ - f.stepState = stateInit - return - } - goto readLiteral - case v == 256: - f.finishBlock() - return - // otherwise, reference to older data - case v < 265: - length = v - (257 - 3) - n = 0 - case v < 269: - length = v*2 - (265*2 - 11) - n = 1 - case v < 273: - length = v*4 - (269*4 - 19) - n = 2 - case v < 277: - length = v*8 - (273*8 - 35) - n = 3 - case v < 281: - length = v*16 - (277*16 - 67) - n = 4 - case v < 285: - length = v*32 - (281*32 - 131) - n = 5 - case v < maxNumLit: - length = 258 - n = 0 - default: - if debugDecode { - fmt.Println(v, ">= maxNumLit") - } - f.err = CorruptInputError(f.roffset) - return - } - if n > 0 { - for f.nb < n { - if err = moreBits(); err != nil { - if debugDecode { - fmt.Println("morebits n>0:", err) - } - f.err = err - return - } - } - length += int(f.b & uint32(1<>= n - f.nb -= n - } - - var dist int - if f.hd == nil { - for f.nb < 5 { - if err = moreBits(); err != nil { - if debugDecode { - fmt.Println("morebits f.nb<5:", err) - } - f.err = err - return - } - } - dist = int(bits.Reverse8(uint8(f.b & 0x1F << 3))) - f.b >>= 5 - f.nb -= 5 - } else { - if dist, err = f.huffSym(f.hd); err != nil { - if debugDecode { - fmt.Println("huffsym:", err) - } - f.err = err - return - } - } - - switch { - case dist < 4: - dist++ - case dist < maxNumDist: - nb := uint(dist-2) >> 1 - // have 1 bit in bottom of dist, need nb more. - extra := (dist & 1) << nb - for f.nb < nb { - if err = moreBits(); err != nil { - if debugDecode { - fmt.Println("morebits f.nb>= nb - f.nb -= nb - dist = 1<<(nb+1) + 1 + extra - default: - if debugDecode { - fmt.Println("dist too big:", dist, maxNumDist) - } - f.err = CorruptInputError(f.roffset) - return - } - - // No check on length; encoding can be prescient. - if dist > f.dict.histSize() { - if debugDecode { - fmt.Println("dist > f.dict.histSize():", dist, f.dict.histSize()) - } - f.err = CorruptInputError(f.roffset) - return - } - - f.copyLen, f.copyDist = length, dist - goto copyHistory - } - -copyHistory: - // Perform a backwards copy according to RFC section 3.2.3. - { - cnt := f.dict.tryWriteCopy(f.copyDist, f.copyLen) - if cnt == 0 { - cnt = f.dict.writeCopy(f.copyDist, f.copyLen) - } - f.copyLen -= cnt - - if f.dict.availWrite() == 0 || f.copyLen > 0 { - f.toRead = f.dict.readFlush() - f.step = (*decompressor).$FUNCNAME$ // We need to continue this work - f.stepState = stateDict - return - } - goto readLiteral - } -} - -` - for i, t := range types { - s := strings.Replace(template, "$FUNCNAME$", "huffman"+names[i], -1) - s = strings.Replace(s, "$TYPE$", t, -1) - f.WriteString(s) - } - f.WriteString("func (f *decompressor) huffmanBlockDecoder() func() {\n") - f.WriteString("\tswitch f.r.(type) {\n") - for i, t := range types { - f.WriteString("\t\tcase " + t + ":\n") - f.WriteString("\t\t\treturn f.huffman" + names[i] + "\n") - } - f.WriteString("\t\tdefault:\n") - f.WriteString("\t\t\treturn f.huffmanBlockGeneric") - f.WriteString("\t}\n}\n") -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/huffman_bit_writer.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/huffman_bit_writer.go deleted file mode 100644 index 53fe1d06e25..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/huffman_bit_writer.go +++ /dev/null @@ -1,911 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flate - -import ( - "io" -) - -const ( - // The largest offset code. - offsetCodeCount = 30 - - // The special code used to mark the end of a block. - endBlockMarker = 256 - - // The first length code. - lengthCodesStart = 257 - - // The number of codegen codes. - codegenCodeCount = 19 - badCode = 255 - - // bufferFlushSize indicates the buffer size - // after which bytes are flushed to the writer. - // Should preferably be a multiple of 6, since - // we accumulate 6 bytes between writes to the buffer. - bufferFlushSize = 240 - - // bufferSize is the actual output byte buffer size. - // It must have additional headroom for a flush - // which can contain up to 8 bytes. - bufferSize = bufferFlushSize + 8 -) - -// The number of extra bits needed by length code X - LENGTH_CODES_START. -var lengthExtraBits = [32]int8{ - /* 257 */ 0, 0, 0, - /* 260 */ 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, - /* 270 */ 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, - /* 280 */ 4, 5, 5, 5, 5, 0, -} - -// The length indicated by length code X - LENGTH_CODES_START. -var lengthBase = [32]uint8{ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, - 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, - 64, 80, 96, 112, 128, 160, 192, 224, 255, -} - -// offset code word extra bits. -var offsetExtraBits = [64]int8{ - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, - 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, - 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, - /* extended window */ - 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, -} - -var offsetBase = [64]uint32{ - /* normal deflate */ - 0x000000, 0x000001, 0x000002, 0x000003, 0x000004, - 0x000006, 0x000008, 0x00000c, 0x000010, 0x000018, - 0x000020, 0x000030, 0x000040, 0x000060, 0x000080, - 0x0000c0, 0x000100, 0x000180, 0x000200, 0x000300, - 0x000400, 0x000600, 0x000800, 0x000c00, 0x001000, - 0x001800, 0x002000, 0x003000, 0x004000, 0x006000, - - /* extended window */ - 0x008000, 0x00c000, 0x010000, 0x018000, 0x020000, - 0x030000, 0x040000, 0x060000, 0x080000, 0x0c0000, - 0x100000, 0x180000, 0x200000, 0x300000, -} - -// The odd order in which the codegen code sizes are written. -var codegenOrder = []uint32{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15} - -type huffmanBitWriter struct { - // writer is the underlying writer. - // Do not use it directly; use the write method, which ensures - // that Write errors are sticky. - writer io.Writer - - // Data waiting to be written is bytes[0:nbytes] - // and then the low nbits of bits. - bits uint64 - nbits uint16 - nbytes uint8 - literalEncoding *huffmanEncoder - offsetEncoding *huffmanEncoder - codegenEncoding *huffmanEncoder - err error - lastHeader int - // Set between 0 (reused block can be up to 2x the size) - logNewTablePenalty uint - lastHuffMan bool - bytes [256]byte - literalFreq [lengthCodesStart + 32]uint16 - offsetFreq [32]uint16 - codegenFreq [codegenCodeCount]uint16 - - // codegen must have an extra space for the final symbol. - codegen [literalCount + offsetCodeCount + 1]uint8 -} - -// Huffman reuse. -// -// The huffmanBitWriter supports reusing huffman tables and thereby combining block sections. -// -// This is controlled by several variables: -// -// If lastHeader is non-zero the Huffman table can be reused. -// This also indicates that a Huffman table has been generated that can output all -// possible symbols. -// It also indicates that an EOB has not yet been emitted, so if a new tabel is generated -// an EOB with the previous table must be written. -// -// If lastHuffMan is set, a table for outputting literals has been generated and offsets are invalid. -// -// An incoming block estimates the output size of a new table using a 'fresh' by calculating the -// optimal size and adding a penalty in 'logNewTablePenalty'. -// A Huffman table is not optimal, which is why we add a penalty, and generating a new table -// is slower both for compression and decompression. - -func newHuffmanBitWriter(w io.Writer) *huffmanBitWriter { - return &huffmanBitWriter{ - writer: w, - literalEncoding: newHuffmanEncoder(literalCount), - codegenEncoding: newHuffmanEncoder(codegenCodeCount), - offsetEncoding: newHuffmanEncoder(offsetCodeCount), - } -} - -func (w *huffmanBitWriter) reset(writer io.Writer) { - w.writer = writer - w.bits, w.nbits, w.nbytes, w.err = 0, 0, 0, nil - w.lastHeader = 0 - w.lastHuffMan = false -} - -func (w *huffmanBitWriter) canReuse(t *tokens) (offsets, lits bool) { - offsets, lits = true, true - a := t.offHist[:offsetCodeCount] - b := w.offsetFreq[:len(a)] - for i := range a { - if b[i] == 0 && a[i] != 0 { - offsets = false - break - } - } - - a = t.extraHist[:literalCount-256] - b = w.literalFreq[256:literalCount] - b = b[:len(a)] - for i := range a { - if b[i] == 0 && a[i] != 0 { - lits = false - break - } - } - if lits { - a = t.litHist[:] - b = w.literalFreq[:len(a)] - for i := range a { - if b[i] == 0 && a[i] != 0 { - lits = false - break - } - } - } - return -} - -func (w *huffmanBitWriter) flush() { - if w.err != nil { - w.nbits = 0 - return - } - if w.lastHeader > 0 { - // We owe an EOB - w.writeCode(w.literalEncoding.codes[endBlockMarker]) - w.lastHeader = 0 - } - n := w.nbytes - for w.nbits != 0 { - w.bytes[n] = byte(w.bits) - w.bits >>= 8 - if w.nbits > 8 { // Avoid underflow - w.nbits -= 8 - } else { - w.nbits = 0 - } - n++ - } - w.bits = 0 - w.write(w.bytes[:n]) - w.nbytes = 0 -} - -func (w *huffmanBitWriter) write(b []byte) { - if w.err != nil { - return - } - _, w.err = w.writer.Write(b) -} - -func (w *huffmanBitWriter) writeBits(b int32, nb uint16) { - w.bits |= uint64(b) << (w.nbits & 63) - w.nbits += nb - if w.nbits >= 48 { - w.writeOutBits() - } -} - -func (w *huffmanBitWriter) writeBytes(bytes []byte) { - if w.err != nil { - return - } - n := w.nbytes - if w.nbits&7 != 0 { - w.err = InternalError("writeBytes with unfinished bits") - return - } - for w.nbits != 0 { - w.bytes[n] = byte(w.bits) - w.bits >>= 8 - w.nbits -= 8 - n++ - } - if n != 0 { - w.write(w.bytes[:n]) - } - w.nbytes = 0 - w.write(bytes) -} - -// RFC 1951 3.2.7 specifies a special run-length encoding for specifying -// the literal and offset lengths arrays (which are concatenated into a single -// array). This method generates that run-length encoding. -// -// The result is written into the codegen array, and the frequencies -// of each code is written into the codegenFreq array. -// Codes 0-15 are single byte codes. Codes 16-18 are followed by additional -// information. Code badCode is an end marker -// -// numLiterals The number of literals in literalEncoding -// numOffsets The number of offsets in offsetEncoding -// litenc, offenc The literal and offset encoder to use -func (w *huffmanBitWriter) generateCodegen(numLiterals int, numOffsets int, litEnc, offEnc *huffmanEncoder) { - for i := range w.codegenFreq { - w.codegenFreq[i] = 0 - } - // Note that we are using codegen both as a temporary variable for holding - // a copy of the frequencies, and as the place where we put the result. - // This is fine because the output is always shorter than the input used - // so far. - codegen := w.codegen[:] // cache - // Copy the concatenated code sizes to codegen. Put a marker at the end. - cgnl := codegen[:numLiterals] - for i := range cgnl { - cgnl[i] = uint8(litEnc.codes[i].len) - } - - cgnl = codegen[numLiterals : numLiterals+numOffsets] - for i := range cgnl { - cgnl[i] = uint8(offEnc.codes[i].len) - } - codegen[numLiterals+numOffsets] = badCode - - size := codegen[0] - count := 1 - outIndex := 0 - for inIndex := 1; size != badCode; inIndex++ { - // INVARIANT: We have seen "count" copies of size that have not yet - // had output generated for them. - nextSize := codegen[inIndex] - if nextSize == size { - count++ - continue - } - // We need to generate codegen indicating "count" of size. - if size != 0 { - codegen[outIndex] = size - outIndex++ - w.codegenFreq[size]++ - count-- - for count >= 3 { - n := 6 - if n > count { - n = count - } - codegen[outIndex] = 16 - outIndex++ - codegen[outIndex] = uint8(n - 3) - outIndex++ - w.codegenFreq[16]++ - count -= n - } - } else { - for count >= 11 { - n := 138 - if n > count { - n = count - } - codegen[outIndex] = 18 - outIndex++ - codegen[outIndex] = uint8(n - 11) - outIndex++ - w.codegenFreq[18]++ - count -= n - } - if count >= 3 { - // count >= 3 && count <= 10 - codegen[outIndex] = 17 - outIndex++ - codegen[outIndex] = uint8(count - 3) - outIndex++ - w.codegenFreq[17]++ - count = 0 - } - } - count-- - for ; count >= 0; count-- { - codegen[outIndex] = size - outIndex++ - w.codegenFreq[size]++ - } - // Set up invariant for next time through the loop. - size = nextSize - count = 1 - } - // Marker indicating the end of the codegen. - codegen[outIndex] = badCode -} - -func (w *huffmanBitWriter) codegens() int { - numCodegens := len(w.codegenFreq) - for numCodegens > 4 && w.codegenFreq[codegenOrder[numCodegens-1]] == 0 { - numCodegens-- - } - return numCodegens -} - -func (w *huffmanBitWriter) headerSize() (size, numCodegens int) { - numCodegens = len(w.codegenFreq) - for numCodegens > 4 && w.codegenFreq[codegenOrder[numCodegens-1]] == 0 { - numCodegens-- - } - return 3 + 5 + 5 + 4 + (3 * numCodegens) + - w.codegenEncoding.bitLength(w.codegenFreq[:]) + - int(w.codegenFreq[16])*2 + - int(w.codegenFreq[17])*3 + - int(w.codegenFreq[18])*7, numCodegens -} - -// dynamicSize returns the size of dynamically encoded data in bits. -func (w *huffmanBitWriter) dynamicReuseSize(litEnc, offEnc *huffmanEncoder) (size int) { - size = litEnc.bitLength(w.literalFreq[:]) + - offEnc.bitLength(w.offsetFreq[:]) - return size -} - -// dynamicSize returns the size of dynamically encoded data in bits. -func (w *huffmanBitWriter) dynamicSize(litEnc, offEnc *huffmanEncoder, extraBits int) (size, numCodegens int) { - header, numCodegens := w.headerSize() - size = header + - litEnc.bitLength(w.literalFreq[:]) + - offEnc.bitLength(w.offsetFreq[:]) + - extraBits - return size, numCodegens -} - -// extraBitSize will return the number of bits that will be written -// as "extra" bits on matches. -func (w *huffmanBitWriter) extraBitSize() int { - total := 0 - for i, n := range w.literalFreq[257:literalCount] { - total += int(n) * int(lengthExtraBits[i&31]) - } - for i, n := range w.offsetFreq[:offsetCodeCount] { - total += int(n) * int(offsetExtraBits[i&31]) - } - return total -} - -// fixedSize returns the size of dynamically encoded data in bits. -func (w *huffmanBitWriter) fixedSize(extraBits int) int { - return 3 + - fixedLiteralEncoding.bitLength(w.literalFreq[:]) + - fixedOffsetEncoding.bitLength(w.offsetFreq[:]) + - extraBits -} - -// storedSize calculates the stored size, including header. -// The function returns the size in bits and whether the block -// fits inside a single block. -func (w *huffmanBitWriter) storedSize(in []byte) (int, bool) { - if in == nil { - return 0, false - } - if len(in) <= maxStoreBlockSize { - return (len(in) + 5) * 8, true - } - return 0, false -} - -func (w *huffmanBitWriter) writeCode(c hcode) { - // The function does not get inlined if we "& 63" the shift. - w.bits |= uint64(c.code) << w.nbits - w.nbits += c.len - if w.nbits >= 48 { - w.writeOutBits() - } -} - -// writeOutBits will write bits to the buffer. -func (w *huffmanBitWriter) writeOutBits() { - bits := w.bits - w.bits >>= 48 - w.nbits -= 48 - n := w.nbytes - w.bytes[n] = byte(bits) - w.bytes[n+1] = byte(bits >> 8) - w.bytes[n+2] = byte(bits >> 16) - w.bytes[n+3] = byte(bits >> 24) - w.bytes[n+4] = byte(bits >> 32) - w.bytes[n+5] = byte(bits >> 40) - n += 6 - if n >= bufferFlushSize { - if w.err != nil { - n = 0 - return - } - w.write(w.bytes[:n]) - n = 0 - } - w.nbytes = n -} - -// Write the header of a dynamic Huffman block to the output stream. -// -// numLiterals The number of literals specified in codegen -// numOffsets The number of offsets specified in codegen -// numCodegens The number of codegens used in codegen -func (w *huffmanBitWriter) writeDynamicHeader(numLiterals int, numOffsets int, numCodegens int, isEof bool) { - if w.err != nil { - return - } - var firstBits int32 = 4 - if isEof { - firstBits = 5 - } - w.writeBits(firstBits, 3) - w.writeBits(int32(numLiterals-257), 5) - w.writeBits(int32(numOffsets-1), 5) - w.writeBits(int32(numCodegens-4), 4) - - for i := 0; i < numCodegens; i++ { - value := uint(w.codegenEncoding.codes[codegenOrder[i]].len) - w.writeBits(int32(value), 3) - } - - i := 0 - for { - var codeWord = uint32(w.codegen[i]) - i++ - if codeWord == badCode { - break - } - w.writeCode(w.codegenEncoding.codes[codeWord]) - - switch codeWord { - case 16: - w.writeBits(int32(w.codegen[i]), 2) - i++ - case 17: - w.writeBits(int32(w.codegen[i]), 3) - i++ - case 18: - w.writeBits(int32(w.codegen[i]), 7) - i++ - } - } -} - -// writeStoredHeader will write a stored header. -// If the stored block is only used for EOF, -// it is replaced with a fixed huffman block. -func (w *huffmanBitWriter) writeStoredHeader(length int, isEof bool) { - if w.err != nil { - return - } - if w.lastHeader > 0 { - // We owe an EOB - w.writeCode(w.literalEncoding.codes[endBlockMarker]) - w.lastHeader = 0 - } - - // To write EOF, use a fixed encoding block. 10 bits instead of 5 bytes. - if length == 0 && isEof { - w.writeFixedHeader(isEof) - // EOB: 7 bits, value: 0 - w.writeBits(0, 7) - w.flush() - return - } - - var flag int32 - if isEof { - flag = 1 - } - w.writeBits(flag, 3) - w.flush() - w.writeBits(int32(length), 16) - w.writeBits(int32(^uint16(length)), 16) -} - -func (w *huffmanBitWriter) writeFixedHeader(isEof bool) { - if w.err != nil { - return - } - if w.lastHeader > 0 { - // We owe an EOB - w.writeCode(w.literalEncoding.codes[endBlockMarker]) - w.lastHeader = 0 - } - - // Indicate that we are a fixed Huffman block - var value int32 = 2 - if isEof { - value = 3 - } - w.writeBits(value, 3) -} - -// writeBlock will write a block of tokens with the smallest encoding. -// The original input can be supplied, and if the huffman encoded data -// is larger than the original bytes, the data will be written as a -// stored block. -// If the input is nil, the tokens will always be Huffman encoded. -func (w *huffmanBitWriter) writeBlock(tokens *tokens, eof bool, input []byte) { - if w.err != nil { - return - } - - tokens.AddEOB() - if w.lastHeader > 0 { - // We owe an EOB - w.writeCode(w.literalEncoding.codes[endBlockMarker]) - w.lastHeader = 0 - } - numLiterals, numOffsets := w.indexTokens(tokens, false) - w.generate(tokens) - var extraBits int - storedSize, storable := w.storedSize(input) - if storable { - extraBits = w.extraBitSize() - } - - // Figure out smallest code. - // Fixed Huffman baseline. - var literalEncoding = fixedLiteralEncoding - var offsetEncoding = fixedOffsetEncoding - var size = w.fixedSize(extraBits) - - // Dynamic Huffman? - var numCodegens int - - // Generate codegen and codegenFrequencies, which indicates how to encode - // the literalEncoding and the offsetEncoding. - w.generateCodegen(numLiterals, numOffsets, w.literalEncoding, w.offsetEncoding) - w.codegenEncoding.generate(w.codegenFreq[:], 7) - dynamicSize, numCodegens := w.dynamicSize(w.literalEncoding, w.offsetEncoding, extraBits) - - if dynamicSize < size { - size = dynamicSize - literalEncoding = w.literalEncoding - offsetEncoding = w.offsetEncoding - } - - // Stored bytes? - if storable && storedSize < size { - w.writeStoredHeader(len(input), eof) - w.writeBytes(input) - return - } - - // Huffman. - if literalEncoding == fixedLiteralEncoding { - w.writeFixedHeader(eof) - } else { - w.writeDynamicHeader(numLiterals, numOffsets, numCodegens, eof) - } - - // Write the tokens. - w.writeTokens(tokens.Slice(), literalEncoding.codes, offsetEncoding.codes) -} - -// writeBlockDynamic encodes a block using a dynamic Huffman table. -// This should be used if the symbols used have a disproportionate -// histogram distribution. -// If input is supplied and the compression savings are below 1/16th of the -// input size the block is stored. -func (w *huffmanBitWriter) writeBlockDynamic(tokens *tokens, eof bool, input []byte, sync bool) { - if w.err != nil { - return - } - - sync = sync || eof - if sync { - tokens.AddEOB() - } - - // We cannot reuse pure huffman table, and must mark as EOF. - if (w.lastHuffMan || eof) && w.lastHeader > 0 { - // We will not try to reuse. - w.writeCode(w.literalEncoding.codes[endBlockMarker]) - w.lastHeader = 0 - w.lastHuffMan = false - } - if !sync { - tokens.Fill() - } - numLiterals, numOffsets := w.indexTokens(tokens, !sync) - - var size int - // Check if we should reuse. - if w.lastHeader > 0 { - // Estimate size for using a new table. - // Use the previous header size as the best estimate. - newSize := w.lastHeader + tokens.EstimatedBits() - newSize += newSize >> w.logNewTablePenalty - - // The estimated size is calculated as an optimal table. - // We add a penalty to make it more realistic and re-use a bit more. - reuseSize := w.dynamicReuseSize(w.literalEncoding, w.offsetEncoding) + w.extraBitSize() - - // Check if a new table is better. - if newSize < reuseSize { - // Write the EOB we owe. - w.writeCode(w.literalEncoding.codes[endBlockMarker]) - size = newSize - w.lastHeader = 0 - } else { - size = reuseSize - } - // Check if we get a reasonable size decrease. - if ssize, storable := w.storedSize(input); storable && ssize < (size+size>>4) { - w.writeStoredHeader(len(input), eof) - w.writeBytes(input) - w.lastHeader = 0 - return - } - } - - // We want a new block/table - if w.lastHeader == 0 { - w.generate(tokens) - // Generate codegen and codegenFrequencies, which indicates how to encode - // the literalEncoding and the offsetEncoding. - w.generateCodegen(numLiterals, numOffsets, w.literalEncoding, w.offsetEncoding) - w.codegenEncoding.generate(w.codegenFreq[:], 7) - var numCodegens int - size, numCodegens = w.dynamicSize(w.literalEncoding, w.offsetEncoding, w.extraBitSize()) - // Store bytes, if we don't get a reasonable improvement. - if ssize, storable := w.storedSize(input); storable && ssize < (size+size>>4) { - w.writeStoredHeader(len(input), eof) - w.writeBytes(input) - w.lastHeader = 0 - return - } - - // Write Huffman table. - w.writeDynamicHeader(numLiterals, numOffsets, numCodegens, eof) - w.lastHeader, _ = w.headerSize() - w.lastHuffMan = false - } - - if sync { - w.lastHeader = 0 - } - // Write the tokens. - w.writeTokens(tokens.Slice(), w.literalEncoding.codes, w.offsetEncoding.codes) -} - -// indexTokens indexes a slice of tokens, and updates -// literalFreq and offsetFreq, and generates literalEncoding -// and offsetEncoding. -// The number of literal and offset tokens is returned. -func (w *huffmanBitWriter) indexTokens(t *tokens, filled bool) (numLiterals, numOffsets int) { - copy(w.literalFreq[:], t.litHist[:]) - copy(w.literalFreq[256:], t.extraHist[:]) - copy(w.offsetFreq[:], t.offHist[:offsetCodeCount]) - - if t.n == 0 { - return - } - if filled { - return maxNumLit, maxNumDist - } - // get the number of literals - numLiterals = len(w.literalFreq) - for w.literalFreq[numLiterals-1] == 0 { - numLiterals-- - } - // get the number of offsets - numOffsets = len(w.offsetFreq) - for numOffsets > 0 && w.offsetFreq[numOffsets-1] == 0 { - numOffsets-- - } - if numOffsets == 0 { - // We haven't found a single match. If we want to go with the dynamic encoding, - // we should count at least one offset to be sure that the offset huffman tree could be encoded. - w.offsetFreq[0] = 1 - numOffsets = 1 - } - return -} - -func (w *huffmanBitWriter) generate(t *tokens) { - w.literalEncoding.generate(w.literalFreq[:literalCount], 15) - w.offsetEncoding.generate(w.offsetFreq[:offsetCodeCount], 15) -} - -// writeTokens writes a slice of tokens to the output. -// codes for literal and offset encoding must be supplied. -func (w *huffmanBitWriter) writeTokens(tokens []token, leCodes, oeCodes []hcode) { - if w.err != nil { - return - } - if len(tokens) == 0 { - return - } - - // Only last token should be endBlockMarker. - var deferEOB bool - if tokens[len(tokens)-1] == endBlockMarker { - tokens = tokens[:len(tokens)-1] - deferEOB = true - } - - // Create slices up to the next power of two to avoid bounds checks. - lits := leCodes[:256] - offs := oeCodes[:32] - lengths := leCodes[lengthCodesStart:] - lengths = lengths[:32] - for _, t := range tokens { - if t < matchType { - w.writeCode(lits[t.literal()]) - continue - } - - // Write the length - length := t.length() - lengthCode := lengthCode(length) - if false { - w.writeCode(lengths[lengthCode&31]) - } else { - // inlined - c := lengths[lengthCode&31] - w.bits |= uint64(c.code) << (w.nbits & 63) - w.nbits += c.len - if w.nbits >= 48 { - w.writeOutBits() - } - } - - extraLengthBits := uint16(lengthExtraBits[lengthCode&31]) - if extraLengthBits > 0 { - extraLength := int32(length - lengthBase[lengthCode&31]) - w.writeBits(extraLength, extraLengthBits) - } - // Write the offset - offset := t.offset() - offsetCode := offsetCode(offset) - if false { - w.writeCode(offs[offsetCode&31]) - } else { - // inlined - c := offs[offsetCode&31] - w.bits |= uint64(c.code) << (w.nbits & 63) - w.nbits += c.len - if w.nbits >= 48 { - w.writeOutBits() - } - } - extraOffsetBits := uint16(offsetExtraBits[offsetCode&63]) - if extraOffsetBits > 0 { - extraOffset := int32(offset - offsetBase[offsetCode&63]) - w.writeBits(extraOffset, extraOffsetBits) - } - } - if deferEOB { - w.writeCode(leCodes[endBlockMarker]) - } -} - -// huffOffset is a static offset encoder used for huffman only encoding. -// It can be reused since we will not be encoding offset values. -var huffOffset *huffmanEncoder - -func init() { - w := newHuffmanBitWriter(nil) - w.offsetFreq[0] = 1 - huffOffset = newHuffmanEncoder(offsetCodeCount) - huffOffset.generate(w.offsetFreq[:offsetCodeCount], 15) -} - -// writeBlockHuff encodes a block of bytes as either -// Huffman encoded literals or uncompressed bytes if the -// results only gains very little from compression. -func (w *huffmanBitWriter) writeBlockHuff(eof bool, input []byte, sync bool) { - if w.err != nil { - return - } - - // Clear histogram - for i := range w.literalFreq[:] { - w.literalFreq[i] = 0 - } - if !w.lastHuffMan { - for i := range w.offsetFreq[:] { - w.offsetFreq[i] = 0 - } - } - - // Add everything as literals - // We have to estimate the header size. - // Assume header is around 70 bytes: - // https://stackoverflow.com/a/25454430 - const guessHeaderSizeBits = 70 * 8 - estBits, estExtra := histogramSize(input, w.literalFreq[:], !eof && !sync) - estBits += w.lastHeader + 15 - if w.lastHeader == 0 { - estBits += guessHeaderSizeBits - } - estBits += estBits >> w.logNewTablePenalty - - // Store bytes, if we don't get a reasonable improvement. - ssize, storable := w.storedSize(input) - if storable && ssize < estBits { - w.writeStoredHeader(len(input), eof) - w.writeBytes(input) - return - } - - if w.lastHeader > 0 { - reuseSize := w.literalEncoding.bitLength(w.literalFreq[:256]) - estBits += estExtra - - if estBits < reuseSize { - // We owe an EOB - w.writeCode(w.literalEncoding.codes[endBlockMarker]) - w.lastHeader = 0 - } - } - - const numLiterals = endBlockMarker + 1 - const numOffsets = 1 - if w.lastHeader == 0 { - w.literalFreq[endBlockMarker] = 1 - w.literalEncoding.generate(w.literalFreq[:numLiterals], 15) - - // Generate codegen and codegenFrequencies, which indicates how to encode - // the literalEncoding and the offsetEncoding. - w.generateCodegen(numLiterals, numOffsets, w.literalEncoding, huffOffset) - w.codegenEncoding.generate(w.codegenFreq[:], 7) - numCodegens := w.codegens() - - // Huffman. - w.writeDynamicHeader(numLiterals, numOffsets, numCodegens, eof) - w.lastHuffMan = true - w.lastHeader, _ = w.headerSize() - } - - encoding := w.literalEncoding.codes[:257] - for _, t := range input { - // Bitwriting inlined, ~30% speedup - c := encoding[t] - w.bits |= uint64(c.code) << ((w.nbits) & 63) - w.nbits += c.len - if w.nbits >= 48 { - bits := w.bits - w.bits >>= 48 - w.nbits -= 48 - n := w.nbytes - w.bytes[n] = byte(bits) - w.bytes[n+1] = byte(bits >> 8) - w.bytes[n+2] = byte(bits >> 16) - w.bytes[n+3] = byte(bits >> 24) - w.bytes[n+4] = byte(bits >> 32) - w.bytes[n+5] = byte(bits >> 40) - n += 6 - if n >= bufferFlushSize { - if w.err != nil { - n = 0 - return - } - w.write(w.bytes[:n]) - n = 0 - } - w.nbytes = n - } - } - if eof || sync { - w.writeCode(encoding[endBlockMarker]) - w.lastHeader = 0 - w.lastHuffMan = false - } -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/huffman_code.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/huffman_code.go deleted file mode 100644 index 4c39a301871..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/huffman_code.go +++ /dev/null @@ -1,363 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flate - -import ( - "math" - "math/bits" -) - -const ( - maxBitsLimit = 16 - // number of valid literals - literalCount = 286 -) - -// hcode is a huffman code with a bit code and bit length. -type hcode struct { - code, len uint16 -} - -type huffmanEncoder struct { - codes []hcode - freqcache []literalNode - bitCount [17]int32 -} - -type literalNode struct { - literal uint16 - freq uint16 -} - -// A levelInfo describes the state of the constructed tree for a given depth. -type levelInfo struct { - // Our level. for better printing - level int32 - - // The frequency of the last node at this level - lastFreq int32 - - // The frequency of the next character to add to this level - nextCharFreq int32 - - // The frequency of the next pair (from level below) to add to this level. - // Only valid if the "needed" value of the next lower level is 0. - nextPairFreq int32 - - // The number of chains remaining to generate for this level before moving - // up to the next level - needed int32 -} - -// set sets the code and length of an hcode. -func (h *hcode) set(code uint16, length uint16) { - h.len = length - h.code = code -} - -func reverseBits(number uint16, bitLength byte) uint16 { - return bits.Reverse16(number << ((16 - bitLength) & 15)) -} - -func maxNode() literalNode { return literalNode{math.MaxUint16, math.MaxUint16} } - -func newHuffmanEncoder(size int) *huffmanEncoder { - // Make capacity to next power of two. - c := uint(bits.Len32(uint32(size - 1))) - return &huffmanEncoder{codes: make([]hcode, size, 1<= 3 -// The cases of 0, 1, and 2 literals are handled by special case code. -// -// list An array of the literals with non-zero frequencies -// and their associated frequencies. The array is in order of increasing -// frequency, and has as its last element a special element with frequency -// MaxInt32 -// maxBits The maximum number of bits that should be used to encode any literal. -// Must be less than 16. -// return An integer array in which array[i] indicates the number of literals -// that should be encoded in i bits. -func (h *huffmanEncoder) bitCounts(list []literalNode, maxBits int32) []int32 { - if maxBits >= maxBitsLimit { - panic("flate: maxBits too large") - } - n := int32(len(list)) - list = list[0 : n+1] - list[n] = maxNode() - - // The tree can't have greater depth than n - 1, no matter what. This - // saves a little bit of work in some small cases - if maxBits > n-1 { - maxBits = n - 1 - } - - // Create information about each of the levels. - // A bogus "Level 0" whose sole purpose is so that - // level1.prev.needed==0. This makes level1.nextPairFreq - // be a legitimate value that never gets chosen. - var levels [maxBitsLimit]levelInfo - // leafCounts[i] counts the number of literals at the left - // of ancestors of the rightmost node at level i. - // leafCounts[i][j] is the number of literals at the left - // of the level j ancestor. - var leafCounts [maxBitsLimit][maxBitsLimit]int32 - - for level := int32(1); level <= maxBits; level++ { - // For every level, the first two items are the first two characters. - // We initialize the levels as if we had already figured this out. - levels[level] = levelInfo{ - level: level, - lastFreq: int32(list[1].freq), - nextCharFreq: int32(list[2].freq), - nextPairFreq: int32(list[0].freq) + int32(list[1].freq), - } - leafCounts[level][level] = 2 - if level == 1 { - levels[level].nextPairFreq = math.MaxInt32 - } - } - - // We need a total of 2*n - 2 items at top level and have already generated 2. - levels[maxBits].needed = 2*n - 4 - - level := maxBits - for { - l := &levels[level] - if l.nextPairFreq == math.MaxInt32 && l.nextCharFreq == math.MaxInt32 { - // We've run out of both leafs and pairs. - // End all calculations for this level. - // To make sure we never come back to this level or any lower level, - // set nextPairFreq impossibly large. - l.needed = 0 - levels[level+1].nextPairFreq = math.MaxInt32 - level++ - continue - } - - prevFreq := l.lastFreq - if l.nextCharFreq < l.nextPairFreq { - // The next item on this row is a leaf node. - n := leafCounts[level][level] + 1 - l.lastFreq = l.nextCharFreq - // Lower leafCounts are the same of the previous node. - leafCounts[level][level] = n - e := list[n] - if e.literal < math.MaxUint16 { - l.nextCharFreq = int32(e.freq) - } else { - l.nextCharFreq = math.MaxInt32 - } - } else { - // The next item on this row is a pair from the previous row. - // nextPairFreq isn't valid until we generate two - // more values in the level below - l.lastFreq = l.nextPairFreq - // Take leaf counts from the lower level, except counts[level] remains the same. - copy(leafCounts[level][:level], leafCounts[level-1][:level]) - levels[l.level-1].needed = 2 - } - - if l.needed--; l.needed == 0 { - // We've done everything we need to do for this level. - // Continue calculating one level up. Fill in nextPairFreq - // of that level with the sum of the two nodes we've just calculated on - // this level. - if l.level == maxBits { - // All done! - break - } - levels[l.level+1].nextPairFreq = prevFreq + l.lastFreq - level++ - } else { - // If we stole from below, move down temporarily to replenish it. - for levels[level-1].needed > 0 { - level-- - } - } - } - - // Somethings is wrong if at the end, the top level is null or hasn't used - // all of the leaves. - if leafCounts[maxBits][maxBits] != n { - panic("leafCounts[maxBits][maxBits] != n") - } - - bitCount := h.bitCount[:maxBits+1] - bits := 1 - counts := &leafCounts[maxBits] - for level := maxBits; level > 0; level-- { - // chain.leafCount gives the number of literals requiring at least "bits" - // bits to encode. - bitCount[bits] = counts[level] - counts[level-1] - bits++ - } - return bitCount -} - -// Look at the leaves and assign them a bit count and an encoding as specified -// in RFC 1951 3.2.2 -func (h *huffmanEncoder) assignEncodingAndSize(bitCount []int32, list []literalNode) { - code := uint16(0) - for n, bits := range bitCount { - code <<= 1 - if n == 0 || bits == 0 { - continue - } - // The literals list[len(list)-bits] .. list[len(list)-bits] - // are encoded using "bits" bits, and get the values - // code, code + 1, .... The code values are - // assigned in literal order (not frequency order). - chunk := list[len(list)-int(bits):] - - sortByLiteral(chunk) - for _, node := range chunk { - h.codes[node.literal] = hcode{code: reverseBits(code, uint8(n)), len: uint16(n)} - code++ - } - list = list[0 : len(list)-int(bits)] - } -} - -// Update this Huffman Code object to be the minimum code for the specified frequency count. -// -// freq An array of frequencies, in which frequency[i] gives the frequency of literal i. -// maxBits The maximum number of bits to use for any literal. -func (h *huffmanEncoder) generate(freq []uint16, maxBits int32) { - if h.freqcache == nil { - // Allocate a reusable buffer with the longest possible frequency table. - // Possible lengths are codegenCodeCount, offsetCodeCount and literalCount. - // The largest of these is literalCount, so we allocate for that case. - h.freqcache = make([]literalNode, literalCount+1) - } - list := h.freqcache[:len(freq)+1] - // Number of non-zero literals - count := 0 - // Set list to be the set of all non-zero literals and their frequencies - for i, f := range freq { - if f != 0 { - list[count] = literalNode{uint16(i), f} - count++ - } else { - list[count] = literalNode{} - h.codes[i].len = 0 - } - } - list[len(freq)] = literalNode{} - - list = list[:count] - if count <= 2 { - // Handle the small cases here, because they are awkward for the general case code. With - // two or fewer literals, everything has bit length 1. - for i, node := range list { - // "list" is in order of increasing literal value. - h.codes[node.literal].set(uint16(i), 1) - } - return - } - sortByFreq(list) - - // Get the number of literals for each bit count - bitCount := h.bitCounts(list, maxBits) - // And do the assignment - h.assignEncodingAndSize(bitCount, list) -} - -func atLeastOne(v float32) float32 { - if v < 1 { - return 1 - } - return v -} - -// histogramSize accumulates a histogram of b in h. -// An estimated size in bits is returned. -// Unassigned values are assigned '1' in the histogram. -// len(h) must be >= 256, and h's elements must be all zeroes. -func histogramSize(b []byte, h []uint16, fill bool) (int, int) { - h = h[:256] - for _, t := range b { - h[t]++ - } - invTotal := 1.0 / float32(len(b)) - shannon := float32(0.0) - var extra float32 - if fill { - oneBits := atLeastOne(-mFastLog2(invTotal)) - for i, v := range h[:] { - if v > 0 { - n := float32(v) - shannon += atLeastOne(-mFastLog2(n*invTotal)) * n - } else { - h[i] = 1 - extra += oneBits - } - } - } else { - for _, v := range h[:] { - if v > 0 { - n := float32(v) - shannon += atLeastOne(-mFastLog2(n*invTotal)) * n - } - } - } - - return int(shannon + 0.99), int(extra + 0.99) -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/huffman_sortByFreq.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/huffman_sortByFreq.go deleted file mode 100644 index 20778029900..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/huffman_sortByFreq.go +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flate - -// Sort sorts data. -// It makes one call to data.Len to determine n, and O(n*log(n)) calls to -// data.Less and data.Swap. The sort is not guaranteed to be stable. -func sortByFreq(data []literalNode) { - n := len(data) - quickSortByFreq(data, 0, n, maxDepth(n)) -} - -func quickSortByFreq(data []literalNode, a, b, maxDepth int) { - for b-a > 12 { // Use ShellSort for slices <= 12 elements - if maxDepth == 0 { - heapSort(data, a, b) - return - } - maxDepth-- - mlo, mhi := doPivotByFreq(data, a, b) - // Avoiding recursion on the larger subproblem guarantees - // a stack depth of at most lg(b-a). - if mlo-a < b-mhi { - quickSortByFreq(data, a, mlo, maxDepth) - a = mhi // i.e., quickSortByFreq(data, mhi, b) - } else { - quickSortByFreq(data, mhi, b, maxDepth) - b = mlo // i.e., quickSortByFreq(data, a, mlo) - } - } - if b-a > 1 { - // Do ShellSort pass with gap 6 - // It could be written in this simplified form cause b-a <= 12 - for i := a + 6; i < b; i++ { - if data[i].freq == data[i-6].freq && data[i].literal < data[i-6].literal || data[i].freq < data[i-6].freq { - data[i], data[i-6] = data[i-6], data[i] - } - } - insertionSortByFreq(data, a, b) - } -} - -// siftDownByFreq implements the heap property on data[lo, hi). -// first is an offset into the array where the root of the heap lies. -func siftDownByFreq(data []literalNode, lo, hi, first int) { - root := lo - for { - child := 2*root + 1 - if child >= hi { - break - } - if child+1 < hi && (data[first+child].freq == data[first+child+1].freq && data[first+child].literal < data[first+child+1].literal || data[first+child].freq < data[first+child+1].freq) { - child++ - } - if data[first+root].freq == data[first+child].freq && data[first+root].literal > data[first+child].literal || data[first+root].freq > data[first+child].freq { - return - } - data[first+root], data[first+child] = data[first+child], data[first+root] - root = child - } -} -func doPivotByFreq(data []literalNode, lo, hi int) (midlo, midhi int) { - m := int(uint(lo+hi) >> 1) // Written like this to avoid integer overflow. - if hi-lo > 40 { - // Tukey's ``Ninther,'' median of three medians of three. - s := (hi - lo) / 8 - medianOfThreeSortByFreq(data, lo, lo+s, lo+2*s) - medianOfThreeSortByFreq(data, m, m-s, m+s) - medianOfThreeSortByFreq(data, hi-1, hi-1-s, hi-1-2*s) - } - medianOfThreeSortByFreq(data, lo, m, hi-1) - - // Invariants are: - // data[lo] = pivot (set up by ChoosePivot) - // data[lo < i < a] < pivot - // data[a <= i < b] <= pivot - // data[b <= i < c] unexamined - // data[c <= i < hi-1] > pivot - // data[hi-1] >= pivot - pivot := lo - a, c := lo+1, hi-1 - - for ; a < c && (data[a].freq == data[pivot].freq && data[a].literal < data[pivot].literal || data[a].freq < data[pivot].freq); a++ { - } - b := a - for { - for ; b < c && (data[pivot].freq == data[b].freq && data[pivot].literal > data[b].literal || data[pivot].freq > data[b].freq); b++ { // data[b] <= pivot - } - for ; b < c && (data[pivot].freq == data[c-1].freq && data[pivot].literal < data[c-1].literal || data[pivot].freq < data[c-1].freq); c-- { // data[c-1] > pivot - } - if b >= c { - break - } - // data[b] > pivot; data[c-1] <= pivot - data[b], data[c-1] = data[c-1], data[b] - b++ - c-- - } - // If hi-c<3 then there are duplicates (by property of median of nine). - // Let's be a bit more conservative, and set border to 5. - protect := hi-c < 5 - if !protect && hi-c < (hi-lo)/4 { - // Lets test some points for equality to pivot - dups := 0 - if data[pivot].freq == data[hi-1].freq && data[pivot].literal > data[hi-1].literal || data[pivot].freq > data[hi-1].freq { // data[hi-1] = pivot - data[c], data[hi-1] = data[hi-1], data[c] - c++ - dups++ - } - if data[b-1].freq == data[pivot].freq && data[b-1].literal > data[pivot].literal || data[b-1].freq > data[pivot].freq { // data[b-1] = pivot - b-- - dups++ - } - // m-lo = (hi-lo)/2 > 6 - // b-lo > (hi-lo)*3/4-1 > 8 - // ==> m < b ==> data[m] <= pivot - if data[m].freq == data[pivot].freq && data[m].literal > data[pivot].literal || data[m].freq > data[pivot].freq { // data[m] = pivot - data[m], data[b-1] = data[b-1], data[m] - b-- - dups++ - } - // if at least 2 points are equal to pivot, assume skewed distribution - protect = dups > 1 - } - if protect { - // Protect against a lot of duplicates - // Add invariant: - // data[a <= i < b] unexamined - // data[b <= i < c] = pivot - for { - for ; a < b && (data[b-1].freq == data[pivot].freq && data[b-1].literal > data[pivot].literal || data[b-1].freq > data[pivot].freq); b-- { // data[b] == pivot - } - for ; a < b && (data[a].freq == data[pivot].freq && data[a].literal < data[pivot].literal || data[a].freq < data[pivot].freq); a++ { // data[a] < pivot - } - if a >= b { - break - } - // data[a] == pivot; data[b-1] < pivot - data[a], data[b-1] = data[b-1], data[a] - a++ - b-- - } - } - // Swap pivot into middle - data[pivot], data[b-1] = data[b-1], data[pivot] - return b - 1, c -} - -// Insertion sort -func insertionSortByFreq(data []literalNode, a, b int) { - for i := a + 1; i < b; i++ { - for j := i; j > a && (data[j].freq == data[j-1].freq && data[j].literal < data[j-1].literal || data[j].freq < data[j-1].freq); j-- { - data[j], data[j-1] = data[j-1], data[j] - } - } -} - -// quickSortByFreq, loosely following Bentley and McIlroy, -// ``Engineering a Sort Function,'' SP&E November 1993. - -// medianOfThreeSortByFreq moves the median of the three values data[m0], data[m1], data[m2] into data[m1]. -func medianOfThreeSortByFreq(data []literalNode, m1, m0, m2 int) { - // sort 3 elements - if data[m1].freq == data[m0].freq && data[m1].literal < data[m0].literal || data[m1].freq < data[m0].freq { - data[m1], data[m0] = data[m0], data[m1] - } - // data[m0] <= data[m1] - if data[m2].freq == data[m1].freq && data[m2].literal < data[m1].literal || data[m2].freq < data[m1].freq { - data[m2], data[m1] = data[m1], data[m2] - // data[m0] <= data[m2] && data[m1] < data[m2] - if data[m1].freq == data[m0].freq && data[m1].literal < data[m0].literal || data[m1].freq < data[m0].freq { - data[m1], data[m0] = data[m0], data[m1] - } - } - // now data[m0] <= data[m1] <= data[m2] -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/huffman_sortByLiteral.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/huffman_sortByLiteral.go deleted file mode 100644 index 93f1aea109e..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/huffman_sortByLiteral.go +++ /dev/null @@ -1,201 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flate - -// Sort sorts data. -// It makes one call to data.Len to determine n, and O(n*log(n)) calls to -// data.Less and data.Swap. The sort is not guaranteed to be stable. -func sortByLiteral(data []literalNode) { - n := len(data) - quickSort(data, 0, n, maxDepth(n)) -} - -func quickSort(data []literalNode, a, b, maxDepth int) { - for b-a > 12 { // Use ShellSort for slices <= 12 elements - if maxDepth == 0 { - heapSort(data, a, b) - return - } - maxDepth-- - mlo, mhi := doPivot(data, a, b) - // Avoiding recursion on the larger subproblem guarantees - // a stack depth of at most lg(b-a). - if mlo-a < b-mhi { - quickSort(data, a, mlo, maxDepth) - a = mhi // i.e., quickSort(data, mhi, b) - } else { - quickSort(data, mhi, b, maxDepth) - b = mlo // i.e., quickSort(data, a, mlo) - } - } - if b-a > 1 { - // Do ShellSort pass with gap 6 - // It could be written in this simplified form cause b-a <= 12 - for i := a + 6; i < b; i++ { - if data[i].literal < data[i-6].literal { - data[i], data[i-6] = data[i-6], data[i] - } - } - insertionSort(data, a, b) - } -} -func heapSort(data []literalNode, a, b int) { - first := a - lo := 0 - hi := b - a - - // Build heap with greatest element at top. - for i := (hi - 1) / 2; i >= 0; i-- { - siftDown(data, i, hi, first) - } - - // Pop elements, largest first, into end of data. - for i := hi - 1; i >= 0; i-- { - data[first], data[first+i] = data[first+i], data[first] - siftDown(data, lo, i, first) - } -} - -// siftDown implements the heap property on data[lo, hi). -// first is an offset into the array where the root of the heap lies. -func siftDown(data []literalNode, lo, hi, first int) { - root := lo - for { - child := 2*root + 1 - if child >= hi { - break - } - if child+1 < hi && data[first+child].literal < data[first+child+1].literal { - child++ - } - if data[first+root].literal > data[first+child].literal { - return - } - data[first+root], data[first+child] = data[first+child], data[first+root] - root = child - } -} -func doPivot(data []literalNode, lo, hi int) (midlo, midhi int) { - m := int(uint(lo+hi) >> 1) // Written like this to avoid integer overflow. - if hi-lo > 40 { - // Tukey's ``Ninther,'' median of three medians of three. - s := (hi - lo) / 8 - medianOfThree(data, lo, lo+s, lo+2*s) - medianOfThree(data, m, m-s, m+s) - medianOfThree(data, hi-1, hi-1-s, hi-1-2*s) - } - medianOfThree(data, lo, m, hi-1) - - // Invariants are: - // data[lo] = pivot (set up by ChoosePivot) - // data[lo < i < a] < pivot - // data[a <= i < b] <= pivot - // data[b <= i < c] unexamined - // data[c <= i < hi-1] > pivot - // data[hi-1] >= pivot - pivot := lo - a, c := lo+1, hi-1 - - for ; a < c && data[a].literal < data[pivot].literal; a++ { - } - b := a - for { - for ; b < c && data[pivot].literal > data[b].literal; b++ { // data[b] <= pivot - } - for ; b < c && data[pivot].literal < data[c-1].literal; c-- { // data[c-1] > pivot - } - if b >= c { - break - } - // data[b] > pivot; data[c-1] <= pivot - data[b], data[c-1] = data[c-1], data[b] - b++ - c-- - } - // If hi-c<3 then there are duplicates (by property of median of nine). - // Let's be a bit more conservative, and set border to 5. - protect := hi-c < 5 - if !protect && hi-c < (hi-lo)/4 { - // Lets test some points for equality to pivot - dups := 0 - if data[pivot].literal > data[hi-1].literal { // data[hi-1] = pivot - data[c], data[hi-1] = data[hi-1], data[c] - c++ - dups++ - } - if data[b-1].literal > data[pivot].literal { // data[b-1] = pivot - b-- - dups++ - } - // m-lo = (hi-lo)/2 > 6 - // b-lo > (hi-lo)*3/4-1 > 8 - // ==> m < b ==> data[m] <= pivot - if data[m].literal > data[pivot].literal { // data[m] = pivot - data[m], data[b-1] = data[b-1], data[m] - b-- - dups++ - } - // if at least 2 points are equal to pivot, assume skewed distribution - protect = dups > 1 - } - if protect { - // Protect against a lot of duplicates - // Add invariant: - // data[a <= i < b] unexamined - // data[b <= i < c] = pivot - for { - for ; a < b && data[b-1].literal > data[pivot].literal; b-- { // data[b] == pivot - } - for ; a < b && data[a].literal < data[pivot].literal; a++ { // data[a] < pivot - } - if a >= b { - break - } - // data[a] == pivot; data[b-1] < pivot - data[a], data[b-1] = data[b-1], data[a] - a++ - b-- - } - } - // Swap pivot into middle - data[pivot], data[b-1] = data[b-1], data[pivot] - return b - 1, c -} - -// Insertion sort -func insertionSort(data []literalNode, a, b int) { - for i := a + 1; i < b; i++ { - for j := i; j > a && data[j].literal < data[j-1].literal; j-- { - data[j], data[j-1] = data[j-1], data[j] - } - } -} - -// maxDepth returns a threshold at which quicksort should switch -// to heapsort. It returns 2*ceil(lg(n+1)). -func maxDepth(n int) int { - var depth int - for i := n; i > 0; i >>= 1 { - depth++ - } - return depth * 2 -} - -// medianOfThree moves the median of the three values data[m0], data[m1], data[m2] into data[m1]. -func medianOfThree(data []literalNode, m1, m0, m2 int) { - // sort 3 elements - if data[m1].literal < data[m0].literal { - data[m1], data[m0] = data[m0], data[m1] - } - // data[m0] <= data[m1] - if data[m2].literal < data[m1].literal { - data[m2], data[m1] = data[m1], data[m2] - // data[m0] <= data[m2] && data[m1] < data[m2] - if data[m1].literal < data[m0].literal { - data[m1], data[m0] = data[m0], data[m1] - } - } - // now data[m0] <= data[m1] <= data[m2] -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/inflate.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/inflate.go deleted file mode 100644 index 7f175a4ec26..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/inflate.go +++ /dev/null @@ -1,1000 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package flate implements the DEFLATE compressed data format, described in -// RFC 1951. The gzip and zlib packages implement access to DEFLATE-based file -// formats. -package flate - -import ( - "bufio" - "fmt" - "io" - "math/bits" - "strconv" - "sync" -) - -const ( - maxCodeLen = 16 // max length of Huffman code - maxCodeLenMask = 15 // mask for max length of Huffman code - // The next three numbers come from the RFC section 3.2.7, with the - // additional proviso in section 3.2.5 which implies that distance codes - // 30 and 31 should never occur in compressed data. - maxNumLit = 286 - maxNumDist = 30 - numCodes = 19 // number of codes in Huffman meta-code - - debugDecode = false -) - -// Initialize the fixedHuffmanDecoder only once upon first use. -var fixedOnce sync.Once -var fixedHuffmanDecoder huffmanDecoder - -// A CorruptInputError reports the presence of corrupt input at a given offset. -type CorruptInputError int64 - -func (e CorruptInputError) Error() string { - return "flate: corrupt input before offset " + strconv.FormatInt(int64(e), 10) -} - -// An InternalError reports an error in the flate code itself. -type InternalError string - -func (e InternalError) Error() string { return "flate: internal error: " + string(e) } - -// A ReadError reports an error encountered while reading input. -// -// Deprecated: No longer returned. -type ReadError struct { - Offset int64 // byte offset where error occurred - Err error // error returned by underlying Read -} - -func (e *ReadError) Error() string { - return "flate: read error at offset " + strconv.FormatInt(e.Offset, 10) + ": " + e.Err.Error() -} - -// A WriteError reports an error encountered while writing output. -// -// Deprecated: No longer returned. -type WriteError struct { - Offset int64 // byte offset where error occurred - Err error // error returned by underlying Write -} - -func (e *WriteError) Error() string { - return "flate: write error at offset " + strconv.FormatInt(e.Offset, 10) + ": " + e.Err.Error() -} - -// Resetter resets a ReadCloser returned by NewReader or NewReaderDict to -// to switch to a new underlying Reader. This permits reusing a ReadCloser -// instead of allocating a new one. -type Resetter interface { - // Reset discards any buffered data and resets the Resetter as if it was - // newly initialized with the given reader. - Reset(r io.Reader, dict []byte) error -} - -// The data structure for decoding Huffman tables is based on that of -// zlib. There is a lookup table of a fixed bit width (huffmanChunkBits), -// For codes smaller than the table width, there are multiple entries -// (each combination of trailing bits has the same value). For codes -// larger than the table width, the table contains a link to an overflow -// table. The width of each entry in the link table is the maximum code -// size minus the chunk width. -// -// Note that you can do a lookup in the table even without all bits -// filled. Since the extra bits are zero, and the DEFLATE Huffman codes -// have the property that shorter codes come before longer ones, the -// bit length estimate in the result is a lower bound on the actual -// number of bits. -// -// See the following: -// http://www.gzip.org/algorithm.txt - -// chunk & 15 is number of bits -// chunk >> 4 is value, including table link - -const ( - huffmanChunkBits = 9 - huffmanNumChunks = 1 << huffmanChunkBits - huffmanCountMask = 15 - huffmanValueShift = 4 -) - -type huffmanDecoder struct { - maxRead int // the maximum number of bits we can read and not overread - chunks *[huffmanNumChunks]uint16 // chunks as described above - links [][]uint16 // overflow links - linkMask uint32 // mask the width of the link table -} - -// Initialize Huffman decoding tables from array of code lengths. -// Following this function, h is guaranteed to be initialized into a complete -// tree (i.e., neither over-subscribed nor under-subscribed). The exception is a -// degenerate case where the tree has only a single symbol with length 1. Empty -// trees are permitted. -func (h *huffmanDecoder) init(lengths []int) bool { - // Sanity enables additional runtime tests during Huffman - // table construction. It's intended to be used during - // development to supplement the currently ad-hoc unit tests. - const sanity = false - - if h.chunks == nil { - h.chunks = &[huffmanNumChunks]uint16{} - } - if h.maxRead != 0 { - *h = huffmanDecoder{chunks: h.chunks, links: h.links} - } - - // Count number of codes of each length, - // compute maxRead and max length. - var count [maxCodeLen]int - var min, max int - for _, n := range lengths { - if n == 0 { - continue - } - if min == 0 || n < min { - min = n - } - if n > max { - max = n - } - count[n&maxCodeLenMask]++ - } - - // Empty tree. The decompressor.huffSym function will fail later if the tree - // is used. Technically, an empty tree is only valid for the HDIST tree and - // not the HCLEN and HLIT tree. However, a stream with an empty HCLEN tree - // is guaranteed to fail since it will attempt to use the tree to decode the - // codes for the HLIT and HDIST trees. Similarly, an empty HLIT tree is - // guaranteed to fail later since the compressed data section must be - // composed of at least one symbol (the end-of-block marker). - if max == 0 { - return true - } - - code := 0 - var nextcode [maxCodeLen]int - for i := min; i <= max; i++ { - code <<= 1 - nextcode[i&maxCodeLenMask] = code - code += count[i&maxCodeLenMask] - } - - // Check that the coding is complete (i.e., that we've - // assigned all 2-to-the-max possible bit sequences). - // Exception: To be compatible with zlib, we also need to - // accept degenerate single-code codings. See also - // TestDegenerateHuffmanCoding. - if code != 1< huffmanChunkBits { - numLinks := 1 << (uint(max) - huffmanChunkBits) - h.linkMask = uint32(numLinks - 1) - - // create link tables - link := nextcode[huffmanChunkBits+1] >> 1 - if cap(h.links) < huffmanNumChunks-link { - h.links = make([][]uint16, huffmanNumChunks-link) - } else { - h.links = h.links[:huffmanNumChunks-link] - } - for j := uint(link); j < huffmanNumChunks; j++ { - reverse := int(bits.Reverse16(uint16(j))) - reverse >>= uint(16 - huffmanChunkBits) - off := j - uint(link) - if sanity && h.chunks[reverse] != 0 { - panic("impossible: overwriting existing chunk") - } - h.chunks[reverse] = uint16(off<>= uint(16 - n) - if n <= huffmanChunkBits { - for off := reverse; off < len(h.chunks); off += 1 << uint(n) { - // We should never need to overwrite - // an existing chunk. Also, 0 is - // never a valid chunk, because the - // lower 4 "count" bits should be - // between 1 and 15. - if sanity && h.chunks[off] != 0 { - panic("impossible: overwriting existing chunk") - } - h.chunks[off] = chunk - } - } else { - j := reverse & (huffmanNumChunks - 1) - if sanity && h.chunks[j]&huffmanCountMask != huffmanChunkBits+1 { - // Longer codes should have been - // associated with a link table above. - panic("impossible: not an indirect chunk") - } - value := h.chunks[j] >> huffmanValueShift - linktab := h.links[value] - reverse >>= huffmanChunkBits - for off := reverse; off < len(linktab); off += 1 << uint(n-huffmanChunkBits) { - if sanity && linktab[off] != 0 { - panic("impossible: overwriting existing chunk") - } - linktab[off] = chunk - } - } - } - - if sanity { - // Above we've sanity checked that we never overwrote - // an existing entry. Here we additionally check that - // we filled the tables completely. - for i, chunk := range h.chunks { - if chunk == 0 { - // As an exception, in the degenerate - // single-code case, we allow odd - // chunks to be missing. - if code == 1 && i%2 == 1 { - continue - } - panic("impossible: missing chunk") - } - } - for _, linktab := range h.links { - for _, chunk := range linktab { - if chunk == 0 { - panic("impossible: missing chunk") - } - } - } - } - - return true -} - -// The actual read interface needed by NewReader. -// If the passed in io.Reader does not also have ReadByte, -// the NewReader will introduce its own buffering. -type Reader interface { - io.Reader - io.ByteReader -} - -// Decompress state. -type decompressor struct { - // Input source. - r Reader - roffset int64 - - // Input bits, in top of b. - b uint32 - nb uint - - // Huffman decoders for literal/length, distance. - h1, h2 huffmanDecoder - - // Length arrays used to define Huffman codes. - bits *[maxNumLit + maxNumDist]int - codebits *[numCodes]int - - // Output history, buffer. - dict dictDecoder - - // Temporary buffer (avoids repeated allocation). - buf [4]byte - - // Next step in the decompression, - // and decompression state. - step func(*decompressor) - stepState int - final bool - err error - toRead []byte - hl, hd *huffmanDecoder - copyLen int - copyDist int -} - -func (f *decompressor) nextBlock() { - for f.nb < 1+2 { - if f.err = f.moreBits(); f.err != nil { - return - } - } - f.final = f.b&1 == 1 - f.b >>= 1 - typ := f.b & 3 - f.b >>= 2 - f.nb -= 1 + 2 - switch typ { - case 0: - f.dataBlock() - case 1: - // compressed, fixed Huffman tables - f.hl = &fixedHuffmanDecoder - f.hd = nil - f.huffmanBlockDecoder()() - case 2: - // compressed, dynamic Huffman tables - if f.err = f.readHuffman(); f.err != nil { - break - } - f.hl = &f.h1 - f.hd = &f.h2 - f.huffmanBlockDecoder()() - default: - // 3 is reserved. - if debugDecode { - fmt.Println("reserved data block encountered") - } - f.err = CorruptInputError(f.roffset) - } -} - -func (f *decompressor) Read(b []byte) (int, error) { - for { - if len(f.toRead) > 0 { - n := copy(b, f.toRead) - f.toRead = f.toRead[n:] - if len(f.toRead) == 0 { - return n, f.err - } - return n, nil - } - if f.err != nil { - return 0, f.err - } - f.step(f) - if f.err != nil && len(f.toRead) == 0 { - f.toRead = f.dict.readFlush() // Flush what's left in case of error - } - } -} - -// Support the io.WriteTo interface for io.Copy and friends. -func (f *decompressor) WriteTo(w io.Writer) (int64, error) { - total := int64(0) - flushed := false - for { - if len(f.toRead) > 0 { - n, err := w.Write(f.toRead) - total += int64(n) - if err != nil { - f.err = err - return total, err - } - if n != len(f.toRead) { - return total, io.ErrShortWrite - } - f.toRead = f.toRead[:0] - } - if f.err != nil && flushed { - if f.err == io.EOF { - return total, nil - } - return total, f.err - } - if f.err == nil { - f.step(f) - } - if len(f.toRead) == 0 && f.err != nil && !flushed { - f.toRead = f.dict.readFlush() // Flush what's left in case of error - flushed = true - } - } -} - -func (f *decompressor) Close() error { - if f.err == io.EOF { - return nil - } - return f.err -} - -// RFC 1951 section 3.2.7. -// Compression with dynamic Huffman codes - -var codeOrder = [...]int{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15} - -func (f *decompressor) readHuffman() error { - // HLIT[5], HDIST[5], HCLEN[4]. - for f.nb < 5+5+4 { - if err := f.moreBits(); err != nil { - return err - } - } - nlit := int(f.b&0x1F) + 257 - if nlit > maxNumLit { - if debugDecode { - fmt.Println("nlit > maxNumLit", nlit) - } - return CorruptInputError(f.roffset) - } - f.b >>= 5 - ndist := int(f.b&0x1F) + 1 - if ndist > maxNumDist { - if debugDecode { - fmt.Println("ndist > maxNumDist", ndist) - } - return CorruptInputError(f.roffset) - } - f.b >>= 5 - nclen := int(f.b&0xF) + 4 - // numCodes is 19, so nclen is always valid. - f.b >>= 4 - f.nb -= 5 + 5 + 4 - - // (HCLEN+4)*3 bits: code lengths in the magic codeOrder order. - for i := 0; i < nclen; i++ { - for f.nb < 3 { - if err := f.moreBits(); err != nil { - return err - } - } - f.codebits[codeOrder[i]] = int(f.b & 0x7) - f.b >>= 3 - f.nb -= 3 - } - for i := nclen; i < len(codeOrder); i++ { - f.codebits[codeOrder[i]] = 0 - } - if !f.h1.init(f.codebits[0:]) { - if debugDecode { - fmt.Println("init codebits failed") - } - return CorruptInputError(f.roffset) - } - - // HLIT + 257 code lengths, HDIST + 1 code lengths, - // using the code length Huffman code. - for i, n := 0, nlit+ndist; i < n; { - x, err := f.huffSym(&f.h1) - if err != nil { - return err - } - if x < 16 { - // Actual length. - f.bits[i] = x - i++ - continue - } - // Repeat previous length or zero. - var rep int - var nb uint - var b int - switch x { - default: - return InternalError("unexpected length code") - case 16: - rep = 3 - nb = 2 - if i == 0 { - if debugDecode { - fmt.Println("i==0") - } - return CorruptInputError(f.roffset) - } - b = f.bits[i-1] - case 17: - rep = 3 - nb = 3 - b = 0 - case 18: - rep = 11 - nb = 7 - b = 0 - } - for f.nb < nb { - if err := f.moreBits(); err != nil { - if debugDecode { - fmt.Println("morebits:", err) - } - return err - } - } - rep += int(f.b & uint32(1<>= nb - f.nb -= nb - if i+rep > n { - if debugDecode { - fmt.Println("i+rep > n", i, rep, n) - } - return CorruptInputError(f.roffset) - } - for j := 0; j < rep; j++ { - f.bits[i] = b - i++ - } - } - - if !f.h1.init(f.bits[0:nlit]) || !f.h2.init(f.bits[nlit:nlit+ndist]) { - if debugDecode { - fmt.Println("init2 failed") - } - return CorruptInputError(f.roffset) - } - - // As an optimization, we can initialize the maxRead bits to read at a time - // for the HLIT tree to the length of the EOB marker since we know that - // every block must terminate with one. This preserves the property that - // we never read any extra bytes after the end of the DEFLATE stream. - if f.h1.maxRead < f.bits[endBlockMarker] { - f.h1.maxRead = f.bits[endBlockMarker] - } - if !f.final { - // If not the final block, the smallest block possible is - // a predefined table, BTYPE=01, with a single EOB marker. - // This will take up 3 + 7 bits. - f.h1.maxRead += 10 - } - - return nil -} - -// Decode a single Huffman block from f. -// hl and hd are the Huffman states for the lit/length values -// and the distance values, respectively. If hd == nil, using the -// fixed distance encoding associated with fixed Huffman blocks. -func (f *decompressor) huffmanBlockGeneric() { - const ( - stateInit = iota // Zero value must be stateInit - stateDict - ) - - switch f.stepState { - case stateInit: - goto readLiteral - case stateDict: - goto copyHistory - } - -readLiteral: - // Read literal and/or (length, distance) according to RFC section 3.2.3. - { - var v int - { - // Inlined v, err := f.huffSym(f.hl) - // Since a huffmanDecoder can be empty or be composed of a degenerate tree - // with single element, huffSym must error on these two edge cases. In both - // cases, the chunks slice will be 0 for the invalid sequence, leading it - // satisfy the n == 0 check below. - n := uint(f.hl.maxRead) - // Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers, - // but is smart enough to keep local variables in registers, so use nb and b, - // inline call to moreBits and reassign b,nb back to f on return. - nb, b := f.nb, f.b - for { - for nb < n { - c, err := f.r.ReadByte() - if err != nil { - f.b = b - f.nb = nb - f.err = noEOF(err) - return - } - f.roffset++ - b |= uint32(c) << (nb & 31) - nb += 8 - } - chunk := f.hl.chunks[b&(huffmanNumChunks-1)] - n = uint(chunk & huffmanCountMask) - if n > huffmanChunkBits { - chunk = f.hl.links[chunk>>huffmanValueShift][(b>>huffmanChunkBits)&f.hl.linkMask] - n = uint(chunk & huffmanCountMask) - } - if n <= nb { - if n == 0 { - f.b = b - f.nb = nb - if debugDecode { - fmt.Println("huffsym: n==0") - } - f.err = CorruptInputError(f.roffset) - return - } - f.b = b >> (n & 31) - f.nb = nb - n - v = int(chunk >> huffmanValueShift) - break - } - } - } - - var n uint // number of bits extra - var length int - var err error - switch { - case v < 256: - f.dict.writeByte(byte(v)) - if f.dict.availWrite() == 0 { - f.toRead = f.dict.readFlush() - f.step = (*decompressor).huffmanBlockGeneric - f.stepState = stateInit - return - } - goto readLiteral - case v == 256: - f.finishBlock() - return - // otherwise, reference to older data - case v < 265: - length = v - (257 - 3) - n = 0 - case v < 269: - length = v*2 - (265*2 - 11) - n = 1 - case v < 273: - length = v*4 - (269*4 - 19) - n = 2 - case v < 277: - length = v*8 - (273*8 - 35) - n = 3 - case v < 281: - length = v*16 - (277*16 - 67) - n = 4 - case v < 285: - length = v*32 - (281*32 - 131) - n = 5 - case v < maxNumLit: - length = 258 - n = 0 - default: - if debugDecode { - fmt.Println(v, ">= maxNumLit") - } - f.err = CorruptInputError(f.roffset) - return - } - if n > 0 { - for f.nb < n { - if err = f.moreBits(); err != nil { - if debugDecode { - fmt.Println("morebits n>0:", err) - } - f.err = err - return - } - } - length += int(f.b & uint32(1<>= n - f.nb -= n - } - - var dist int - if f.hd == nil { - for f.nb < 5 { - if err = f.moreBits(); err != nil { - if debugDecode { - fmt.Println("morebits f.nb<5:", err) - } - f.err = err - return - } - } - dist = int(bits.Reverse8(uint8(f.b & 0x1F << 3))) - f.b >>= 5 - f.nb -= 5 - } else { - if dist, err = f.huffSym(f.hd); err != nil { - if debugDecode { - fmt.Println("huffsym:", err) - } - f.err = err - return - } - } - - switch { - case dist < 4: - dist++ - case dist < maxNumDist: - nb := uint(dist-2) >> 1 - // have 1 bit in bottom of dist, need nb more. - extra := (dist & 1) << nb - for f.nb < nb { - if err = f.moreBits(); err != nil { - if debugDecode { - fmt.Println("morebits f.nb>= nb - f.nb -= nb - dist = 1<<(nb+1) + 1 + extra - default: - if debugDecode { - fmt.Println("dist too big:", dist, maxNumDist) - } - f.err = CorruptInputError(f.roffset) - return - } - - // No check on length; encoding can be prescient. - if dist > f.dict.histSize() { - if debugDecode { - fmt.Println("dist > f.dict.histSize():", dist, f.dict.histSize()) - } - f.err = CorruptInputError(f.roffset) - return - } - - f.copyLen, f.copyDist = length, dist - goto copyHistory - } - -copyHistory: - // Perform a backwards copy according to RFC section 3.2.3. - { - cnt := f.dict.tryWriteCopy(f.copyDist, f.copyLen) - if cnt == 0 { - cnt = f.dict.writeCopy(f.copyDist, f.copyLen) - } - f.copyLen -= cnt - - if f.dict.availWrite() == 0 || f.copyLen > 0 { - f.toRead = f.dict.readFlush() - f.step = (*decompressor).huffmanBlockGeneric // We need to continue this work - f.stepState = stateDict - return - } - goto readLiteral - } -} - -// Copy a single uncompressed data block from input to output. -func (f *decompressor) dataBlock() { - // Uncompressed. - // Discard current half-byte. - left := (f.nb) & 7 - f.nb -= left - f.b >>= left - - offBytes := f.nb >> 3 - // Unfilled values will be overwritten. - f.buf[0] = uint8(f.b) - f.buf[1] = uint8(f.b >> 8) - f.buf[2] = uint8(f.b >> 16) - f.buf[3] = uint8(f.b >> 24) - - f.roffset += int64(offBytes) - f.nb, f.b = 0, 0 - - // Length then ones-complement of length. - nr, err := io.ReadFull(f.r, f.buf[offBytes:4]) - f.roffset += int64(nr) - if err != nil { - f.err = noEOF(err) - return - } - n := uint16(f.buf[0]) | uint16(f.buf[1])<<8 - nn := uint16(f.buf[2]) | uint16(f.buf[3])<<8 - if nn != ^n { - if debugDecode { - ncomp := ^n - fmt.Println("uint16(nn) != uint16(^n)", nn, ncomp) - } - f.err = CorruptInputError(f.roffset) - return - } - - if n == 0 { - f.toRead = f.dict.readFlush() - f.finishBlock() - return - } - - f.copyLen = int(n) - f.copyData() -} - -// copyData copies f.copyLen bytes from the underlying reader into f.hist. -// It pauses for reads when f.hist is full. -func (f *decompressor) copyData() { - buf := f.dict.writeSlice() - if len(buf) > f.copyLen { - buf = buf[:f.copyLen] - } - - cnt, err := io.ReadFull(f.r, buf) - f.roffset += int64(cnt) - f.copyLen -= cnt - f.dict.writeMark(cnt) - if err != nil { - f.err = noEOF(err) - return - } - - if f.dict.availWrite() == 0 || f.copyLen > 0 { - f.toRead = f.dict.readFlush() - f.step = (*decompressor).copyData - return - } - f.finishBlock() -} - -func (f *decompressor) finishBlock() { - if f.final { - if f.dict.availRead() > 0 { - f.toRead = f.dict.readFlush() - } - f.err = io.EOF - } - f.step = (*decompressor).nextBlock -} - -// noEOF returns err, unless err == io.EOF, in which case it returns io.ErrUnexpectedEOF. -func noEOF(e error) error { - if e == io.EOF { - return io.ErrUnexpectedEOF - } - return e -} - -func (f *decompressor) moreBits() error { - c, err := f.r.ReadByte() - if err != nil { - return noEOF(err) - } - f.roffset++ - f.b |= uint32(c) << f.nb - f.nb += 8 - return nil -} - -// Read the next Huffman-encoded symbol from f according to h. -func (f *decompressor) huffSym(h *huffmanDecoder) (int, error) { - // Since a huffmanDecoder can be empty or be composed of a degenerate tree - // with single element, huffSym must error on these two edge cases. In both - // cases, the chunks slice will be 0 for the invalid sequence, leading it - // satisfy the n == 0 check below. - n := uint(h.maxRead) - // Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers, - // but is smart enough to keep local variables in registers, so use nb and b, - // inline call to moreBits and reassign b,nb back to f on return. - nb, b := f.nb, f.b - for { - for nb < n { - c, err := f.r.ReadByte() - if err != nil { - f.b = b - f.nb = nb - return 0, noEOF(err) - } - f.roffset++ - b |= uint32(c) << (nb & 31) - nb += 8 - } - chunk := h.chunks[b&(huffmanNumChunks-1)] - n = uint(chunk & huffmanCountMask) - if n > huffmanChunkBits { - chunk = h.links[chunk>>huffmanValueShift][(b>>huffmanChunkBits)&h.linkMask] - n = uint(chunk & huffmanCountMask) - } - if n <= nb { - if n == 0 { - f.b = b - f.nb = nb - if debugDecode { - fmt.Println("huffsym: n==0") - } - f.err = CorruptInputError(f.roffset) - return 0, f.err - } - f.b = b >> (n & 31) - f.nb = nb - n - return int(chunk >> huffmanValueShift), nil - } - } -} - -func makeReader(r io.Reader) Reader { - if rr, ok := r.(Reader); ok { - return rr - } - return bufio.NewReader(r) -} - -func fixedHuffmanDecoderInit() { - fixedOnce.Do(func() { - // These come from the RFC section 3.2.6. - var bits [288]int - for i := 0; i < 144; i++ { - bits[i] = 8 - } - for i := 144; i < 256; i++ { - bits[i] = 9 - } - for i := 256; i < 280; i++ { - bits[i] = 7 - } - for i := 280; i < 288; i++ { - bits[i] = 8 - } - fixedHuffmanDecoder.init(bits[:]) - }) -} - -func (f *decompressor) Reset(r io.Reader, dict []byte) error { - *f = decompressor{ - r: makeReader(r), - bits: f.bits, - codebits: f.codebits, - h1: f.h1, - h2: f.h2, - dict: f.dict, - step: (*decompressor).nextBlock, - } - f.dict.init(maxMatchOffset, dict) - return nil -} - -// NewReader returns a new ReadCloser that can be used -// to read the uncompressed version of r. -// If r does not also implement io.ByteReader, -// the decompressor may read more data than necessary from r. -// It is the caller's responsibility to call Close on the ReadCloser -// when finished reading. -// -// The ReadCloser returned by NewReader also implements Resetter. -func NewReader(r io.Reader) io.ReadCloser { - fixedHuffmanDecoderInit() - - var f decompressor - f.r = makeReader(r) - f.bits = new([maxNumLit + maxNumDist]int) - f.codebits = new([numCodes]int) - f.step = (*decompressor).nextBlock - f.dict.init(maxMatchOffset, nil) - return &f -} - -// NewReaderDict is like NewReader but initializes the reader -// with a preset dictionary. The returned Reader behaves as if -// the uncompressed data stream started with the given dictionary, -// which has already been read. NewReaderDict is typically used -// to read data compressed by NewWriterDict. -// -// The ReadCloser returned by NewReader also implements Resetter. -func NewReaderDict(r io.Reader, dict []byte) io.ReadCloser { - fixedHuffmanDecoderInit() - - var f decompressor - f.r = makeReader(r) - f.bits = new([maxNumLit + maxNumDist]int) - f.codebits = new([numCodes]int) - f.step = (*decompressor).nextBlock - f.dict.init(maxMatchOffset, dict) - return &f -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/inflate_gen.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/inflate_gen.go deleted file mode 100644 index 397dc1b1a13..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/inflate_gen.go +++ /dev/null @@ -1,922 +0,0 @@ -// Code generated by go generate gen_inflate.go. DO NOT EDIT. - -package flate - -import ( - "bufio" - "bytes" - "fmt" - "math/bits" - "strings" -) - -// Decode a single Huffman block from f. -// hl and hd are the Huffman states for the lit/length values -// and the distance values, respectively. If hd == nil, using the -// fixed distance encoding associated with fixed Huffman blocks. -func (f *decompressor) huffmanBytesBuffer() { - const ( - stateInit = iota // Zero value must be stateInit - stateDict - ) - fr := f.r.(*bytes.Buffer) - moreBits := func() error { - c, err := fr.ReadByte() - if err != nil { - return noEOF(err) - } - f.roffset++ - f.b |= uint32(c) << f.nb - f.nb += 8 - return nil - } - - switch f.stepState { - case stateInit: - goto readLiteral - case stateDict: - goto copyHistory - } - -readLiteral: - // Read literal and/or (length, distance) according to RFC section 3.2.3. - { - var v int - { - // Inlined v, err := f.huffSym(f.hl) - // Since a huffmanDecoder can be empty or be composed of a degenerate tree - // with single element, huffSym must error on these two edge cases. In both - // cases, the chunks slice will be 0 for the invalid sequence, leading it - // satisfy the n == 0 check below. - n := uint(f.hl.maxRead) - // Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers, - // but is smart enough to keep local variables in registers, so use nb and b, - // inline call to moreBits and reassign b,nb back to f on return. - nb, b := f.nb, f.b - for { - for nb < n { - c, err := fr.ReadByte() - if err != nil { - f.b = b - f.nb = nb - f.err = noEOF(err) - return - } - f.roffset++ - b |= uint32(c) << (nb & 31) - nb += 8 - } - chunk := f.hl.chunks[b&(huffmanNumChunks-1)] - n = uint(chunk & huffmanCountMask) - if n > huffmanChunkBits { - chunk = f.hl.links[chunk>>huffmanValueShift][(b>>huffmanChunkBits)&f.hl.linkMask] - n = uint(chunk & huffmanCountMask) - } - if n <= nb { - if n == 0 { - f.b = b - f.nb = nb - if debugDecode { - fmt.Println("huffsym: n==0") - } - f.err = CorruptInputError(f.roffset) - return - } - f.b = b >> (n & 31) - f.nb = nb - n - v = int(chunk >> huffmanValueShift) - break - } - } - } - - var n uint // number of bits extra - var length int - var err error - switch { - case v < 256: - f.dict.writeByte(byte(v)) - if f.dict.availWrite() == 0 { - f.toRead = f.dict.readFlush() - f.step = (*decompressor).huffmanBytesBuffer - f.stepState = stateInit - return - } - goto readLiteral - case v == 256: - f.finishBlock() - return - // otherwise, reference to older data - case v < 265: - length = v - (257 - 3) - n = 0 - case v < 269: - length = v*2 - (265*2 - 11) - n = 1 - case v < 273: - length = v*4 - (269*4 - 19) - n = 2 - case v < 277: - length = v*8 - (273*8 - 35) - n = 3 - case v < 281: - length = v*16 - (277*16 - 67) - n = 4 - case v < 285: - length = v*32 - (281*32 - 131) - n = 5 - case v < maxNumLit: - length = 258 - n = 0 - default: - if debugDecode { - fmt.Println(v, ">= maxNumLit") - } - f.err = CorruptInputError(f.roffset) - return - } - if n > 0 { - for f.nb < n { - if err = moreBits(); err != nil { - if debugDecode { - fmt.Println("morebits n>0:", err) - } - f.err = err - return - } - } - length += int(f.b & uint32(1<>= n - f.nb -= n - } - - var dist int - if f.hd == nil { - for f.nb < 5 { - if err = moreBits(); err != nil { - if debugDecode { - fmt.Println("morebits f.nb<5:", err) - } - f.err = err - return - } - } - dist = int(bits.Reverse8(uint8(f.b & 0x1F << 3))) - f.b >>= 5 - f.nb -= 5 - } else { - if dist, err = f.huffSym(f.hd); err != nil { - if debugDecode { - fmt.Println("huffsym:", err) - } - f.err = err - return - } - } - - switch { - case dist < 4: - dist++ - case dist < maxNumDist: - nb := uint(dist-2) >> 1 - // have 1 bit in bottom of dist, need nb more. - extra := (dist & 1) << nb - for f.nb < nb { - if err = moreBits(); err != nil { - if debugDecode { - fmt.Println("morebits f.nb>= nb - f.nb -= nb - dist = 1<<(nb+1) + 1 + extra - default: - if debugDecode { - fmt.Println("dist too big:", dist, maxNumDist) - } - f.err = CorruptInputError(f.roffset) - return - } - - // No check on length; encoding can be prescient. - if dist > f.dict.histSize() { - if debugDecode { - fmt.Println("dist > f.dict.histSize():", dist, f.dict.histSize()) - } - f.err = CorruptInputError(f.roffset) - return - } - - f.copyLen, f.copyDist = length, dist - goto copyHistory - } - -copyHistory: - // Perform a backwards copy according to RFC section 3.2.3. - { - cnt := f.dict.tryWriteCopy(f.copyDist, f.copyLen) - if cnt == 0 { - cnt = f.dict.writeCopy(f.copyDist, f.copyLen) - } - f.copyLen -= cnt - - if f.dict.availWrite() == 0 || f.copyLen > 0 { - f.toRead = f.dict.readFlush() - f.step = (*decompressor).huffmanBytesBuffer // We need to continue this work - f.stepState = stateDict - return - } - goto readLiteral - } -} - -// Decode a single Huffman block from f. -// hl and hd are the Huffman states for the lit/length values -// and the distance values, respectively. If hd == nil, using the -// fixed distance encoding associated with fixed Huffman blocks. -func (f *decompressor) huffmanBytesReader() { - const ( - stateInit = iota // Zero value must be stateInit - stateDict - ) - fr := f.r.(*bytes.Reader) - moreBits := func() error { - c, err := fr.ReadByte() - if err != nil { - return noEOF(err) - } - f.roffset++ - f.b |= uint32(c) << f.nb - f.nb += 8 - return nil - } - - switch f.stepState { - case stateInit: - goto readLiteral - case stateDict: - goto copyHistory - } - -readLiteral: - // Read literal and/or (length, distance) according to RFC section 3.2.3. - { - var v int - { - // Inlined v, err := f.huffSym(f.hl) - // Since a huffmanDecoder can be empty or be composed of a degenerate tree - // with single element, huffSym must error on these two edge cases. In both - // cases, the chunks slice will be 0 for the invalid sequence, leading it - // satisfy the n == 0 check below. - n := uint(f.hl.maxRead) - // Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers, - // but is smart enough to keep local variables in registers, so use nb and b, - // inline call to moreBits and reassign b,nb back to f on return. - nb, b := f.nb, f.b - for { - for nb < n { - c, err := fr.ReadByte() - if err != nil { - f.b = b - f.nb = nb - f.err = noEOF(err) - return - } - f.roffset++ - b |= uint32(c) << (nb & 31) - nb += 8 - } - chunk := f.hl.chunks[b&(huffmanNumChunks-1)] - n = uint(chunk & huffmanCountMask) - if n > huffmanChunkBits { - chunk = f.hl.links[chunk>>huffmanValueShift][(b>>huffmanChunkBits)&f.hl.linkMask] - n = uint(chunk & huffmanCountMask) - } - if n <= nb { - if n == 0 { - f.b = b - f.nb = nb - if debugDecode { - fmt.Println("huffsym: n==0") - } - f.err = CorruptInputError(f.roffset) - return - } - f.b = b >> (n & 31) - f.nb = nb - n - v = int(chunk >> huffmanValueShift) - break - } - } - } - - var n uint // number of bits extra - var length int - var err error - switch { - case v < 256: - f.dict.writeByte(byte(v)) - if f.dict.availWrite() == 0 { - f.toRead = f.dict.readFlush() - f.step = (*decompressor).huffmanBytesReader - f.stepState = stateInit - return - } - goto readLiteral - case v == 256: - f.finishBlock() - return - // otherwise, reference to older data - case v < 265: - length = v - (257 - 3) - n = 0 - case v < 269: - length = v*2 - (265*2 - 11) - n = 1 - case v < 273: - length = v*4 - (269*4 - 19) - n = 2 - case v < 277: - length = v*8 - (273*8 - 35) - n = 3 - case v < 281: - length = v*16 - (277*16 - 67) - n = 4 - case v < 285: - length = v*32 - (281*32 - 131) - n = 5 - case v < maxNumLit: - length = 258 - n = 0 - default: - if debugDecode { - fmt.Println(v, ">= maxNumLit") - } - f.err = CorruptInputError(f.roffset) - return - } - if n > 0 { - for f.nb < n { - if err = moreBits(); err != nil { - if debugDecode { - fmt.Println("morebits n>0:", err) - } - f.err = err - return - } - } - length += int(f.b & uint32(1<>= n - f.nb -= n - } - - var dist int - if f.hd == nil { - for f.nb < 5 { - if err = moreBits(); err != nil { - if debugDecode { - fmt.Println("morebits f.nb<5:", err) - } - f.err = err - return - } - } - dist = int(bits.Reverse8(uint8(f.b & 0x1F << 3))) - f.b >>= 5 - f.nb -= 5 - } else { - if dist, err = f.huffSym(f.hd); err != nil { - if debugDecode { - fmt.Println("huffsym:", err) - } - f.err = err - return - } - } - - switch { - case dist < 4: - dist++ - case dist < maxNumDist: - nb := uint(dist-2) >> 1 - // have 1 bit in bottom of dist, need nb more. - extra := (dist & 1) << nb - for f.nb < nb { - if err = moreBits(); err != nil { - if debugDecode { - fmt.Println("morebits f.nb>= nb - f.nb -= nb - dist = 1<<(nb+1) + 1 + extra - default: - if debugDecode { - fmt.Println("dist too big:", dist, maxNumDist) - } - f.err = CorruptInputError(f.roffset) - return - } - - // No check on length; encoding can be prescient. - if dist > f.dict.histSize() { - if debugDecode { - fmt.Println("dist > f.dict.histSize():", dist, f.dict.histSize()) - } - f.err = CorruptInputError(f.roffset) - return - } - - f.copyLen, f.copyDist = length, dist - goto copyHistory - } - -copyHistory: - // Perform a backwards copy according to RFC section 3.2.3. - { - cnt := f.dict.tryWriteCopy(f.copyDist, f.copyLen) - if cnt == 0 { - cnt = f.dict.writeCopy(f.copyDist, f.copyLen) - } - f.copyLen -= cnt - - if f.dict.availWrite() == 0 || f.copyLen > 0 { - f.toRead = f.dict.readFlush() - f.step = (*decompressor).huffmanBytesReader // We need to continue this work - f.stepState = stateDict - return - } - goto readLiteral - } -} - -// Decode a single Huffman block from f. -// hl and hd are the Huffman states for the lit/length values -// and the distance values, respectively. If hd == nil, using the -// fixed distance encoding associated with fixed Huffman blocks. -func (f *decompressor) huffmanBufioReader() { - const ( - stateInit = iota // Zero value must be stateInit - stateDict - ) - fr := f.r.(*bufio.Reader) - moreBits := func() error { - c, err := fr.ReadByte() - if err != nil { - return noEOF(err) - } - f.roffset++ - f.b |= uint32(c) << f.nb - f.nb += 8 - return nil - } - - switch f.stepState { - case stateInit: - goto readLiteral - case stateDict: - goto copyHistory - } - -readLiteral: - // Read literal and/or (length, distance) according to RFC section 3.2.3. - { - var v int - { - // Inlined v, err := f.huffSym(f.hl) - // Since a huffmanDecoder can be empty or be composed of a degenerate tree - // with single element, huffSym must error on these two edge cases. In both - // cases, the chunks slice will be 0 for the invalid sequence, leading it - // satisfy the n == 0 check below. - n := uint(f.hl.maxRead) - // Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers, - // but is smart enough to keep local variables in registers, so use nb and b, - // inline call to moreBits and reassign b,nb back to f on return. - nb, b := f.nb, f.b - for { - for nb < n { - c, err := fr.ReadByte() - if err != nil { - f.b = b - f.nb = nb - f.err = noEOF(err) - return - } - f.roffset++ - b |= uint32(c) << (nb & 31) - nb += 8 - } - chunk := f.hl.chunks[b&(huffmanNumChunks-1)] - n = uint(chunk & huffmanCountMask) - if n > huffmanChunkBits { - chunk = f.hl.links[chunk>>huffmanValueShift][(b>>huffmanChunkBits)&f.hl.linkMask] - n = uint(chunk & huffmanCountMask) - } - if n <= nb { - if n == 0 { - f.b = b - f.nb = nb - if debugDecode { - fmt.Println("huffsym: n==0") - } - f.err = CorruptInputError(f.roffset) - return - } - f.b = b >> (n & 31) - f.nb = nb - n - v = int(chunk >> huffmanValueShift) - break - } - } - } - - var n uint // number of bits extra - var length int - var err error - switch { - case v < 256: - f.dict.writeByte(byte(v)) - if f.dict.availWrite() == 0 { - f.toRead = f.dict.readFlush() - f.step = (*decompressor).huffmanBufioReader - f.stepState = stateInit - return - } - goto readLiteral - case v == 256: - f.finishBlock() - return - // otherwise, reference to older data - case v < 265: - length = v - (257 - 3) - n = 0 - case v < 269: - length = v*2 - (265*2 - 11) - n = 1 - case v < 273: - length = v*4 - (269*4 - 19) - n = 2 - case v < 277: - length = v*8 - (273*8 - 35) - n = 3 - case v < 281: - length = v*16 - (277*16 - 67) - n = 4 - case v < 285: - length = v*32 - (281*32 - 131) - n = 5 - case v < maxNumLit: - length = 258 - n = 0 - default: - if debugDecode { - fmt.Println(v, ">= maxNumLit") - } - f.err = CorruptInputError(f.roffset) - return - } - if n > 0 { - for f.nb < n { - if err = moreBits(); err != nil { - if debugDecode { - fmt.Println("morebits n>0:", err) - } - f.err = err - return - } - } - length += int(f.b & uint32(1<>= n - f.nb -= n - } - - var dist int - if f.hd == nil { - for f.nb < 5 { - if err = moreBits(); err != nil { - if debugDecode { - fmt.Println("morebits f.nb<5:", err) - } - f.err = err - return - } - } - dist = int(bits.Reverse8(uint8(f.b & 0x1F << 3))) - f.b >>= 5 - f.nb -= 5 - } else { - if dist, err = f.huffSym(f.hd); err != nil { - if debugDecode { - fmt.Println("huffsym:", err) - } - f.err = err - return - } - } - - switch { - case dist < 4: - dist++ - case dist < maxNumDist: - nb := uint(dist-2) >> 1 - // have 1 bit in bottom of dist, need nb more. - extra := (dist & 1) << nb - for f.nb < nb { - if err = moreBits(); err != nil { - if debugDecode { - fmt.Println("morebits f.nb>= nb - f.nb -= nb - dist = 1<<(nb+1) + 1 + extra - default: - if debugDecode { - fmt.Println("dist too big:", dist, maxNumDist) - } - f.err = CorruptInputError(f.roffset) - return - } - - // No check on length; encoding can be prescient. - if dist > f.dict.histSize() { - if debugDecode { - fmt.Println("dist > f.dict.histSize():", dist, f.dict.histSize()) - } - f.err = CorruptInputError(f.roffset) - return - } - - f.copyLen, f.copyDist = length, dist - goto copyHistory - } - -copyHistory: - // Perform a backwards copy according to RFC section 3.2.3. - { - cnt := f.dict.tryWriteCopy(f.copyDist, f.copyLen) - if cnt == 0 { - cnt = f.dict.writeCopy(f.copyDist, f.copyLen) - } - f.copyLen -= cnt - - if f.dict.availWrite() == 0 || f.copyLen > 0 { - f.toRead = f.dict.readFlush() - f.step = (*decompressor).huffmanBufioReader // We need to continue this work - f.stepState = stateDict - return - } - goto readLiteral - } -} - -// Decode a single Huffman block from f. -// hl and hd are the Huffman states for the lit/length values -// and the distance values, respectively. If hd == nil, using the -// fixed distance encoding associated with fixed Huffman blocks. -func (f *decompressor) huffmanStringsReader() { - const ( - stateInit = iota // Zero value must be stateInit - stateDict - ) - fr := f.r.(*strings.Reader) - moreBits := func() error { - c, err := fr.ReadByte() - if err != nil { - return noEOF(err) - } - f.roffset++ - f.b |= uint32(c) << f.nb - f.nb += 8 - return nil - } - - switch f.stepState { - case stateInit: - goto readLiteral - case stateDict: - goto copyHistory - } - -readLiteral: - // Read literal and/or (length, distance) according to RFC section 3.2.3. - { - var v int - { - // Inlined v, err := f.huffSym(f.hl) - // Since a huffmanDecoder can be empty or be composed of a degenerate tree - // with single element, huffSym must error on these two edge cases. In both - // cases, the chunks slice will be 0 for the invalid sequence, leading it - // satisfy the n == 0 check below. - n := uint(f.hl.maxRead) - // Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers, - // but is smart enough to keep local variables in registers, so use nb and b, - // inline call to moreBits and reassign b,nb back to f on return. - nb, b := f.nb, f.b - for { - for nb < n { - c, err := fr.ReadByte() - if err != nil { - f.b = b - f.nb = nb - f.err = noEOF(err) - return - } - f.roffset++ - b |= uint32(c) << (nb & 31) - nb += 8 - } - chunk := f.hl.chunks[b&(huffmanNumChunks-1)] - n = uint(chunk & huffmanCountMask) - if n > huffmanChunkBits { - chunk = f.hl.links[chunk>>huffmanValueShift][(b>>huffmanChunkBits)&f.hl.linkMask] - n = uint(chunk & huffmanCountMask) - } - if n <= nb { - if n == 0 { - f.b = b - f.nb = nb - if debugDecode { - fmt.Println("huffsym: n==0") - } - f.err = CorruptInputError(f.roffset) - return - } - f.b = b >> (n & 31) - f.nb = nb - n - v = int(chunk >> huffmanValueShift) - break - } - } - } - - var n uint // number of bits extra - var length int - var err error - switch { - case v < 256: - f.dict.writeByte(byte(v)) - if f.dict.availWrite() == 0 { - f.toRead = f.dict.readFlush() - f.step = (*decompressor).huffmanStringsReader - f.stepState = stateInit - return - } - goto readLiteral - case v == 256: - f.finishBlock() - return - // otherwise, reference to older data - case v < 265: - length = v - (257 - 3) - n = 0 - case v < 269: - length = v*2 - (265*2 - 11) - n = 1 - case v < 273: - length = v*4 - (269*4 - 19) - n = 2 - case v < 277: - length = v*8 - (273*8 - 35) - n = 3 - case v < 281: - length = v*16 - (277*16 - 67) - n = 4 - case v < 285: - length = v*32 - (281*32 - 131) - n = 5 - case v < maxNumLit: - length = 258 - n = 0 - default: - if debugDecode { - fmt.Println(v, ">= maxNumLit") - } - f.err = CorruptInputError(f.roffset) - return - } - if n > 0 { - for f.nb < n { - if err = moreBits(); err != nil { - if debugDecode { - fmt.Println("morebits n>0:", err) - } - f.err = err - return - } - } - length += int(f.b & uint32(1<>= n - f.nb -= n - } - - var dist int - if f.hd == nil { - for f.nb < 5 { - if err = moreBits(); err != nil { - if debugDecode { - fmt.Println("morebits f.nb<5:", err) - } - f.err = err - return - } - } - dist = int(bits.Reverse8(uint8(f.b & 0x1F << 3))) - f.b >>= 5 - f.nb -= 5 - } else { - if dist, err = f.huffSym(f.hd); err != nil { - if debugDecode { - fmt.Println("huffsym:", err) - } - f.err = err - return - } - } - - switch { - case dist < 4: - dist++ - case dist < maxNumDist: - nb := uint(dist-2) >> 1 - // have 1 bit in bottom of dist, need nb more. - extra := (dist & 1) << nb - for f.nb < nb { - if err = moreBits(); err != nil { - if debugDecode { - fmt.Println("morebits f.nb>= nb - f.nb -= nb - dist = 1<<(nb+1) + 1 + extra - default: - if debugDecode { - fmt.Println("dist too big:", dist, maxNumDist) - } - f.err = CorruptInputError(f.roffset) - return - } - - // No check on length; encoding can be prescient. - if dist > f.dict.histSize() { - if debugDecode { - fmt.Println("dist > f.dict.histSize():", dist, f.dict.histSize()) - } - f.err = CorruptInputError(f.roffset) - return - } - - f.copyLen, f.copyDist = length, dist - goto copyHistory - } - -copyHistory: - // Perform a backwards copy according to RFC section 3.2.3. - { - cnt := f.dict.tryWriteCopy(f.copyDist, f.copyLen) - if cnt == 0 { - cnt = f.dict.writeCopy(f.copyDist, f.copyLen) - } - f.copyLen -= cnt - - if f.dict.availWrite() == 0 || f.copyLen > 0 { - f.toRead = f.dict.readFlush() - f.step = (*decompressor).huffmanStringsReader // We need to continue this work - f.stepState = stateDict - return - } - goto readLiteral - } -} - -func (f *decompressor) huffmanBlockDecoder() func() { - switch f.r.(type) { - case *bytes.Buffer: - return f.huffmanBytesBuffer - case *bytes.Reader: - return f.huffmanBytesReader - case *bufio.Reader: - return f.huffmanBufioReader - case *strings.Reader: - return f.huffmanStringsReader - default: - return f.huffmanBlockGeneric - } -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/level1.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/level1.go deleted file mode 100644 index 1e5eea3968a..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/level1.go +++ /dev/null @@ -1,179 +0,0 @@ -package flate - -import "fmt" - -// fastGen maintains the table for matches, -// and the previous byte block for level 2. -// This is the generic implementation. -type fastEncL1 struct { - fastGen - table [tableSize]tableEntry -} - -// EncodeL1 uses a similar algorithm to level 1 -func (e *fastEncL1) Encode(dst *tokens, src []byte) { - const ( - inputMargin = 12 - 1 - minNonLiteralBlockSize = 1 + 1 + inputMargin - ) - if debugDeflate && e.cur < 0 { - panic(fmt.Sprint("e.cur < 0: ", e.cur)) - } - - // Protect against e.cur wraparound. - for e.cur >= bufferReset { - if len(e.hist) == 0 { - for i := range e.table[:] { - e.table[i] = tableEntry{} - } - e.cur = maxMatchOffset - break - } - // Shift down everything in the table that isn't already too far away. - minOff := e.cur + int32(len(e.hist)) - maxMatchOffset - for i := range e.table[:] { - v := e.table[i].offset - if v <= minOff { - v = 0 - } else { - v = v - e.cur + maxMatchOffset - } - e.table[i].offset = v - } - e.cur = maxMatchOffset - } - - s := e.addBlock(src) - - // This check isn't in the Snappy implementation, but there, the caller - // instead of the callee handles this case. - if len(src) < minNonLiteralBlockSize { - // We do not fill the token table. - // This will be picked up by caller. - dst.n = uint16(len(src)) - return - } - - // Override src - src = e.hist - nextEmit := s - - // sLimit is when to stop looking for offset/length copies. The inputMargin - // lets us use a fast path for emitLiteral in the main loop, while we are - // looking for copies. - sLimit := int32(len(src) - inputMargin) - - // nextEmit is where in src the next emitLiteral should start from. - cv := load3232(src, s) - - for { - const skipLog = 5 - const doEvery = 2 - - nextS := s - var candidate tableEntry - for { - nextHash := hash(cv) - candidate = e.table[nextHash] - nextS = s + doEvery + (s-nextEmit)>>skipLog - if nextS > sLimit { - goto emitRemainder - } - - now := load6432(src, nextS) - e.table[nextHash] = tableEntry{offset: s + e.cur} - nextHash = hash(uint32(now)) - - offset := s - (candidate.offset - e.cur) - if offset < maxMatchOffset && cv == load3232(src, candidate.offset-e.cur) { - e.table[nextHash] = tableEntry{offset: nextS + e.cur} - break - } - - // Do one right away... - cv = uint32(now) - s = nextS - nextS++ - candidate = e.table[nextHash] - now >>= 8 - e.table[nextHash] = tableEntry{offset: s + e.cur} - - offset = s - (candidate.offset - e.cur) - if offset < maxMatchOffset && cv == load3232(src, candidate.offset-e.cur) { - e.table[nextHash] = tableEntry{offset: nextS + e.cur} - break - } - cv = uint32(now) - s = nextS - } - - // A 4-byte match has been found. We'll later see if more than 4 bytes - // match. But, prior to the match, src[nextEmit:s] are unmatched. Emit - // them as literal bytes. - for { - // Invariant: we have a 4-byte match at s, and no need to emit any - // literal bytes prior to s. - - // Extend the 4-byte match as long as possible. - t := candidate.offset - e.cur - l := e.matchlenLong(s+4, t+4, src) + 4 - - // Extend backwards - for t > 0 && s > nextEmit && src[t-1] == src[s-1] { - s-- - t-- - l++ - } - if nextEmit < s { - emitLiteral(dst, src[nextEmit:s]) - } - - // Save the match found - dst.AddMatchLong(l, uint32(s-t-baseMatchOffset)) - s += l - nextEmit = s - if nextS >= s { - s = nextS + 1 - } - if s >= sLimit { - // Index first pair after match end. - if int(s+l+4) < len(src) { - cv := load3232(src, s) - e.table[hash(cv)] = tableEntry{offset: s + e.cur} - } - goto emitRemainder - } - - // We could immediately start working at s now, but to improve - // compression we first update the hash table at s-2 and at s. If - // another emitCopy is not our next move, also calculate nextHash - // at s+1. At least on GOARCH=amd64, these three hash calculations - // are faster as one load64 call (with some shifts) instead of - // three load32 calls. - x := load6432(src, s-2) - o := e.cur + s - 2 - prevHash := hash(uint32(x)) - e.table[prevHash] = tableEntry{offset: o} - x >>= 16 - currHash := hash(uint32(x)) - candidate = e.table[currHash] - e.table[currHash] = tableEntry{offset: o + 2} - - offset := s - (candidate.offset - e.cur) - if offset > maxMatchOffset || uint32(x) != load3232(src, candidate.offset-e.cur) { - cv = uint32(x >> 8) - s++ - break - } - } - } - -emitRemainder: - if int(nextEmit) < len(src) { - // If nothing was added, don't encode literals. - if dst.n == 0 { - return - } - emitLiteral(dst, src[nextEmit:]) - } -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/level2.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/level2.go deleted file mode 100644 index 5b986a1944e..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/level2.go +++ /dev/null @@ -1,205 +0,0 @@ -package flate - -import "fmt" - -// fastGen maintains the table for matches, -// and the previous byte block for level 2. -// This is the generic implementation. -type fastEncL2 struct { - fastGen - table [bTableSize]tableEntry -} - -// EncodeL2 uses a similar algorithm to level 1, but is capable -// of matching across blocks giving better compression at a small slowdown. -func (e *fastEncL2) Encode(dst *tokens, src []byte) { - const ( - inputMargin = 12 - 1 - minNonLiteralBlockSize = 1 + 1 + inputMargin - ) - - if debugDeflate && e.cur < 0 { - panic(fmt.Sprint("e.cur < 0: ", e.cur)) - } - - // Protect against e.cur wraparound. - for e.cur >= bufferReset { - if len(e.hist) == 0 { - for i := range e.table[:] { - e.table[i] = tableEntry{} - } - e.cur = maxMatchOffset - break - } - // Shift down everything in the table that isn't already too far away. - minOff := e.cur + int32(len(e.hist)) - maxMatchOffset - for i := range e.table[:] { - v := e.table[i].offset - if v <= minOff { - v = 0 - } else { - v = v - e.cur + maxMatchOffset - } - e.table[i].offset = v - } - e.cur = maxMatchOffset - } - - s := e.addBlock(src) - - // This check isn't in the Snappy implementation, but there, the caller - // instead of the callee handles this case. - if len(src) < minNonLiteralBlockSize { - // We do not fill the token table. - // This will be picked up by caller. - dst.n = uint16(len(src)) - return - } - - // Override src - src = e.hist - nextEmit := s - - // sLimit is when to stop looking for offset/length copies. The inputMargin - // lets us use a fast path for emitLiteral in the main loop, while we are - // looking for copies. - sLimit := int32(len(src) - inputMargin) - - // nextEmit is where in src the next emitLiteral should start from. - cv := load3232(src, s) - for { - // When should we start skipping if we haven't found matches in a long while. - const skipLog = 5 - const doEvery = 2 - - nextS := s - var candidate tableEntry - for { - nextHash := hash4u(cv, bTableBits) - s = nextS - nextS = s + doEvery + (s-nextEmit)>>skipLog - if nextS > sLimit { - goto emitRemainder - } - candidate = e.table[nextHash] - now := load6432(src, nextS) - e.table[nextHash] = tableEntry{offset: s + e.cur} - nextHash = hash4u(uint32(now), bTableBits) - - offset := s - (candidate.offset - e.cur) - if offset < maxMatchOffset && cv == load3232(src, candidate.offset-e.cur) { - e.table[nextHash] = tableEntry{offset: nextS + e.cur} - break - } - - // Do one right away... - cv = uint32(now) - s = nextS - nextS++ - candidate = e.table[nextHash] - now >>= 8 - e.table[nextHash] = tableEntry{offset: s + e.cur} - - offset = s - (candidate.offset - e.cur) - if offset < maxMatchOffset && cv == load3232(src, candidate.offset-e.cur) { - break - } - cv = uint32(now) - } - - // A 4-byte match has been found. We'll later see if more than 4 bytes - // match. But, prior to the match, src[nextEmit:s] are unmatched. Emit - // them as literal bytes. - - // Call emitCopy, and then see if another emitCopy could be our next - // move. Repeat until we find no match for the input immediately after - // what was consumed by the last emitCopy call. - // - // If we exit this loop normally then we need to call emitLiteral next, - // though we don't yet know how big the literal will be. We handle that - // by proceeding to the next iteration of the main loop. We also can - // exit this loop via goto if we get close to exhausting the input. - for { - // Invariant: we have a 4-byte match at s, and no need to emit any - // literal bytes prior to s. - - // Extend the 4-byte match as long as possible. - t := candidate.offset - e.cur - l := e.matchlenLong(s+4, t+4, src) + 4 - - // Extend backwards - for t > 0 && s > nextEmit && src[t-1] == src[s-1] { - s-- - t-- - l++ - } - if nextEmit < s { - emitLiteral(dst, src[nextEmit:s]) - } - - dst.AddMatchLong(l, uint32(s-t-baseMatchOffset)) - s += l - nextEmit = s - if nextS >= s { - s = nextS + 1 - } - - if s >= sLimit { - // Index first pair after match end. - if int(s+l+4) < len(src) { - cv := load3232(src, s) - e.table[hash4u(cv, bTableBits)] = tableEntry{offset: s + e.cur} - } - goto emitRemainder - } - - // Store every second hash in-between, but offset by 1. - for i := s - l + 2; i < s-5; i += 7 { - x := load6432(src, int32(i)) - nextHash := hash4u(uint32(x), bTableBits) - e.table[nextHash] = tableEntry{offset: e.cur + i} - // Skip one - x >>= 16 - nextHash = hash4u(uint32(x), bTableBits) - e.table[nextHash] = tableEntry{offset: e.cur + i + 2} - // Skip one - x >>= 16 - nextHash = hash4u(uint32(x), bTableBits) - e.table[nextHash] = tableEntry{offset: e.cur + i + 4} - } - - // We could immediately start working at s now, but to improve - // compression we first update the hash table at s-2 to s. If - // another emitCopy is not our next move, also calculate nextHash - // at s+1. At least on GOARCH=amd64, these three hash calculations - // are faster as one load64 call (with some shifts) instead of - // three load32 calls. - x := load6432(src, s-2) - o := e.cur + s - 2 - prevHash := hash4u(uint32(x), bTableBits) - prevHash2 := hash4u(uint32(x>>8), bTableBits) - e.table[prevHash] = tableEntry{offset: o} - e.table[prevHash2] = tableEntry{offset: o + 1} - currHash := hash4u(uint32(x>>16), bTableBits) - candidate = e.table[currHash] - e.table[currHash] = tableEntry{offset: o + 2} - - offset := s - (candidate.offset - e.cur) - if offset > maxMatchOffset || uint32(x>>16) != load3232(src, candidate.offset-e.cur) { - cv = uint32(x >> 24) - s++ - break - } - } - } - -emitRemainder: - if int(nextEmit) < len(src) { - // If nothing was added, don't encode literals. - if dst.n == 0 { - return - } - - emitLiteral(dst, src[nextEmit:]) - } -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/level3.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/level3.go deleted file mode 100644 index c22b4244a5c..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/level3.go +++ /dev/null @@ -1,229 +0,0 @@ -package flate - -import "fmt" - -// fastEncL3 -type fastEncL3 struct { - fastGen - table [tableSize]tableEntryPrev -} - -// Encode uses a similar algorithm to level 2, will check up to two candidates. -func (e *fastEncL3) Encode(dst *tokens, src []byte) { - const ( - inputMargin = 8 - 1 - minNonLiteralBlockSize = 1 + 1 + inputMargin - ) - - if debugDeflate && e.cur < 0 { - panic(fmt.Sprint("e.cur < 0: ", e.cur)) - } - - // Protect against e.cur wraparound. - for e.cur >= bufferReset { - if len(e.hist) == 0 { - for i := range e.table[:] { - e.table[i] = tableEntryPrev{} - } - e.cur = maxMatchOffset - break - } - // Shift down everything in the table that isn't already too far away. - minOff := e.cur + int32(len(e.hist)) - maxMatchOffset - for i := range e.table[:] { - v := e.table[i] - if v.Cur.offset <= minOff { - v.Cur.offset = 0 - } else { - v.Cur.offset = v.Cur.offset - e.cur + maxMatchOffset - } - if v.Prev.offset <= minOff { - v.Prev.offset = 0 - } else { - v.Prev.offset = v.Prev.offset - e.cur + maxMatchOffset - } - e.table[i] = v - } - e.cur = maxMatchOffset - } - - s := e.addBlock(src) - - // Skip if too small. - if len(src) < minNonLiteralBlockSize { - // We do not fill the token table. - // This will be picked up by caller. - dst.n = uint16(len(src)) - return - } - - // Override src - src = e.hist - nextEmit := s - - // sLimit is when to stop looking for offset/length copies. The inputMargin - // lets us use a fast path for emitLiteral in the main loop, while we are - // looking for copies. - sLimit := int32(len(src) - inputMargin) - - // nextEmit is where in src the next emitLiteral should start from. - cv := load3232(src, s) - for { - const skipLog = 6 - nextS := s - var candidate tableEntry - for { - nextHash := hash(cv) - s = nextS - nextS = s + 1 + (s-nextEmit)>>skipLog - if nextS > sLimit { - goto emitRemainder - } - candidates := e.table[nextHash] - now := load3232(src, nextS) - - // Safe offset distance until s + 4... - minOffset := e.cur + s - (maxMatchOffset - 4) - e.table[nextHash] = tableEntryPrev{Prev: candidates.Cur, Cur: tableEntry{offset: s + e.cur}} - - // Check both candidates - candidate = candidates.Cur - if candidate.offset < minOffset { - cv = now - // Previous will also be invalid, we have nothing. - continue - } - - if cv == load3232(src, candidate.offset-e.cur) { - if candidates.Prev.offset < minOffset || cv != load3232(src, candidates.Prev.offset-e.cur) { - break - } - // Both match and are valid, pick longest. - offset := s - (candidate.offset - e.cur) - o2 := s - (candidates.Prev.offset - e.cur) - l1, l2 := matchLen(src[s+4:], src[s-offset+4:]), matchLen(src[s+4:], src[s-o2+4:]) - if l2 > l1 { - candidate = candidates.Prev - } - break - } else { - // We only check if value mismatches. - // Offset will always be invalid in other cases. - candidate = candidates.Prev - if candidate.offset > minOffset && cv == load3232(src, candidate.offset-e.cur) { - break - } - } - cv = now - } - - // Call emitCopy, and then see if another emitCopy could be our next - // move. Repeat until we find no match for the input immediately after - // what was consumed by the last emitCopy call. - // - // If we exit this loop normally then we need to call emitLiteral next, - // though we don't yet know how big the literal will be. We handle that - // by proceeding to the next iteration of the main loop. We also can - // exit this loop via goto if we get close to exhausting the input. - for { - // Invariant: we have a 4-byte match at s, and no need to emit any - // literal bytes prior to s. - - // Extend the 4-byte match as long as possible. - // - t := candidate.offset - e.cur - l := e.matchlenLong(s+4, t+4, src) + 4 - - // Extend backwards - for t > 0 && s > nextEmit && src[t-1] == src[s-1] { - s-- - t-- - l++ - } - if nextEmit < s { - emitLiteral(dst, src[nextEmit:s]) - } - - dst.AddMatchLong(l, uint32(s-t-baseMatchOffset)) - s += l - nextEmit = s - if nextS >= s { - s = nextS + 1 - } - - if s >= sLimit { - t += l - // Index first pair after match end. - if int(t+4) < len(src) && t > 0 { - cv := load3232(src, t) - nextHash := hash(cv) - e.table[nextHash] = tableEntryPrev{ - Prev: e.table[nextHash].Cur, - Cur: tableEntry{offset: e.cur + t}, - } - } - goto emitRemainder - } - - // We could immediately start working at s now, but to improve - // compression we first update the hash table at s-3 to s. - x := load6432(src, s-3) - prevHash := hash(uint32(x)) - e.table[prevHash] = tableEntryPrev{ - Prev: e.table[prevHash].Cur, - Cur: tableEntry{offset: e.cur + s - 3}, - } - x >>= 8 - prevHash = hash(uint32(x)) - - e.table[prevHash] = tableEntryPrev{ - Prev: e.table[prevHash].Cur, - Cur: tableEntry{offset: e.cur + s - 2}, - } - x >>= 8 - prevHash = hash(uint32(x)) - - e.table[prevHash] = tableEntryPrev{ - Prev: e.table[prevHash].Cur, - Cur: tableEntry{offset: e.cur + s - 1}, - } - x >>= 8 - currHash := hash(uint32(x)) - candidates := e.table[currHash] - cv = uint32(x) - e.table[currHash] = tableEntryPrev{ - Prev: candidates.Cur, - Cur: tableEntry{offset: s + e.cur}, - } - - // Check both candidates - candidate = candidates.Cur - minOffset := e.cur + s - (maxMatchOffset - 4) - - if candidate.offset > minOffset && cv != load3232(src, candidate.offset-e.cur) { - // We only check if value mismatches. - // Offset will always be invalid in other cases. - candidate = candidates.Prev - if candidate.offset > minOffset && cv == load3232(src, candidate.offset-e.cur) { - offset := s - (candidate.offset - e.cur) - if offset <= maxMatchOffset { - continue - } - } - } - cv = uint32(x >> 8) - s++ - break - } - } - -emitRemainder: - if int(nextEmit) < len(src) { - // If nothing was added, don't encode literals. - if dst.n == 0 { - return - } - - emitLiteral(dst, src[nextEmit:]) - } -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/level4.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/level4.go deleted file mode 100644 index e62f0c02b1e..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/level4.go +++ /dev/null @@ -1,212 +0,0 @@ -package flate - -import "fmt" - -type fastEncL4 struct { - fastGen - table [tableSize]tableEntry - bTable [tableSize]tableEntry -} - -func (e *fastEncL4) Encode(dst *tokens, src []byte) { - const ( - inputMargin = 12 - 1 - minNonLiteralBlockSize = 1 + 1 + inputMargin - ) - if debugDeflate && e.cur < 0 { - panic(fmt.Sprint("e.cur < 0: ", e.cur)) - } - // Protect against e.cur wraparound. - for e.cur >= bufferReset { - if len(e.hist) == 0 { - for i := range e.table[:] { - e.table[i] = tableEntry{} - } - for i := range e.bTable[:] { - e.bTable[i] = tableEntry{} - } - e.cur = maxMatchOffset - break - } - // Shift down everything in the table that isn't already too far away. - minOff := e.cur + int32(len(e.hist)) - maxMatchOffset - for i := range e.table[:] { - v := e.table[i].offset - if v <= minOff { - v = 0 - } else { - v = v - e.cur + maxMatchOffset - } - e.table[i].offset = v - } - for i := range e.bTable[:] { - v := e.bTable[i].offset - if v <= minOff { - v = 0 - } else { - v = v - e.cur + maxMatchOffset - } - e.bTable[i].offset = v - } - e.cur = maxMatchOffset - } - - s := e.addBlock(src) - - // This check isn't in the Snappy implementation, but there, the caller - // instead of the callee handles this case. - if len(src) < minNonLiteralBlockSize { - // We do not fill the token table. - // This will be picked up by caller. - dst.n = uint16(len(src)) - return - } - - // Override src - src = e.hist - nextEmit := s - - // sLimit is when to stop looking for offset/length copies. The inputMargin - // lets us use a fast path for emitLiteral in the main loop, while we are - // looking for copies. - sLimit := int32(len(src) - inputMargin) - - // nextEmit is where in src the next emitLiteral should start from. - cv := load6432(src, s) - for { - const skipLog = 6 - const doEvery = 1 - - nextS := s - var t int32 - for { - nextHashS := hash4x64(cv, tableBits) - nextHashL := hash7(cv, tableBits) - - s = nextS - nextS = s + doEvery + (s-nextEmit)>>skipLog - if nextS > sLimit { - goto emitRemainder - } - // Fetch a short+long candidate - sCandidate := e.table[nextHashS] - lCandidate := e.bTable[nextHashL] - next := load6432(src, nextS) - entry := tableEntry{offset: s + e.cur} - e.table[nextHashS] = entry - e.bTable[nextHashL] = entry - - t = lCandidate.offset - e.cur - if s-t < maxMatchOffset && uint32(cv) == load3232(src, lCandidate.offset-e.cur) { - // We got a long match. Use that. - break - } - - t = sCandidate.offset - e.cur - if s-t < maxMatchOffset && uint32(cv) == load3232(src, sCandidate.offset-e.cur) { - // Found a 4 match... - lCandidate = e.bTable[hash7(next, tableBits)] - - // If the next long is a candidate, check if we should use that instead... - lOff := nextS - (lCandidate.offset - e.cur) - if lOff < maxMatchOffset && load3232(src, lCandidate.offset-e.cur) == uint32(next) { - l1, l2 := matchLen(src[s+4:], src[t+4:]), matchLen(src[nextS+4:], src[nextS-lOff+4:]) - if l2 > l1 { - s = nextS - t = lCandidate.offset - e.cur - } - } - break - } - cv = next - } - - // A 4-byte match has been found. We'll later see if more than 4 bytes - // match. But, prior to the match, src[nextEmit:s] are unmatched. Emit - // them as literal bytes. - - // Extend the 4-byte match as long as possible. - l := e.matchlenLong(s+4, t+4, src) + 4 - - // Extend backwards - for t > 0 && s > nextEmit && src[t-1] == src[s-1] { - s-- - t-- - l++ - } - if nextEmit < s { - emitLiteral(dst, src[nextEmit:s]) - } - if debugDeflate { - if t >= s { - panic("s-t") - } - if (s - t) > maxMatchOffset { - panic(fmt.Sprintln("mmo", t)) - } - if l < baseMatchLength { - panic("bml") - } - } - - dst.AddMatchLong(l, uint32(s-t-baseMatchOffset)) - s += l - nextEmit = s - if nextS >= s { - s = nextS + 1 - } - - if s >= sLimit { - // Index first pair after match end. - if int(s+8) < len(src) { - cv := load6432(src, s) - e.table[hash4x64(cv, tableBits)] = tableEntry{offset: s + e.cur} - e.bTable[hash7(cv, tableBits)] = tableEntry{offset: s + e.cur} - } - goto emitRemainder - } - - // Store every 3rd hash in-between - if true { - i := nextS - if i < s-1 { - cv := load6432(src, i) - t := tableEntry{offset: i + e.cur} - t2 := tableEntry{offset: t.offset + 1} - e.bTable[hash7(cv, tableBits)] = t - e.bTable[hash7(cv>>8, tableBits)] = t2 - e.table[hash4u(uint32(cv>>8), tableBits)] = t2 - - i += 3 - for ; i < s-1; i += 3 { - cv := load6432(src, i) - t := tableEntry{offset: i + e.cur} - t2 := tableEntry{offset: t.offset + 1} - e.bTable[hash7(cv, tableBits)] = t - e.bTable[hash7(cv>>8, tableBits)] = t2 - e.table[hash4u(uint32(cv>>8), tableBits)] = t2 - } - } - } - - // We could immediately start working at s now, but to improve - // compression we first update the hash table at s-1 and at s. - x := load6432(src, s-1) - o := e.cur + s - 1 - prevHashS := hash4x64(x, tableBits) - prevHashL := hash7(x, tableBits) - e.table[prevHashS] = tableEntry{offset: o} - e.bTable[prevHashL] = tableEntry{offset: o} - cv = x >> 8 - } - -emitRemainder: - if int(nextEmit) < len(src) { - // If nothing was added, don't encode literals. - if dst.n == 0 { - return - } - - emitLiteral(dst, src[nextEmit:]) - } -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/level5.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/level5.go deleted file mode 100644 index d513f1ffd37..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/level5.go +++ /dev/null @@ -1,279 +0,0 @@ -package flate - -import "fmt" - -type fastEncL5 struct { - fastGen - table [tableSize]tableEntry - bTable [tableSize]tableEntryPrev -} - -func (e *fastEncL5) Encode(dst *tokens, src []byte) { - const ( - inputMargin = 12 - 1 - minNonLiteralBlockSize = 1 + 1 + inputMargin - ) - if debugDeflate && e.cur < 0 { - panic(fmt.Sprint("e.cur < 0: ", e.cur)) - } - - // Protect against e.cur wraparound. - for e.cur >= bufferReset { - if len(e.hist) == 0 { - for i := range e.table[:] { - e.table[i] = tableEntry{} - } - for i := range e.bTable[:] { - e.bTable[i] = tableEntryPrev{} - } - e.cur = maxMatchOffset - break - } - // Shift down everything in the table that isn't already too far away. - minOff := e.cur + int32(len(e.hist)) - maxMatchOffset - for i := range e.table[:] { - v := e.table[i].offset - if v <= minOff { - v = 0 - } else { - v = v - e.cur + maxMatchOffset - } - e.table[i].offset = v - } - for i := range e.bTable[:] { - v := e.bTable[i] - if v.Cur.offset <= minOff { - v.Cur.offset = 0 - v.Prev.offset = 0 - } else { - v.Cur.offset = v.Cur.offset - e.cur + maxMatchOffset - if v.Prev.offset <= minOff { - v.Prev.offset = 0 - } else { - v.Prev.offset = v.Prev.offset - e.cur + maxMatchOffset - } - } - e.bTable[i] = v - } - e.cur = maxMatchOffset - } - - s := e.addBlock(src) - - // This check isn't in the Snappy implementation, but there, the caller - // instead of the callee handles this case. - if len(src) < minNonLiteralBlockSize { - // We do not fill the token table. - // This will be picked up by caller. - dst.n = uint16(len(src)) - return - } - - // Override src - src = e.hist - nextEmit := s - - // sLimit is when to stop looking for offset/length copies. The inputMargin - // lets us use a fast path for emitLiteral in the main loop, while we are - // looking for copies. - sLimit := int32(len(src) - inputMargin) - - // nextEmit is where in src the next emitLiteral should start from. - cv := load6432(src, s) - for { - const skipLog = 6 - const doEvery = 1 - - nextS := s - var l int32 - var t int32 - for { - nextHashS := hash4x64(cv, tableBits) - nextHashL := hash7(cv, tableBits) - - s = nextS - nextS = s + doEvery + (s-nextEmit)>>skipLog - if nextS > sLimit { - goto emitRemainder - } - // Fetch a short+long candidate - sCandidate := e.table[nextHashS] - lCandidate := e.bTable[nextHashL] - next := load6432(src, nextS) - entry := tableEntry{offset: s + e.cur} - e.table[nextHashS] = entry - eLong := &e.bTable[nextHashL] - eLong.Cur, eLong.Prev = entry, eLong.Cur - - nextHashS = hash4x64(next, tableBits) - nextHashL = hash7(next, tableBits) - - t = lCandidate.Cur.offset - e.cur - if s-t < maxMatchOffset { - if uint32(cv) == load3232(src, lCandidate.Cur.offset-e.cur) { - // Store the next match - e.table[nextHashS] = tableEntry{offset: nextS + e.cur} - eLong := &e.bTable[nextHashL] - eLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur - - t2 := lCandidate.Prev.offset - e.cur - if s-t2 < maxMatchOffset && uint32(cv) == load3232(src, lCandidate.Prev.offset-e.cur) { - l = e.matchlen(s+4, t+4, src) + 4 - ml1 := e.matchlen(s+4, t2+4, src) + 4 - if ml1 > l { - t = t2 - l = ml1 - break - } - } - break - } - t = lCandidate.Prev.offset - e.cur - if s-t < maxMatchOffset && uint32(cv) == load3232(src, lCandidate.Prev.offset-e.cur) { - // Store the next match - e.table[nextHashS] = tableEntry{offset: nextS + e.cur} - eLong := &e.bTable[nextHashL] - eLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur - break - } - } - - t = sCandidate.offset - e.cur - if s-t < maxMatchOffset && uint32(cv) == load3232(src, sCandidate.offset-e.cur) { - // Found a 4 match... - l = e.matchlen(s+4, t+4, src) + 4 - lCandidate = e.bTable[nextHashL] - // Store the next match - - e.table[nextHashS] = tableEntry{offset: nextS + e.cur} - eLong := &e.bTable[nextHashL] - eLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur - - // If the next long is a candidate, use that... - t2 := lCandidate.Cur.offset - e.cur - if nextS-t2 < maxMatchOffset { - if load3232(src, lCandidate.Cur.offset-e.cur) == uint32(next) { - ml := e.matchlen(nextS+4, t2+4, src) + 4 - if ml > l { - t = t2 - s = nextS - l = ml - break - } - } - // If the previous long is a candidate, use that... - t2 = lCandidate.Prev.offset - e.cur - if nextS-t2 < maxMatchOffset && load3232(src, lCandidate.Prev.offset-e.cur) == uint32(next) { - ml := e.matchlen(nextS+4, t2+4, src) + 4 - if ml > l { - t = t2 - s = nextS - l = ml - break - } - } - } - break - } - cv = next - } - - // A 4-byte match has been found. We'll later see if more than 4 bytes - // match. But, prior to the match, src[nextEmit:s] are unmatched. Emit - // them as literal bytes. - - // Extend the 4-byte match as long as possible. - if l == 0 { - l = e.matchlenLong(s+4, t+4, src) + 4 - } else if l == maxMatchLength { - l += e.matchlenLong(s+l, t+l, src) - } - // Extend backwards - for t > 0 && s > nextEmit && src[t-1] == src[s-1] { - s-- - t-- - l++ - } - if nextEmit < s { - emitLiteral(dst, src[nextEmit:s]) - } - if debugDeflate { - if t >= s { - panic(fmt.Sprintln("s-t", s, t)) - } - if (s - t) > maxMatchOffset { - panic(fmt.Sprintln("mmo", s-t)) - } - if l < baseMatchLength { - panic("bml") - } - } - - dst.AddMatchLong(l, uint32(s-t-baseMatchOffset)) - s += l - nextEmit = s - if nextS >= s { - s = nextS + 1 - } - - if s >= sLimit { - goto emitRemainder - } - - // Store every 3rd hash in-between. - if true { - const hashEvery = 3 - i := s - l + 1 - if i < s-1 { - cv := load6432(src, i) - t := tableEntry{offset: i + e.cur} - e.table[hash4x64(cv, tableBits)] = t - eLong := &e.bTable[hash7(cv, tableBits)] - eLong.Cur, eLong.Prev = t, eLong.Cur - - // Do an long at i+1 - cv >>= 8 - t = tableEntry{offset: t.offset + 1} - eLong = &e.bTable[hash7(cv, tableBits)] - eLong.Cur, eLong.Prev = t, eLong.Cur - - // We only have enough bits for a short entry at i+2 - cv >>= 8 - t = tableEntry{offset: t.offset + 1} - e.table[hash4x64(cv, tableBits)] = t - - // Skip one - otherwise we risk hitting 's' - i += 4 - for ; i < s-1; i += hashEvery { - cv := load6432(src, i) - t := tableEntry{offset: i + e.cur} - t2 := tableEntry{offset: t.offset + 1} - eLong := &e.bTable[hash7(cv, tableBits)] - eLong.Cur, eLong.Prev = t, eLong.Cur - e.table[hash4u(uint32(cv>>8), tableBits)] = t2 - } - } - } - - // We could immediately start working at s now, but to improve - // compression we first update the hash table at s-1 and at s. - x := load6432(src, s-1) - o := e.cur + s - 1 - prevHashS := hash4x64(x, tableBits) - prevHashL := hash7(x, tableBits) - e.table[prevHashS] = tableEntry{offset: o} - eLong := &e.bTable[prevHashL] - eLong.Cur, eLong.Prev = tableEntry{offset: o}, eLong.Cur - cv = x >> 8 - } - -emitRemainder: - if int(nextEmit) < len(src) { - // If nothing was added, don't encode literals. - if dst.n == 0 { - return - } - - emitLiteral(dst, src[nextEmit:]) - } -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/level6.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/level6.go deleted file mode 100644 index a52c80ea456..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/level6.go +++ /dev/null @@ -1,282 +0,0 @@ -package flate - -import "fmt" - -type fastEncL6 struct { - fastGen - table [tableSize]tableEntry - bTable [tableSize]tableEntryPrev -} - -func (e *fastEncL6) Encode(dst *tokens, src []byte) { - const ( - inputMargin = 12 - 1 - minNonLiteralBlockSize = 1 + 1 + inputMargin - ) - if debugDeflate && e.cur < 0 { - panic(fmt.Sprint("e.cur < 0: ", e.cur)) - } - - // Protect against e.cur wraparound. - for e.cur >= bufferReset { - if len(e.hist) == 0 { - for i := range e.table[:] { - e.table[i] = tableEntry{} - } - for i := range e.bTable[:] { - e.bTable[i] = tableEntryPrev{} - } - e.cur = maxMatchOffset - break - } - // Shift down everything in the table that isn't already too far away. - minOff := e.cur + int32(len(e.hist)) - maxMatchOffset - for i := range e.table[:] { - v := e.table[i].offset - if v <= minOff { - v = 0 - } else { - v = v - e.cur + maxMatchOffset - } - e.table[i].offset = v - } - for i := range e.bTable[:] { - v := e.bTable[i] - if v.Cur.offset <= minOff { - v.Cur.offset = 0 - v.Prev.offset = 0 - } else { - v.Cur.offset = v.Cur.offset - e.cur + maxMatchOffset - if v.Prev.offset <= minOff { - v.Prev.offset = 0 - } else { - v.Prev.offset = v.Prev.offset - e.cur + maxMatchOffset - } - } - e.bTable[i] = v - } - e.cur = maxMatchOffset - } - - s := e.addBlock(src) - - // This check isn't in the Snappy implementation, but there, the caller - // instead of the callee handles this case. - if len(src) < minNonLiteralBlockSize { - // We do not fill the token table. - // This will be picked up by caller. - dst.n = uint16(len(src)) - return - } - - // Override src - src = e.hist - nextEmit := s - - // sLimit is when to stop looking for offset/length copies. The inputMargin - // lets us use a fast path for emitLiteral in the main loop, while we are - // looking for copies. - sLimit := int32(len(src) - inputMargin) - - // nextEmit is where in src the next emitLiteral should start from. - cv := load6432(src, s) - // Repeat MUST be > 1 and within range - repeat := int32(1) - for { - const skipLog = 7 - const doEvery = 1 - - nextS := s - var l int32 - var t int32 - for { - nextHashS := hash4x64(cv, tableBits) - nextHashL := hash7(cv, tableBits) - s = nextS - nextS = s + doEvery + (s-nextEmit)>>skipLog - if nextS > sLimit { - goto emitRemainder - } - // Fetch a short+long candidate - sCandidate := e.table[nextHashS] - lCandidate := e.bTable[nextHashL] - next := load6432(src, nextS) - entry := tableEntry{offset: s + e.cur} - e.table[nextHashS] = entry - eLong := &e.bTable[nextHashL] - eLong.Cur, eLong.Prev = entry, eLong.Cur - - // Calculate hashes of 'next' - nextHashS = hash4x64(next, tableBits) - nextHashL = hash7(next, tableBits) - - t = lCandidate.Cur.offset - e.cur - if s-t < maxMatchOffset { - if uint32(cv) == load3232(src, lCandidate.Cur.offset-e.cur) { - // Long candidate matches at least 4 bytes. - - // Store the next match - e.table[nextHashS] = tableEntry{offset: nextS + e.cur} - eLong := &e.bTable[nextHashL] - eLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur - - // Check the previous long candidate as well. - t2 := lCandidate.Prev.offset - e.cur - if s-t2 < maxMatchOffset && uint32(cv) == load3232(src, lCandidate.Prev.offset-e.cur) { - l = e.matchlen(s+4, t+4, src) + 4 - ml1 := e.matchlen(s+4, t2+4, src) + 4 - if ml1 > l { - t = t2 - l = ml1 - break - } - } - break - } - // Current value did not match, but check if previous long value does. - t = lCandidate.Prev.offset - e.cur - if s-t < maxMatchOffset && uint32(cv) == load3232(src, lCandidate.Prev.offset-e.cur) { - // Store the next match - e.table[nextHashS] = tableEntry{offset: nextS + e.cur} - eLong := &e.bTable[nextHashL] - eLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur - break - } - } - - t = sCandidate.offset - e.cur - if s-t < maxMatchOffset && uint32(cv) == load3232(src, sCandidate.offset-e.cur) { - // Found a 4 match... - l = e.matchlen(s+4, t+4, src) + 4 - - // Look up next long candidate (at nextS) - lCandidate = e.bTable[nextHashL] - - // Store the next match - e.table[nextHashS] = tableEntry{offset: nextS + e.cur} - eLong := &e.bTable[nextHashL] - eLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur - - // Check repeat at s + repOff - const repOff = 1 - t2 := s - repeat + repOff - if load3232(src, t2) == uint32(cv>>(8*repOff)) { - ml := e.matchlen(s+4+repOff, t2+4, src) + 4 - if ml > l { - t = t2 - l = ml - s += repOff - // Not worth checking more. - break - } - } - - // If the next long is a candidate, use that... - t2 = lCandidate.Cur.offset - e.cur - if nextS-t2 < maxMatchOffset { - if load3232(src, lCandidate.Cur.offset-e.cur) == uint32(next) { - ml := e.matchlen(nextS+4, t2+4, src) + 4 - if ml > l { - t = t2 - s = nextS - l = ml - // This is ok, but check previous as well. - } - } - // If the previous long is a candidate, use that... - t2 = lCandidate.Prev.offset - e.cur - if nextS-t2 < maxMatchOffset && load3232(src, lCandidate.Prev.offset-e.cur) == uint32(next) { - ml := e.matchlen(nextS+4, t2+4, src) + 4 - if ml > l { - t = t2 - s = nextS - l = ml - break - } - } - } - break - } - cv = next - } - - // A 4-byte match has been found. We'll later see if more than 4 bytes - // match. But, prior to the match, src[nextEmit:s] are unmatched. Emit - // them as literal bytes. - - // Extend the 4-byte match as long as possible. - if l == 0 { - l = e.matchlenLong(s+4, t+4, src) + 4 - } else if l == maxMatchLength { - l += e.matchlenLong(s+l, t+l, src) - } - - // Extend backwards - for t > 0 && s > nextEmit && src[t-1] == src[s-1] { - s-- - t-- - l++ - } - if nextEmit < s { - emitLiteral(dst, src[nextEmit:s]) - } - if false { - if t >= s { - panic(fmt.Sprintln("s-t", s, t)) - } - if (s - t) > maxMatchOffset { - panic(fmt.Sprintln("mmo", s-t)) - } - if l < baseMatchLength { - panic("bml") - } - } - - dst.AddMatchLong(l, uint32(s-t-baseMatchOffset)) - repeat = s - t - s += l - nextEmit = s - if nextS >= s { - s = nextS + 1 - } - - if s >= sLimit { - // Index after match end. - for i := nextS + 1; i < int32(len(src))-8; i += 2 { - cv := load6432(src, i) - e.table[hash4x64(cv, tableBits)] = tableEntry{offset: i + e.cur} - eLong := &e.bTable[hash7(cv, tableBits)] - eLong.Cur, eLong.Prev = tableEntry{offset: i + e.cur}, eLong.Cur - } - goto emitRemainder - } - - // Store every long hash in-between and every second short. - if true { - for i := nextS + 1; i < s-1; i += 2 { - cv := load6432(src, i) - t := tableEntry{offset: i + e.cur} - t2 := tableEntry{offset: t.offset + 1} - eLong := &e.bTable[hash7(cv, tableBits)] - eLong2 := &e.bTable[hash7(cv>>8, tableBits)] - e.table[hash4x64(cv, tableBits)] = t - eLong.Cur, eLong.Prev = t, eLong.Cur - eLong2.Cur, eLong2.Prev = t2, eLong2.Cur - } - } - - // We could immediately start working at s now, but to improve - // compression we first update the hash table at s-1 and at s. - cv = load6432(src, s) - } - -emitRemainder: - if int(nextEmit) < len(src) { - // If nothing was added, don't encode literals. - if dst.n == 0 { - return - } - - emitLiteral(dst, src[nextEmit:]) - } -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/stateless.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/stateless.go deleted file mode 100644 index 53e89912463..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/stateless.go +++ /dev/null @@ -1,297 +0,0 @@ -package flate - -import ( - "io" - "math" - "sync" -) - -const ( - maxStatelessBlock = math.MaxInt16 - // dictionary will be taken from maxStatelessBlock, so limit it. - maxStatelessDict = 8 << 10 - - slTableBits = 13 - slTableSize = 1 << slTableBits - slTableShift = 32 - slTableBits -) - -type statelessWriter struct { - dst io.Writer - closed bool -} - -func (s *statelessWriter) Close() error { - if s.closed { - return nil - } - s.closed = true - // Emit EOF block - return StatelessDeflate(s.dst, nil, true, nil) -} - -func (s *statelessWriter) Write(p []byte) (n int, err error) { - err = StatelessDeflate(s.dst, p, false, nil) - if err != nil { - return 0, err - } - return len(p), nil -} - -func (s *statelessWriter) Reset(w io.Writer) { - s.dst = w - s.closed = false -} - -// NewStatelessWriter will do compression but without maintaining any state -// between Write calls. -// There will be no memory kept between Write calls, -// but compression and speed will be suboptimal. -// Because of this, the size of actual Write calls will affect output size. -func NewStatelessWriter(dst io.Writer) io.WriteCloser { - return &statelessWriter{dst: dst} -} - -// bitWriterPool contains bit writers that can be reused. -var bitWriterPool = sync.Pool{ - New: func() interface{} { - return newHuffmanBitWriter(nil) - }, -} - -// StatelessDeflate allows to compress directly to a Writer without retaining state. -// When returning everything will be flushed. -// Up to 8KB of an optional dictionary can be given which is presumed to presumed to precede the block. -// Longer dictionaries will be truncated and will still produce valid output. -// Sending nil dictionary is perfectly fine. -func StatelessDeflate(out io.Writer, in []byte, eof bool, dict []byte) error { - var dst tokens - bw := bitWriterPool.Get().(*huffmanBitWriter) - bw.reset(out) - defer func() { - // don't keep a reference to our output - bw.reset(nil) - bitWriterPool.Put(bw) - }() - if eof && len(in) == 0 { - // Just write an EOF block. - // Could be faster... - bw.writeStoredHeader(0, true) - bw.flush() - return bw.err - } - - // Truncate dict - if len(dict) > maxStatelessDict { - dict = dict[len(dict)-maxStatelessDict:] - } - - for len(in) > 0 { - todo := in - if len(todo) > maxStatelessBlock-len(dict) { - todo = todo[:maxStatelessBlock-len(dict)] - } - in = in[len(todo):] - uncompressed := todo - if len(dict) > 0 { - // combine dict and source - bufLen := len(todo) + len(dict) - combined := make([]byte, bufLen) - copy(combined, dict) - copy(combined[len(dict):], todo) - todo = combined - } - // Compress - statelessEnc(&dst, todo, int16(len(dict))) - isEof := eof && len(in) == 0 - - if dst.n == 0 { - bw.writeStoredHeader(len(uncompressed), isEof) - if bw.err != nil { - return bw.err - } - bw.writeBytes(uncompressed) - } else if int(dst.n) > len(uncompressed)-len(uncompressed)>>4 { - // If we removed less than 1/16th, huffman compress the block. - bw.writeBlockHuff(isEof, uncompressed, len(in) == 0) - } else { - bw.writeBlockDynamic(&dst, isEof, uncompressed, len(in) == 0) - } - if len(in) > 0 { - // Retain a dict if we have more - dict = todo[len(todo)-maxStatelessDict:] - dst.Reset() - } - if bw.err != nil { - return bw.err - } - } - if !eof { - // Align, only a stored block can do that. - bw.writeStoredHeader(0, false) - } - bw.flush() - return bw.err -} - -func hashSL(u uint32) uint32 { - return (u * 0x1e35a7bd) >> slTableShift -} - -func load3216(b []byte, i int16) uint32 { - // Help the compiler eliminate bounds checks on the read so it can be done in a single read. - b = b[i:] - b = b[:4] - return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 -} - -func load6416(b []byte, i int16) uint64 { - // Help the compiler eliminate bounds checks on the read so it can be done in a single read. - b = b[i:] - b = b[:8] - return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | - uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 -} - -func statelessEnc(dst *tokens, src []byte, startAt int16) { - const ( - inputMargin = 12 - 1 - minNonLiteralBlockSize = 1 + 1 + inputMargin - ) - - type tableEntry struct { - offset int16 - } - - var table [slTableSize]tableEntry - - // This check isn't in the Snappy implementation, but there, the caller - // instead of the callee handles this case. - if len(src)-int(startAt) < minNonLiteralBlockSize { - // We do not fill the token table. - // This will be picked up by caller. - dst.n = 0 - return - } - // Index until startAt - if startAt > 0 { - cv := load3232(src, 0) - for i := int16(0); i < startAt; i++ { - table[hashSL(cv)] = tableEntry{offset: i} - cv = (cv >> 8) | (uint32(src[i+4]) << 24) - } - } - - s := startAt + 1 - nextEmit := startAt - // sLimit is when to stop looking for offset/length copies. The inputMargin - // lets us use a fast path for emitLiteral in the main loop, while we are - // looking for copies. - sLimit := int16(len(src) - inputMargin) - - // nextEmit is where in src the next emitLiteral should start from. - cv := load3216(src, s) - - for { - const skipLog = 5 - const doEvery = 2 - - nextS := s - var candidate tableEntry - for { - nextHash := hashSL(cv) - candidate = table[nextHash] - nextS = s + doEvery + (s-nextEmit)>>skipLog - if nextS > sLimit || nextS <= 0 { - goto emitRemainder - } - - now := load6416(src, nextS) - table[nextHash] = tableEntry{offset: s} - nextHash = hashSL(uint32(now)) - - if cv == load3216(src, candidate.offset) { - table[nextHash] = tableEntry{offset: nextS} - break - } - - // Do one right away... - cv = uint32(now) - s = nextS - nextS++ - candidate = table[nextHash] - now >>= 8 - table[nextHash] = tableEntry{offset: s} - - if cv == load3216(src, candidate.offset) { - table[nextHash] = tableEntry{offset: nextS} - break - } - cv = uint32(now) - s = nextS - } - - // A 4-byte match has been found. We'll later see if more than 4 bytes - // match. But, prior to the match, src[nextEmit:s] are unmatched. Emit - // them as literal bytes. - for { - // Invariant: we have a 4-byte match at s, and no need to emit any - // literal bytes prior to s. - - // Extend the 4-byte match as long as possible. - t := candidate.offset - l := int16(matchLen(src[s+4:], src[t+4:]) + 4) - - // Extend backwards - for t > 0 && s > nextEmit && src[t-1] == src[s-1] { - s-- - t-- - l++ - } - if nextEmit < s { - emitLiteral(dst, src[nextEmit:s]) - } - - // Save the match found - dst.AddMatchLong(int32(l), uint32(s-t-baseMatchOffset)) - s += l - nextEmit = s - if nextS >= s { - s = nextS + 1 - } - if s >= sLimit { - goto emitRemainder - } - - // We could immediately start working at s now, but to improve - // compression we first update the hash table at s-2 and at s. If - // another emitCopy is not our next move, also calculate nextHash - // at s+1. At least on GOARCH=amd64, these three hash calculations - // are faster as one load64 call (with some shifts) instead of - // three load32 calls. - x := load6416(src, s-2) - o := s - 2 - prevHash := hashSL(uint32(x)) - table[prevHash] = tableEntry{offset: o} - x >>= 16 - currHash := hashSL(uint32(x)) - candidate = table[currHash] - table[currHash] = tableEntry{offset: o + 2} - - if uint32(x) != load3216(src, candidate.offset) { - cv = uint32(x >> 8) - s++ - break - } - } - } - -emitRemainder: - if int(nextEmit) < len(src) { - // If nothing was added, don't encode literals. - if dst.n == 0 { - return - } - emitLiteral(dst, src[nextEmit:]) - } -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/token.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/token.go deleted file mode 100644 index f9abf606d67..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/klauspost/compress/flate/token.go +++ /dev/null @@ -1,375 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flate - -import ( - "bytes" - "encoding/binary" - "fmt" - "io" - "math" -) - -const ( - // 2 bits: type 0 = literal 1=EOF 2=Match 3=Unused - // 8 bits: xlength = length - MIN_MATCH_LENGTH - // 22 bits xoffset = offset - MIN_OFFSET_SIZE, or literal - lengthShift = 22 - offsetMask = 1<maxnumlit - offHist [32]uint16 // offset codes - litHist [256]uint16 // codes 0->255 - n uint16 // Must be able to contain maxStoreBlockSize - tokens [maxStoreBlockSize + 1]token -} - -func (t *tokens) Reset() { - if t.n == 0 { - return - } - t.n = 0 - t.nLits = 0 - for i := range t.litHist[:] { - t.litHist[i] = 0 - } - for i := range t.extraHist[:] { - t.extraHist[i] = 0 - } - for i := range t.offHist[:] { - t.offHist[i] = 0 - } -} - -func (t *tokens) Fill() { - if t.n == 0 { - return - } - for i, v := range t.litHist[:] { - if v == 0 { - t.litHist[i] = 1 - t.nLits++ - } - } - for i, v := range t.extraHist[:literalCount-256] { - if v == 0 { - t.nLits++ - t.extraHist[i] = 1 - } - } - for i, v := range t.offHist[:offsetCodeCount] { - if v == 0 { - t.offHist[i] = 1 - } - } -} - -func indexTokens(in []token) tokens { - var t tokens - t.indexTokens(in) - return t -} - -func (t *tokens) indexTokens(in []token) { - t.Reset() - for _, tok := range in { - if tok < matchType { - t.AddLiteral(tok.literal()) - continue - } - t.AddMatch(uint32(tok.length()), tok.offset()) - } -} - -// emitLiteral writes a literal chunk and returns the number of bytes written. -func emitLiteral(dst *tokens, lit []byte) { - ol := int(dst.n) - for i, v := range lit { - dst.tokens[(i+ol)&maxStoreBlockSize] = token(v) - dst.litHist[v]++ - } - dst.n += uint16(len(lit)) - dst.nLits += len(lit) -} - -func (t *tokens) AddLiteral(lit byte) { - t.tokens[t.n] = token(lit) - t.litHist[lit]++ - t.n++ - t.nLits++ -} - -// from https://stackoverflow.com/a/28730362 -func mFastLog2(val float32) float32 { - ux := int32(math.Float32bits(val)) - log2 := (float32)(((ux >> 23) & 255) - 128) - ux &= -0x7f800001 - ux += 127 << 23 - uval := math.Float32frombits(uint32(ux)) - log2 += ((-0.34484843)*uval+2.02466578)*uval - 0.67487759 - return log2 -} - -// EstimatedBits will return an minimum size estimated by an *optimal* -// compression of the block. -// The size of the block -func (t *tokens) EstimatedBits() int { - shannon := float32(0) - bits := int(0) - nMatches := 0 - if t.nLits > 0 { - invTotal := 1.0 / float32(t.nLits) - for _, v := range t.litHist[:] { - if v > 0 { - n := float32(v) - shannon += -mFastLog2(n*invTotal) * n - } - } - // Just add 15 for EOB - shannon += 15 - for i, v := range t.extraHist[1 : literalCount-256] { - if v > 0 { - n := float32(v) - shannon += -mFastLog2(n*invTotal) * n - bits += int(lengthExtraBits[i&31]) * int(v) - nMatches += int(v) - } - } - } - if nMatches > 0 { - invTotal := 1.0 / float32(nMatches) - for i, v := range t.offHist[:offsetCodeCount] { - if v > 0 { - n := float32(v) - shannon += -mFastLog2(n*invTotal) * n - bits += int(offsetExtraBits[i&31]) * int(v) - } - } - } - return int(shannon) + bits -} - -// AddMatch adds a match to the tokens. -// This function is very sensitive to inlining and right on the border. -func (t *tokens) AddMatch(xlength uint32, xoffset uint32) { - if debugDeflate { - if xlength >= maxMatchLength+baseMatchLength { - panic(fmt.Errorf("invalid length: %v", xlength)) - } - if xoffset >= maxMatchOffset+baseMatchOffset { - panic(fmt.Errorf("invalid offset: %v", xoffset)) - } - } - t.nLits++ - lengthCode := lengthCodes1[uint8(xlength)] & 31 - t.tokens[t.n] = token(matchType | xlength<= maxMatchOffset+baseMatchOffset { - panic(fmt.Errorf("invalid offset: %v", xoffset)) - } - } - oc := offsetCode(xoffset) & 31 - for xlength > 0 { - xl := xlength - if xl > 258 { - // We need to have at least baseMatchLength left over for next loop. - xl = 258 - baseMatchLength - } - xlength -= xl - xl -= 3 - t.nLits++ - lengthCode := lengthCodes1[uint8(xl)] & 31 - t.tokens[t.n] = token(matchType | uint32(xl)<> lengthShift) } - -// The code is never more than 8 bits, but is returned as uint32 for convenience. -func lengthCode(len uint8) uint32 { return uint32(lengthCodes[len]) } - -// Returns the offset code corresponding to a specific offset -func offsetCode(off uint32) uint32 { - if false { - if off < uint32(len(offsetCodes)) { - return offsetCodes[off&255] - } else if off>>7 < uint32(len(offsetCodes)) { - return offsetCodes[(off>>7)&255] + 14 - } else { - return offsetCodes[(off>>14)&255] + 28 - } - } - if off < uint32(len(offsetCodes)) { - return offsetCodes[uint8(off)] - } - return offsetCodes14[uint8(off>>7)] -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/go-logger/.gitignore b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/go-logger/.gitignore deleted file mode 100644 index f1c181ec9c5..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/go-logger/.gitignore +++ /dev/null @@ -1,12 +0,0 @@ -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -# Test binary, build with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/go-logger/LICENSE b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/go-logger/LICENSE deleted file mode 100644 index 7364c76bad1..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/go-logger/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 sachin shinde - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/go-logger/logging.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/go-logger/logging.go deleted file mode 100644 index 12d377d8056..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/go-logger/logging.go +++ /dev/null @@ -1,82 +0,0 @@ -package logging - -import ( - "log" - "io" - "io/ioutil" - "os" -) - -type Logger struct { - Name string - Trace *log.Logger - Info *log.Logger - Warning *log.Logger - Error *log.Logger - level LoggingLevel -} - -var loggers = make(map[string]Logger) - -func GetLogger(name string) Logger { - return New(name, os.Stdout, os.Stdout, os.Stdout, os.Stderr) -} - -func (logger Logger) SetLevel(level LoggingLevel) Logger{ - switch level { - case TRACE: - logger.Trace.SetOutput(os.Stdout); - logger.Info.SetOutput(os.Stdout); - logger.Warning.SetOutput(os.Stdout); - logger.Error.SetOutput(os.Stderr); - case INFO: - logger.Trace.SetOutput(ioutil.Discard); - logger.Info.SetOutput(os.Stdout); - logger.Warning.SetOutput(os.Stdout); - logger.Error.SetOutput(os.Stderr); - case WARNING: - logger.Trace.SetOutput(ioutil.Discard); - logger.Info.SetOutput(ioutil.Discard); - logger.Warning.SetOutput(os.Stdout); - logger.Error.SetOutput(os.Stderr); - case ERROR: - logger.Trace.SetOutput(ioutil.Discard); - logger.Info.SetOutput(ioutil.Discard); - logger.Warning.SetOutput(ioutil.Discard); - logger.Error.SetOutput(os.Stderr); - case OFF: - logger.Trace.SetOutput(ioutil.Discard); - logger.Info.SetOutput(ioutil.Discard); - logger.Warning.SetOutput(ioutil.Discard); - logger.Error.SetOutput(ioutil.Discard); - } - return logger; -} - -func (logger Logger) GetLevel() LoggingLevel { - return logger.level; -} - -func New( - name string, - traceHandle io.Writer, - infoHandle io.Writer, - warningHandle io.Writer, - errorHandle io.Writer) Logger { - loggers[name] = Logger{ - Name: name, - Trace: log.New(traceHandle, - "TRACE: ", - log.Ldate|log.Ltime|log.Lshortfile), - Info: log.New(infoHandle, - "INFO: ", - log.Ldate|log.Ltime|log.Lshortfile), - Warning: log.New(warningHandle, - "WARNING: ", - log.Ldate|log.Ltime|log.Lshortfile), - Error: log.New(errorHandle, - "ERROR: ", - log.Ldate|log.Ltime|log.Lshortfile), - } - return loggers[name] -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/go-logger/loggingL.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/go-logger/loggingL.go deleted file mode 100644 index aab5a8567af..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/go-logger/loggingL.go +++ /dev/null @@ -1,13 +0,0 @@ -package logging - -type LoggingLevel int - -//go:generate stringer -type=LoggingLevel - -const ( - TRACE LoggingLevel = iota - INFO - WARNING - ERROR - OFF -) diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/go-logger/logginglevel_string.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/go-logger/logginglevel_string.go deleted file mode 100644 index 9f24f0acbfe..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/go-logger/logginglevel_string.go +++ /dev/null @@ -1,16 +0,0 @@ -// Code generated by "stringer -type=LoggingLevel"; DO NOT EDIT. - -package logging - -import "strconv" - -const _LoggingLevel_name = "TRACEINFOWARNINGERROROFF" - -var _LoggingLevel_index = [...]uint8{0, 5, 9, 16, 21, 24} - -func (i LoggingLevel) String() string { - if i < 0 || i >= LoggingLevel(len(_LoggingLevel_index)-1) { - return "LoggingLevel(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _LoggingLevel_name[_LoggingLevel_index[i]:_LoggingLevel_index[i+1]] -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/gowebsocket/.gitignore b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/gowebsocket/.gitignore deleted file mode 100644 index 9a289397844..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/gowebsocket/.gitignore +++ /dev/null @@ -1,21 +0,0 @@ -# Binaries for programs and plugins -*.exe -*.dll -*.so -*.dylib - -# Test binary, build with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 -.glide/ - -# ignore build under build directory -build/ -bin/ - -#ignore any IDE based files -.idea/** \ No newline at end of file diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/gowebsocket/README.md b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/gowebsocket/README.md deleted file mode 100644 index 2439bc6a7e1..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/gowebsocket/README.md +++ /dev/null @@ -1,157 +0,0 @@ -# GoWebsocket -Gorilla websocket based simplified client implementation in GO. - -Overview --------- -This client provides following easy to implement functionality -- Support for emitting and receiving text and binary data -- Data compression -- Concurrency control -- Proxy support -- Setting request headers -- Subprotocols support -- SSL verification enable/disable - -To install use - -```markdown - go get github.com/sacOO7/gowebsocket -``` - -Description ------------ - -Create instance of `Websocket` by passing url of websocket-server end-point - -```go - //Create a client instance - socket := gowebsocket.New("ws://echo.websocket.org/") - -``` - -**Important Note** : url to websocket server must be specified with either **ws** or **wss**. - -#### Connecting to server -- For connecting to server: - -```go - //This will send websocket handshake request to socketcluster-server - socket.Connect() -``` - -#### Registering All Listeners -```go - package main - - import ( - "log" - "github.com/sacOO7/gowebsocket" - "os" - "os/signal" - ) - - func main() { - - interrupt := make(chan os.Signal, 1) - signal.Notify(interrupt, os.Interrupt) - - socket := gowebsocket.New("ws://echo.websocket.org/"); - - socket.OnConnected = func(socket gowebsocket.Socket) { - log.Println("Connected to server"); - }; - - socket.OnConnectError = func(err error, socket gowebsocket.Socket) { - log.Println("Recieved connect error ", err) - }; - - socket.OnTextMessage = func(message string, socket gowebsocket.Socket) { - log.Println("Recieved message " + message) - }; - - socket.OnBinaryMessage = func(data [] byte, socket gowebsocket.Socket) { - log.Println("Recieved binary data ", data) - }; - - socket.OnPingReceived = func(data string, socket gowebsocket.Socket) { - log.Println("Recieved ping " + data) - }; - - socket.OnPongReceived = func(data string, socket gowebsocket.Socket) { - log.Println("Recieved pong " + data) - }; - - socket.OnDisconnected = func(err error, socket gowebsocket.Socket) { - log.Println("Disconnected from server ") - return - }; - - socket.Connect() - - for { - select { - case <-interrupt: - log.Println("interrupt") - socket.Close() - return - } - } - } - -``` - -#### Sending Text message - -```go - socket.SendText("Hi there, this is my sample test message") -``` - -#### Sending Binary data -```go - token := make([]byte, 4) - // rand.Read(token) putting some random value in token - socket.SendBinary(token) -``` - -#### Closing the connection with server -```go - socket.Close() -``` - -#### Setting request headers -```go - socket.RequestHeader.Set("Accept-Encoding","gzip, deflate, sdch") - socket.RequestHeader.Set("Accept-Language","en-US,en;q=0.8") - socket.RequestHeader.Set("Pragma","no-cache") - socket.RequestHeader.Set("User-Agent","Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36") - -``` - -#### Setting proxy server -- It can be set using connectionOptions by providing url to proxy server - -```go - socket.ConnectionOptions = gowebsocket.ConnectionOptions { - Proxy: gowebsocket.BuildProxy("http://example.com"), - } -``` - -#### Setting data compression, ssl verification and subprotocols - -- It can be set using connectionOptions inside socket - -```go - socket.ConnectionOptions = gowebsocket.ConnectionOptions { - UseSSL:true, - UseCompression:true, - Subprotocols: [] string{"chat","superchat"}, - } -``` - -- ConnectionOptions needs to be applied before connecting to server -- Please checkout [**examples/gowebsocket**](!https://github.com/sacOO7/GoWebsocket/tree/master/examples/gowebsocket) directory for detailed code.. - -License -------- -Apache License, Version 2.0 - diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/gowebsocket/gowebsocket.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/gowebsocket/gowebsocket.go deleted file mode 100644 index 1ea2b0d7a71..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/gowebsocket/gowebsocket.go +++ /dev/null @@ -1,186 +0,0 @@ -package gowebsocket - -import ( - "github.com/gorilla/websocket" - "net/http" - "errors" - "crypto/tls" - "net/url" - "sync" - "github.com/sacOO7/go-logger" - "reflect" -) - -type Empty struct { -} - -var logger = logging.GetLogger(reflect.TypeOf(Empty{}).PkgPath()).SetLevel(logging.OFF) - -func (socket Socket) EnableLogging() { - logger.SetLevel(logging.TRACE) -} - -func (socket Socket) GetLogger() logging.Logger { - return logger; -} - -type Socket struct { - Conn *websocket.Conn - WebsocketDialer *websocket.Dialer - Url string - ConnectionOptions ConnectionOptions - RequestHeader http.Header - OnConnected func(socket Socket) - OnTextMessage func(message string, socket Socket) - OnBinaryMessage func(data [] byte, socket Socket) - OnConnectError func(err error, socket Socket) - OnDisconnected func(err error, socket Socket) - OnPingReceived func(data string, socket Socket) - OnPongReceived func(data string, socket Socket) - IsConnected bool - sendMu *sync.Mutex // Prevent "concurrent write to websocket connection" - receiveMu *sync.Mutex -} - -type ConnectionOptions struct { - UseCompression bool - UseSSL bool - Proxy func(*http.Request) (*url.URL, error) - Subprotocols [] string -} - -// todo Yet to be done -type ReconnectionOptions struct { -} - -func New(url string) Socket { - return Socket{ - Url: url, - RequestHeader: http.Header{}, - ConnectionOptions: ConnectionOptions{ - UseCompression: false, - UseSSL: true, - }, - WebsocketDialer: &websocket.Dialer{}, - sendMu: &sync.Mutex{}, - receiveMu: &sync.Mutex{}, - } -} - -func (socket *Socket) setConnectionOptions() { - socket.WebsocketDialer.EnableCompression = socket.ConnectionOptions.UseCompression - socket.WebsocketDialer.TLSClientConfig = &tls.Config{InsecureSkipVerify: socket.ConnectionOptions.UseSSL} - socket.WebsocketDialer.Proxy = socket.ConnectionOptions.Proxy - socket.WebsocketDialer.Subprotocols = socket.ConnectionOptions.Subprotocols -} - -func (socket *Socket) Connect() { - var err error; - socket.setConnectionOptions() - - socket.Conn, _, err = socket.WebsocketDialer.Dial(socket.Url, socket.RequestHeader) - - if err != nil { - logger.Error.Println("Error while connecting to server ", err) - socket.IsConnected = false - if socket.OnConnectError != nil { - socket.OnConnectError(err, *socket) - } - return - } - - logger.Info.Println("Connected to server") - - if socket.OnConnected != nil { - socket.IsConnected = true - socket.OnConnected(*socket) - } - - defaultPingHandler := socket.Conn.PingHandler() - socket.Conn.SetPingHandler(func(appData string) error { - logger.Trace.Println("Received PING from server") - if socket.OnPingReceived != nil { - socket.OnPingReceived(appData, *socket) - } - return defaultPingHandler(appData) - }) - - defaultPongHandler := socket.Conn.PongHandler() - socket.Conn.SetPongHandler(func(appData string) error { - logger.Trace.Println("Received PONG from server") - if socket.OnPongReceived != nil { - socket.OnPongReceived(appData, *socket) - } - return defaultPongHandler(appData) - }) - - defaultCloseHandler := socket.Conn.CloseHandler() - socket.Conn.SetCloseHandler(func(code int, text string) error { - result := defaultCloseHandler(code, text) - logger.Warning.Println("Disconnected from server ", result) - if socket.OnDisconnected != nil { - socket.IsConnected = false - socket.OnDisconnected(errors.New(text), *socket) - } - return result - }) - - go func() { - for { - socket.receiveMu.Lock() - messageType, message, err := socket.Conn.ReadMessage() - socket.receiveMu.Unlock() - if err != nil { - logger.Error.Println("read:", err) - return - } - logger.Info.Println("recv: %s", message) - - switch messageType { - case websocket.TextMessage: - if socket.OnTextMessage != nil { - socket.OnTextMessage(string(message), *socket) - } - case websocket.BinaryMessage: - if socket.OnBinaryMessage != nil { - socket.OnBinaryMessage(message, *socket) - } - } - } - }() -} - -func (socket *Socket) SendText(message string) { - err := socket.send(websocket.TextMessage, [] byte (message)) - if err != nil { - logger.Error.Println("write:", err) - return - } -} - -func (socket *Socket) SendBinary(data [] byte) { - err := socket.send(websocket.BinaryMessage, data) - if err != nil { - logger.Error.Println("write:", err) - return - } -} - -func (socket *Socket) send(messageType int, data [] byte) error { - socket.sendMu.Lock() - err := socket.Conn.WriteMessage(messageType, data) - socket.sendMu.Unlock() - return err -} - -func (socket *Socket) Close() { - err := socket.send(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")) - if err != nil { - logger.Error.Println("write close:", err) - } - socket.Conn.Close() - if socket.OnDisconnected != nil { - socket.IsConnected = false - socket.OnDisconnected(err, *socket) - } -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/gowebsocket/stub.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/gowebsocket/stub.go new file mode 100644 index 00000000000..f1f20c86857 --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/gowebsocket/stub.go @@ -0,0 +1,58 @@ +// Code generated by depstubber. DO NOT EDIT. +// This is a simple stub for github.com/sacOO7/gowebsocket, strictly for use in testing. + +// See the LICENSE file for information about the licensing of the original library. +// Source: github.com/sacOO7/gowebsocket (exports: ; functions: New,BuildProxy) + +// Package gowebsocket is a stub of github.com/sacOO7/gowebsocket, generated by depstubber. +package gowebsocket + +import ( + http "net/http" + url "net/url" +) + +func BuildProxy(_ string) func(*http.Request) (*url.URL, error) { + return nil +} + +type ConnectionOptions struct { + UseCompression bool + UseSSL bool + Proxy func(*http.Request) (*url.URL, error) + Subprotocols []string +} + +func New(_ string) Socket { + return Socket{} +} + +type Socket struct { + Conn interface{} + WebsocketDialer interface{} + Url string + ConnectionOptions ConnectionOptions + RequestHeader http.Header + OnConnected func(Socket) + OnTextMessage func(string, Socket) + OnBinaryMessage func([]byte, Socket) + OnConnectError func(error, Socket) + OnDisconnected func(error, Socket) + OnPingReceived func(string, Socket) + OnPongReceived func(string, Socket) + IsConnected bool +} + +func (_ Socket) EnableLogging() {} + +func (_ Socket) GetLogger() interface{} { + return nil +} + +func (_ *Socket) Close() {} + +func (_ *Socket) Connect() {} + +func (_ *Socket) SendBinary(_ []byte) {} + +func (_ *Socket) SendText(_ string) {} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/gowebsocket/utils.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/gowebsocket/utils.go deleted file mode 100644 index d8702ebb6df..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/github.com/sacOO7/gowebsocket/utils.go +++ /dev/null @@ -1,15 +0,0 @@ -package gowebsocket - -import ( - "net/http" - "net/url" - "log" -) - -func BuildProxy(Url string) func(*http.Request) (*url.URL, error) { - uProxy, err := url.Parse(Url) - if err != nil { - log.Fatal("Error while parsing url ", err) - } - return http.ProxyURL(uProxy) -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/AUTHORS b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/AUTHORS deleted file mode 100644 index 15167cd746c..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/AUTHORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code refers to The Go Authors for copyright purposes. -# The master list of authors is in the main Go distribution, -# visible at http://tip.golang.org/AUTHORS. diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/CONTRIBUTORS b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/CONTRIBUTORS deleted file mode 100644 index 1c4577e9680..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/CONTRIBUTORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code was written by the Go contributors. -# The master list of contributors is in the main Go distribution, -# visible at http://tip.golang.org/CONTRIBUTORS. diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/PATENTS b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/PATENTS deleted file mode 100644 index 733099041f8..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/PATENTS +++ /dev/null @@ -1,22 +0,0 @@ -Additional IP Rights Grant (Patents) - -"This implementation" means the copyrightable works distributed by -Google as part of the Go project. - -Google hereby grants to You a perpetual, worldwide, non-exclusive, -no-charge, royalty-free, irrevocable (except as stated in this section) -patent license to make, have made, use, offer to sell, sell, import, -transfer and otherwise run, modify and propagate the contents of this -implementation of Go, where such license applies only to those patent -claims, both currently owned or controlled by Google and acquired in -the future, licensable by Google that are necessarily infringed by this -implementation of Go. This grant does not include claims that would be -infringed only as a consequence of further modification of this -implementation. If you or your agent or exclusive licensee institute or -order or agree to the institution of patent litigation against any -entity (including a cross-claim or counterclaim in a lawsuit) alleging -that this implementation of Go or any code incorporated within this -implementation of Go constitutes direct or contributory patent -infringement, or inducement of patent infringement, then any patent -rights granted to you under this License for this implementation of Go -shall terminate as of the date such litigation is filed. diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/LICENSE b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/LICENSE similarity index 100% rename from ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/LICENSE rename to ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/LICENSE diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/client.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/client.go deleted file mode 100644 index 69a4ac7eefe..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/client.go +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -import ( - "bufio" - "io" - "net" - "net/http" - "net/url" -) - -// DialError is an error that occurs while dialling a websocket server. -type DialError struct { - *Config - Err error -} - -func (e *DialError) Error() string { - return "websocket.Dial " + e.Config.Location.String() + ": " + e.Err.Error() -} - -// NewConfig creates a new WebSocket config for client connection. -func NewConfig(server, origin string) (config *Config, err error) { - config = new(Config) - config.Version = ProtocolVersionHybi13 - config.Location, err = url.ParseRequestURI(server) - if err != nil { - return - } - config.Origin, err = url.ParseRequestURI(origin) - if err != nil { - return - } - config.Header = http.Header(make(map[string][]string)) - return -} - -// NewClient creates a new WebSocket client connection over rwc. -func NewClient(config *Config, rwc io.ReadWriteCloser) (ws *Conn, err error) { - br := bufio.NewReader(rwc) - bw := bufio.NewWriter(rwc) - err = hybiClientHandshake(config, br, bw) - if err != nil { - return - } - buf := bufio.NewReadWriter(br, bw) - ws = newHybiClientConn(config, buf, rwc) - return -} - -// Dial opens a new client connection to a WebSocket. -func Dial(url_, protocol, origin string) (ws *Conn, err error) { - config, err := NewConfig(url_, origin) - if err != nil { - return nil, err - } - if protocol != "" { - config.Protocol = []string{protocol} - } - return DialConfig(config) -} - -var portMap = map[string]string{ - "ws": "80", - "wss": "443", -} - -func parseAuthority(location *url.URL) string { - if _, ok := portMap[location.Scheme]; ok { - if _, _, err := net.SplitHostPort(location.Host); err != nil { - return net.JoinHostPort(location.Host, portMap[location.Scheme]) - } - } - return location.Host -} - -// DialConfig opens a new client connection to a WebSocket with a config. -func DialConfig(config *Config) (ws *Conn, err error) { - var client net.Conn - if config.Location == nil { - return nil, &DialError{config, ErrBadWebSocketLocation} - } - if config.Origin == nil { - return nil, &DialError{config, ErrBadWebSocketOrigin} - } - dialer := config.Dialer - if dialer == nil { - dialer = &net.Dialer{} - } - client, err = dialWithDialer(dialer, config) - if err != nil { - goto Error - } - ws, err = NewClient(config, client) - if err != nil { - client.Close() - goto Error - } - return - -Error: - return nil, &DialError{config, err} -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/dial.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/dial.go deleted file mode 100644 index 2dab943a489..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/dial.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -import ( - "crypto/tls" - "net" -) - -func dialWithDialer(dialer *net.Dialer, config *Config) (conn net.Conn, err error) { - switch config.Location.Scheme { - case "ws": - conn, err = dialer.Dial("tcp", parseAuthority(config.Location)) - - case "wss": - conn, err = tls.DialWithDialer(dialer, "tcp", parseAuthority(config.Location), config.TlsConfig) - - default: - err = ErrBadScheme - } - return -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/hybi.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/hybi.go deleted file mode 100644 index 8cffdd16c91..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/hybi.go +++ /dev/null @@ -1,583 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -// This file implements a protocol of hybi draft. -// http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17 - -import ( - "bufio" - "bytes" - "crypto/rand" - "crypto/sha1" - "encoding/base64" - "encoding/binary" - "fmt" - "io" - "io/ioutil" - "net/http" - "net/url" - "strings" -) - -const ( - websocketGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" - - closeStatusNormal = 1000 - closeStatusGoingAway = 1001 - closeStatusProtocolError = 1002 - closeStatusUnsupportedData = 1003 - closeStatusFrameTooLarge = 1004 - closeStatusNoStatusRcvd = 1005 - closeStatusAbnormalClosure = 1006 - closeStatusBadMessageData = 1007 - closeStatusPolicyViolation = 1008 - closeStatusTooBigData = 1009 - closeStatusExtensionMismatch = 1010 - - maxControlFramePayloadLength = 125 -) - -var ( - ErrBadMaskingKey = &ProtocolError{"bad masking key"} - ErrBadPongMessage = &ProtocolError{"bad pong message"} - ErrBadClosingStatus = &ProtocolError{"bad closing status"} - ErrUnsupportedExtensions = &ProtocolError{"unsupported extensions"} - ErrNotImplemented = &ProtocolError{"not implemented"} - - handshakeHeader = map[string]bool{ - "Host": true, - "Upgrade": true, - "Connection": true, - "Sec-Websocket-Key": true, - "Sec-Websocket-Origin": true, - "Sec-Websocket-Version": true, - "Sec-Websocket-Protocol": true, - "Sec-Websocket-Accept": true, - } -) - -// A hybiFrameHeader is a frame header as defined in hybi draft. -type hybiFrameHeader struct { - Fin bool - Rsv [3]bool - OpCode byte - Length int64 - MaskingKey []byte - - data *bytes.Buffer -} - -// A hybiFrameReader is a reader for hybi frame. -type hybiFrameReader struct { - reader io.Reader - - header hybiFrameHeader - pos int64 - length int -} - -func (frame *hybiFrameReader) Read(msg []byte) (n int, err error) { - n, err = frame.reader.Read(msg) - if frame.header.MaskingKey != nil { - for i := 0; i < n; i++ { - msg[i] = msg[i] ^ frame.header.MaskingKey[frame.pos%4] - frame.pos++ - } - } - return n, err -} - -func (frame *hybiFrameReader) PayloadType() byte { return frame.header.OpCode } - -func (frame *hybiFrameReader) HeaderReader() io.Reader { - if frame.header.data == nil { - return nil - } - if frame.header.data.Len() == 0 { - return nil - } - return frame.header.data -} - -func (frame *hybiFrameReader) TrailerReader() io.Reader { return nil } - -func (frame *hybiFrameReader) Len() (n int) { return frame.length } - -// A hybiFrameReaderFactory creates new frame reader based on its frame type. -type hybiFrameReaderFactory struct { - *bufio.Reader -} - -// NewFrameReader reads a frame header from the connection, and creates new reader for the frame. -// See Section 5.2 Base Framing protocol for detail. -// http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17#section-5.2 -func (buf hybiFrameReaderFactory) NewFrameReader() (frame frameReader, err error) { - hybiFrame := new(hybiFrameReader) - frame = hybiFrame - var header []byte - var b byte - // First byte. FIN/RSV1/RSV2/RSV3/OpCode(4bits) - b, err = buf.ReadByte() - if err != nil { - return - } - header = append(header, b) - hybiFrame.header.Fin = ((header[0] >> 7) & 1) != 0 - for i := 0; i < 3; i++ { - j := uint(6 - i) - hybiFrame.header.Rsv[i] = ((header[0] >> j) & 1) != 0 - } - hybiFrame.header.OpCode = header[0] & 0x0f - - // Second byte. Mask/Payload len(7bits) - b, err = buf.ReadByte() - if err != nil { - return - } - header = append(header, b) - mask := (b & 0x80) != 0 - b &= 0x7f - lengthFields := 0 - switch { - case b <= 125: // Payload length 7bits. - hybiFrame.header.Length = int64(b) - case b == 126: // Payload length 7+16bits - lengthFields = 2 - case b == 127: // Payload length 7+64bits - lengthFields = 8 - } - for i := 0; i < lengthFields; i++ { - b, err = buf.ReadByte() - if err != nil { - return - } - if lengthFields == 8 && i == 0 { // MSB must be zero when 7+64 bits - b &= 0x7f - } - header = append(header, b) - hybiFrame.header.Length = hybiFrame.header.Length*256 + int64(b) - } - if mask { - // Masking key. 4 bytes. - for i := 0; i < 4; i++ { - b, err = buf.ReadByte() - if err != nil { - return - } - header = append(header, b) - hybiFrame.header.MaskingKey = append(hybiFrame.header.MaskingKey, b) - } - } - hybiFrame.reader = io.LimitReader(buf.Reader, hybiFrame.header.Length) - hybiFrame.header.data = bytes.NewBuffer(header) - hybiFrame.length = len(header) + int(hybiFrame.header.Length) - return -} - -// A HybiFrameWriter is a writer for hybi frame. -type hybiFrameWriter struct { - writer *bufio.Writer - - header *hybiFrameHeader -} - -func (frame *hybiFrameWriter) Write(msg []byte) (n int, err error) { - var header []byte - var b byte - if frame.header.Fin { - b |= 0x80 - } - for i := 0; i < 3; i++ { - if frame.header.Rsv[i] { - j := uint(6 - i) - b |= 1 << j - } - } - b |= frame.header.OpCode - header = append(header, b) - if frame.header.MaskingKey != nil { - b = 0x80 - } else { - b = 0 - } - lengthFields := 0 - length := len(msg) - switch { - case length <= 125: - b |= byte(length) - case length < 65536: - b |= 126 - lengthFields = 2 - default: - b |= 127 - lengthFields = 8 - } - header = append(header, b) - for i := 0; i < lengthFields; i++ { - j := uint((lengthFields - i - 1) * 8) - b = byte((length >> j) & 0xff) - header = append(header, b) - } - if frame.header.MaskingKey != nil { - if len(frame.header.MaskingKey) != 4 { - return 0, ErrBadMaskingKey - } - header = append(header, frame.header.MaskingKey...) - frame.writer.Write(header) - data := make([]byte, length) - for i := range data { - data[i] = msg[i] ^ frame.header.MaskingKey[i%4] - } - frame.writer.Write(data) - err = frame.writer.Flush() - return length, err - } - frame.writer.Write(header) - frame.writer.Write(msg) - err = frame.writer.Flush() - return length, err -} - -func (frame *hybiFrameWriter) Close() error { return nil } - -type hybiFrameWriterFactory struct { - *bufio.Writer - needMaskingKey bool -} - -func (buf hybiFrameWriterFactory) NewFrameWriter(payloadType byte) (frame frameWriter, err error) { - frameHeader := &hybiFrameHeader{Fin: true, OpCode: payloadType} - if buf.needMaskingKey { - frameHeader.MaskingKey, err = generateMaskingKey() - if err != nil { - return nil, err - } - } - return &hybiFrameWriter{writer: buf.Writer, header: frameHeader}, nil -} - -type hybiFrameHandler struct { - conn *Conn - payloadType byte -} - -func (handler *hybiFrameHandler) HandleFrame(frame frameReader) (frameReader, error) { - if handler.conn.IsServerConn() { - // The client MUST mask all frames sent to the server. - if frame.(*hybiFrameReader).header.MaskingKey == nil { - handler.WriteClose(closeStatusProtocolError) - return nil, io.EOF - } - } else { - // The server MUST NOT mask all frames. - if frame.(*hybiFrameReader).header.MaskingKey != nil { - handler.WriteClose(closeStatusProtocolError) - return nil, io.EOF - } - } - if header := frame.HeaderReader(); header != nil { - io.Copy(ioutil.Discard, header) - } - switch frame.PayloadType() { - case ContinuationFrame: - frame.(*hybiFrameReader).header.OpCode = handler.payloadType - case TextFrame, BinaryFrame: - handler.payloadType = frame.PayloadType() - case CloseFrame: - return nil, io.EOF - case PingFrame, PongFrame: - b := make([]byte, maxControlFramePayloadLength) - n, err := io.ReadFull(frame, b) - if err != nil && err != io.EOF && err != io.ErrUnexpectedEOF { - return nil, err - } - io.Copy(ioutil.Discard, frame) - if frame.PayloadType() == PingFrame { - if _, err := handler.WritePong(b[:n]); err != nil { - return nil, err - } - } - return nil, nil - } - return frame, nil -} - -func (handler *hybiFrameHandler) WriteClose(status int) (err error) { - handler.conn.wio.Lock() - defer handler.conn.wio.Unlock() - w, err := handler.conn.frameWriterFactory.NewFrameWriter(CloseFrame) - if err != nil { - return err - } - msg := make([]byte, 2) - binary.BigEndian.PutUint16(msg, uint16(status)) - _, err = w.Write(msg) - w.Close() - return err -} - -func (handler *hybiFrameHandler) WritePong(msg []byte) (n int, err error) { - handler.conn.wio.Lock() - defer handler.conn.wio.Unlock() - w, err := handler.conn.frameWriterFactory.NewFrameWriter(PongFrame) - if err != nil { - return 0, err - } - n, err = w.Write(msg) - w.Close() - return n, err -} - -// newHybiConn creates a new WebSocket connection speaking hybi draft protocol. -func newHybiConn(config *Config, buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) *Conn { - if buf == nil { - br := bufio.NewReader(rwc) - bw := bufio.NewWriter(rwc) - buf = bufio.NewReadWriter(br, bw) - } - ws := &Conn{config: config, request: request, buf: buf, rwc: rwc, - frameReaderFactory: hybiFrameReaderFactory{buf.Reader}, - frameWriterFactory: hybiFrameWriterFactory{ - buf.Writer, request == nil}, - PayloadType: TextFrame, - defaultCloseStatus: closeStatusNormal} - ws.frameHandler = &hybiFrameHandler{conn: ws} - return ws -} - -// generateMaskingKey generates a masking key for a frame. -func generateMaskingKey() (maskingKey []byte, err error) { - maskingKey = make([]byte, 4) - if _, err = io.ReadFull(rand.Reader, maskingKey); err != nil { - return - } - return -} - -// generateNonce generates a nonce consisting of a randomly selected 16-byte -// value that has been base64-encoded. -func generateNonce() (nonce []byte) { - key := make([]byte, 16) - if _, err := io.ReadFull(rand.Reader, key); err != nil { - panic(err) - } - nonce = make([]byte, 24) - base64.StdEncoding.Encode(nonce, key) - return -} - -// removeZone removes IPv6 zone identifer from host. -// E.g., "[fe80::1%en0]:8080" to "[fe80::1]:8080" -func removeZone(host string) string { - if !strings.HasPrefix(host, "[") { - return host - } - i := strings.LastIndex(host, "]") - if i < 0 { - return host - } - j := strings.LastIndex(host[:i], "%") - if j < 0 { - return host - } - return host[:j] + host[i:] -} - -// getNonceAccept computes the base64-encoded SHA-1 of the concatenation of -// the nonce ("Sec-WebSocket-Key" value) with the websocket GUID string. -func getNonceAccept(nonce []byte) (expected []byte, err error) { - h := sha1.New() - if _, err = h.Write(nonce); err != nil { - return - } - if _, err = h.Write([]byte(websocketGUID)); err != nil { - return - } - expected = make([]byte, 28) - base64.StdEncoding.Encode(expected, h.Sum(nil)) - return -} - -// Client handshake described in draft-ietf-hybi-thewebsocket-protocol-17 -func hybiClientHandshake(config *Config, br *bufio.Reader, bw *bufio.Writer) (err error) { - bw.WriteString("GET " + config.Location.RequestURI() + " HTTP/1.1\r\n") - - // According to RFC 6874, an HTTP client, proxy, or other - // intermediary must remove any IPv6 zone identifier attached - // to an outgoing URI. - bw.WriteString("Host: " + removeZone(config.Location.Host) + "\r\n") - bw.WriteString("Upgrade: websocket\r\n") - bw.WriteString("Connection: Upgrade\r\n") - nonce := generateNonce() - if config.handshakeData != nil { - nonce = []byte(config.handshakeData["key"]) - } - bw.WriteString("Sec-WebSocket-Key: " + string(nonce) + "\r\n") - bw.WriteString("Origin: " + strings.ToLower(config.Origin.String()) + "\r\n") - - if config.Version != ProtocolVersionHybi13 { - return ErrBadProtocolVersion - } - - bw.WriteString("Sec-WebSocket-Version: " + fmt.Sprintf("%d", config.Version) + "\r\n") - if len(config.Protocol) > 0 { - bw.WriteString("Sec-WebSocket-Protocol: " + strings.Join(config.Protocol, ", ") + "\r\n") - } - // TODO(ukai): send Sec-WebSocket-Extensions. - err = config.Header.WriteSubset(bw, handshakeHeader) - if err != nil { - return err - } - - bw.WriteString("\r\n") - if err = bw.Flush(); err != nil { - return err - } - - resp, err := http.ReadResponse(br, &http.Request{Method: "GET"}) - if err != nil { - return err - } - if resp.StatusCode != 101 { - return ErrBadStatus - } - if strings.ToLower(resp.Header.Get("Upgrade")) != "websocket" || - strings.ToLower(resp.Header.Get("Connection")) != "upgrade" { - return ErrBadUpgrade - } - expectedAccept, err := getNonceAccept(nonce) - if err != nil { - return err - } - if resp.Header.Get("Sec-WebSocket-Accept") != string(expectedAccept) { - return ErrChallengeResponse - } - if resp.Header.Get("Sec-WebSocket-Extensions") != "" { - return ErrUnsupportedExtensions - } - offeredProtocol := resp.Header.Get("Sec-WebSocket-Protocol") - if offeredProtocol != "" { - protocolMatched := false - for i := 0; i < len(config.Protocol); i++ { - if config.Protocol[i] == offeredProtocol { - protocolMatched = true - break - } - } - if !protocolMatched { - return ErrBadWebSocketProtocol - } - config.Protocol = []string{offeredProtocol} - } - - return nil -} - -// newHybiClientConn creates a client WebSocket connection after handshake. -func newHybiClientConn(config *Config, buf *bufio.ReadWriter, rwc io.ReadWriteCloser) *Conn { - return newHybiConn(config, buf, rwc, nil) -} - -// A HybiServerHandshaker performs a server handshake using hybi draft protocol. -type hybiServerHandshaker struct { - *Config - accept []byte -} - -func (c *hybiServerHandshaker) ReadHandshake(buf *bufio.Reader, req *http.Request) (code int, err error) { - c.Version = ProtocolVersionHybi13 - if req.Method != "GET" { - return http.StatusMethodNotAllowed, ErrBadRequestMethod - } - // HTTP version can be safely ignored. - - if strings.ToLower(req.Header.Get("Upgrade")) != "websocket" || - !strings.Contains(strings.ToLower(req.Header.Get("Connection")), "upgrade") { - return http.StatusBadRequest, ErrNotWebSocket - } - - key := req.Header.Get("Sec-Websocket-Key") - if key == "" { - return http.StatusBadRequest, ErrChallengeResponse - } - version := req.Header.Get("Sec-Websocket-Version") - switch version { - case "13": - c.Version = ProtocolVersionHybi13 - default: - return http.StatusBadRequest, ErrBadWebSocketVersion - } - var scheme string - if req.TLS != nil { - scheme = "wss" - } else { - scheme = "ws" - } - c.Location, err = url.ParseRequestURI(scheme + "://" + req.Host + req.URL.RequestURI()) - if err != nil { - return http.StatusBadRequest, err - } - protocol := strings.TrimSpace(req.Header.Get("Sec-Websocket-Protocol")) - if protocol != "" { - protocols := strings.Split(protocol, ",") - for i := 0; i < len(protocols); i++ { - c.Protocol = append(c.Protocol, strings.TrimSpace(protocols[i])) - } - } - c.accept, err = getNonceAccept([]byte(key)) - if err != nil { - return http.StatusInternalServerError, err - } - return http.StatusSwitchingProtocols, nil -} - -// Origin parses the Origin header in req. -// If the Origin header is not set, it returns nil and nil. -func Origin(config *Config, req *http.Request) (*url.URL, error) { - var origin string - switch config.Version { - case ProtocolVersionHybi13: - origin = req.Header.Get("Origin") - } - if origin == "" { - return nil, nil - } - return url.ParseRequestURI(origin) -} - -func (c *hybiServerHandshaker) AcceptHandshake(buf *bufio.Writer) (err error) { - if len(c.Protocol) > 0 { - if len(c.Protocol) != 1 { - // You need choose a Protocol in Handshake func in Server. - return ErrBadWebSocketProtocol - } - } - buf.WriteString("HTTP/1.1 101 Switching Protocols\r\n") - buf.WriteString("Upgrade: websocket\r\n") - buf.WriteString("Connection: Upgrade\r\n") - buf.WriteString("Sec-WebSocket-Accept: " + string(c.accept) + "\r\n") - if len(c.Protocol) > 0 { - buf.WriteString("Sec-WebSocket-Protocol: " + c.Protocol[0] + "\r\n") - } - // TODO(ukai): send Sec-WebSocket-Extensions. - if c.Header != nil { - err := c.Header.WriteSubset(buf, handshakeHeader) - if err != nil { - return err - } - } - buf.WriteString("\r\n") - return buf.Flush() -} - -func (c *hybiServerHandshaker) NewServerConn(buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) *Conn { - return newHybiServerConn(c.Config, buf, rwc, request) -} - -// newHybiServerConn returns a new WebSocket connection speaking hybi draft protocol. -func newHybiServerConn(config *Config, buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) *Conn { - return newHybiConn(config, buf, rwc, request) -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/server.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/server.go deleted file mode 100644 index 0895dea1905..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/server.go +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package websocket - -import ( - "bufio" - "fmt" - "io" - "net/http" -) - -func newServerConn(rwc io.ReadWriteCloser, buf *bufio.ReadWriter, req *http.Request, config *Config, handshake func(*Config, *http.Request) error) (conn *Conn, err error) { - var hs serverHandshaker = &hybiServerHandshaker{Config: config} - code, err := hs.ReadHandshake(buf.Reader, req) - if err == ErrBadWebSocketVersion { - fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code)) - fmt.Fprintf(buf, "Sec-WebSocket-Version: %s\r\n", SupportedProtocolVersion) - buf.WriteString("\r\n") - buf.WriteString(err.Error()) - buf.Flush() - return - } - if err != nil { - fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code)) - buf.WriteString("\r\n") - buf.WriteString(err.Error()) - buf.Flush() - return - } - if handshake != nil { - err = handshake(config, req) - if err != nil { - code = http.StatusForbidden - fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code)) - buf.WriteString("\r\n") - buf.Flush() - return - } - } - err = hs.AcceptHandshake(buf.Writer) - if err != nil { - code = http.StatusBadRequest - fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code)) - buf.WriteString("\r\n") - buf.Flush() - return - } - conn = hs.NewServerConn(buf, rwc, req) - return -} - -// Server represents a server of a WebSocket. -type Server struct { - // Config is a WebSocket configuration for new WebSocket connection. - Config - - // Handshake is an optional function in WebSocket handshake. - // For example, you can check, or don't check Origin header. - // Another example, you can select config.Protocol. - Handshake func(*Config, *http.Request) error - - // Handler handles a WebSocket connection. - Handler -} - -// ServeHTTP implements the http.Handler interface for a WebSocket -func (s Server) ServeHTTP(w http.ResponseWriter, req *http.Request) { - s.serveWebSocket(w, req) -} - -func (s Server) serveWebSocket(w http.ResponseWriter, req *http.Request) { - rwc, buf, err := w.(http.Hijacker).Hijack() - if err != nil { - panic("Hijack failed: " + err.Error()) - } - // The server should abort the WebSocket connection if it finds - // the client did not send a handshake that matches with protocol - // specification. - defer rwc.Close() - conn, err := newServerConn(rwc, buf, req, &s.Config, s.Handshake) - if err != nil { - return - } - if conn == nil { - panic("unexpected nil conn") - } - s.Handler(conn) -} - -// Handler is a simple interface to a WebSocket browser client. -// It checks if Origin header is valid URL by default. -// You might want to verify websocket.Conn.Config().Origin in the func. -// If you use Server instead of Handler, you could call websocket.Origin and -// check the origin in your Handshake func. So, if you want to accept -// non-browser clients, which do not send an Origin header, set a -// Server.Handshake that does not check the origin. -type Handler func(*Conn) - -func checkOrigin(config *Config, req *http.Request) (err error) { - config.Origin, err = Origin(config, req) - if err == nil && config.Origin == nil { - return fmt.Errorf("null origin") - } - return err -} - -// ServeHTTP implements the http.Handler interface for a WebSocket -func (h Handler) ServeHTTP(w http.ResponseWriter, req *http.Request) { - s := Server{Handler: h, Handshake: checkOrigin} - s.serveWebSocket(w, req) -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/stub.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/stub.go new file mode 100644 index 00000000000..b860854e6e8 --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/stub.go @@ -0,0 +1,120 @@ +// Code generated by depstubber. DO NOT EDIT. +// This is a simple stub for golang.org/x/net/websocket, strictly for use in testing. + +// See the LICENSE file for information about the licensing of the original library. +// Source: golang.org/x/net/websocket (exports: ; functions: Dial,NewConfig,DialConfig) + +// Package websocket is a stub of golang.org/x/net/websocket, generated by depstubber. +package websocket + +import ( + tls "crypto/tls" + io "io" + net "net" + http "net/http" + url "net/url" + time "time" +) + +type Config struct { + Location *url.URL + Origin *url.URL + Protocol []string + Version int + TlsConfig *tls.Config + Header http.Header + Dialer *net.Dialer +} + +type Conn struct { + PayloadType byte + MaxPayloadBytes int +} + +func (_ Conn) HandleFrame(_ interface{}) (interface{}, error) { + return nil, nil +} + +func (_ Conn) HeaderReader() io.Reader { + return nil +} + +func (_ Conn) Len() int { + return 0 +} + +func (_ Conn) NewFrameReader() (interface{}, error) { + return nil, nil +} + +func (_ Conn) NewFrameWriter(_ byte) (interface{}, error) { + return nil, nil +} + +func (_ Conn) TrailerReader() io.Reader { + return nil +} + +func (_ Conn) WriteClose(_ int) error { + return nil +} + +func (_ *Conn) Close() error { + return nil +} + +func (_ *Conn) Config() *Config { + return nil +} + +func (_ *Conn) IsClientConn() bool { + return false +} + +func (_ *Conn) IsServerConn() bool { + return false +} + +func (_ *Conn) LocalAddr() net.Addr { + return nil +} + +func (_ *Conn) Read(_ []byte) (int, error) { + return 0, nil +} + +func (_ *Conn) RemoteAddr() net.Addr { + return nil +} + +func (_ *Conn) Request() *http.Request { + return nil +} + +func (_ *Conn) SetDeadline(_ time.Time) error { + return nil +} + +func (_ *Conn) SetReadDeadline(_ time.Time) error { + return nil +} + +func (_ *Conn) SetWriteDeadline(_ time.Time) error { + return nil +} + +func (_ *Conn) Write(_ []byte) (int, error) { + return 0, nil +} + +func Dial(_ string, _ string, _ string) (*Conn, error) { + return nil, nil +} + +func DialConfig(_ *Config) (*Conn, error) { + return nil, nil +} + +func NewConfig(_ string, _ string) (*Config, error) { + return nil, nil +} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/websocket.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/websocket.go deleted file mode 100644 index 6c45c735296..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/golang.org/x/net/websocket/websocket.go +++ /dev/null @@ -1,451 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package websocket implements a client and server for the WebSocket protocol -// as specified in RFC 6455. -// -// This package currently lacks some features found in alternative -// and more actively maintained WebSocket packages: -// -// https://godoc.org/github.com/gorilla/websocket -// https://godoc.org/nhooyr.io/websocket -package websocket // import "golang.org/x/net/websocket" - -import ( - "bufio" - "crypto/tls" - "encoding/json" - "errors" - "io" - "io/ioutil" - "net" - "net/http" - "net/url" - "sync" - "time" -) - -const ( - ProtocolVersionHybi13 = 13 - ProtocolVersionHybi = ProtocolVersionHybi13 - SupportedProtocolVersion = "13" - - ContinuationFrame = 0 - TextFrame = 1 - BinaryFrame = 2 - CloseFrame = 8 - PingFrame = 9 - PongFrame = 10 - UnknownFrame = 255 - - DefaultMaxPayloadBytes = 32 << 20 // 32MB -) - -// ProtocolError represents WebSocket protocol errors. -type ProtocolError struct { - ErrorString string -} - -func (err *ProtocolError) Error() string { return err.ErrorString } - -var ( - ErrBadProtocolVersion = &ProtocolError{"bad protocol version"} - ErrBadScheme = &ProtocolError{"bad scheme"} - ErrBadStatus = &ProtocolError{"bad status"} - ErrBadUpgrade = &ProtocolError{"missing or bad upgrade"} - ErrBadWebSocketOrigin = &ProtocolError{"missing or bad WebSocket-Origin"} - ErrBadWebSocketLocation = &ProtocolError{"missing or bad WebSocket-Location"} - ErrBadWebSocketProtocol = &ProtocolError{"missing or bad WebSocket-Protocol"} - ErrBadWebSocketVersion = &ProtocolError{"missing or bad WebSocket Version"} - ErrChallengeResponse = &ProtocolError{"mismatch challenge/response"} - ErrBadFrame = &ProtocolError{"bad frame"} - ErrBadFrameBoundary = &ProtocolError{"not on frame boundary"} - ErrNotWebSocket = &ProtocolError{"not websocket protocol"} - ErrBadRequestMethod = &ProtocolError{"bad method"} - ErrNotSupported = &ProtocolError{"not supported"} -) - -// ErrFrameTooLarge is returned by Codec's Receive method if payload size -// exceeds limit set by Conn.MaxPayloadBytes -var ErrFrameTooLarge = errors.New("websocket: frame payload size exceeds limit") - -// Addr is an implementation of net.Addr for WebSocket. -type Addr struct { - *url.URL -} - -// Network returns the network type for a WebSocket, "websocket". -func (addr *Addr) Network() string { return "websocket" } - -// Config is a WebSocket configuration -type Config struct { - // A WebSocket server address. - Location *url.URL - - // A Websocket client origin. - Origin *url.URL - - // WebSocket subprotocols. - Protocol []string - - // WebSocket protocol version. - Version int - - // TLS config for secure WebSocket (wss). - TlsConfig *tls.Config - - // Additional header fields to be sent in WebSocket opening handshake. - Header http.Header - - // Dialer used when opening websocket connections. - Dialer *net.Dialer - - handshakeData map[string]string -} - -// serverHandshaker is an interface to handle WebSocket server side handshake. -type serverHandshaker interface { - // ReadHandshake reads handshake request message from client. - // Returns http response code and error if any. - ReadHandshake(buf *bufio.Reader, req *http.Request) (code int, err error) - - // AcceptHandshake accepts the client handshake request and sends - // handshake response back to client. - AcceptHandshake(buf *bufio.Writer) (err error) - - // NewServerConn creates a new WebSocket connection. - NewServerConn(buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) (conn *Conn) -} - -// frameReader is an interface to read a WebSocket frame. -type frameReader interface { - // Reader is to read payload of the frame. - io.Reader - - // PayloadType returns payload type. - PayloadType() byte - - // HeaderReader returns a reader to read header of the frame. - HeaderReader() io.Reader - - // TrailerReader returns a reader to read trailer of the frame. - // If it returns nil, there is no trailer in the frame. - TrailerReader() io.Reader - - // Len returns total length of the frame, including header and trailer. - Len() int -} - -// frameReaderFactory is an interface to creates new frame reader. -type frameReaderFactory interface { - NewFrameReader() (r frameReader, err error) -} - -// frameWriter is an interface to write a WebSocket frame. -type frameWriter interface { - // Writer is to write payload of the frame. - io.WriteCloser -} - -// frameWriterFactory is an interface to create new frame writer. -type frameWriterFactory interface { - NewFrameWriter(payloadType byte) (w frameWriter, err error) -} - -type frameHandler interface { - HandleFrame(frame frameReader) (r frameReader, err error) - WriteClose(status int) (err error) -} - -// Conn represents a WebSocket connection. -// -// Multiple goroutines may invoke methods on a Conn simultaneously. -type Conn struct { - config *Config - request *http.Request - - buf *bufio.ReadWriter - rwc io.ReadWriteCloser - - rio sync.Mutex - frameReaderFactory - frameReader - - wio sync.Mutex - frameWriterFactory - - frameHandler - PayloadType byte - defaultCloseStatus int - - // MaxPayloadBytes limits the size of frame payload received over Conn - // by Codec's Receive method. If zero, DefaultMaxPayloadBytes is used. - MaxPayloadBytes int -} - -// Read implements the io.Reader interface: -// it reads data of a frame from the WebSocket connection. -// if msg is not large enough for the frame data, it fills the msg and next Read -// will read the rest of the frame data. -// it reads Text frame or Binary frame. -func (ws *Conn) Read(msg []byte) (n int, err error) { - ws.rio.Lock() - defer ws.rio.Unlock() -again: - if ws.frameReader == nil { - frame, err := ws.frameReaderFactory.NewFrameReader() - if err != nil { - return 0, err - } - ws.frameReader, err = ws.frameHandler.HandleFrame(frame) - if err != nil { - return 0, err - } - if ws.frameReader == nil { - goto again - } - } - n, err = ws.frameReader.Read(msg) - if err == io.EOF { - if trailer := ws.frameReader.TrailerReader(); trailer != nil { - io.Copy(ioutil.Discard, trailer) - } - ws.frameReader = nil - goto again - } - return n, err -} - -// Write implements the io.Writer interface: -// it writes data as a frame to the WebSocket connection. -func (ws *Conn) Write(msg []byte) (n int, err error) { - ws.wio.Lock() - defer ws.wio.Unlock() - w, err := ws.frameWriterFactory.NewFrameWriter(ws.PayloadType) - if err != nil { - return 0, err - } - n, err = w.Write(msg) - w.Close() - return n, err -} - -// Close implements the io.Closer interface. -func (ws *Conn) Close() error { - err := ws.frameHandler.WriteClose(ws.defaultCloseStatus) - err1 := ws.rwc.Close() - if err != nil { - return err - } - return err1 -} - -// IsClientConn reports whether ws is a client-side connection. -func (ws *Conn) IsClientConn() bool { return ws.request == nil } - -// IsServerConn reports whether ws is a server-side connection. -func (ws *Conn) IsServerConn() bool { return ws.request != nil } - -// LocalAddr returns the WebSocket Origin for the connection for client, or -// the WebSocket location for server. -func (ws *Conn) LocalAddr() net.Addr { - if ws.IsClientConn() { - return &Addr{ws.config.Origin} - } - return &Addr{ws.config.Location} -} - -// RemoteAddr returns the WebSocket location for the connection for client, or -// the Websocket Origin for server. -func (ws *Conn) RemoteAddr() net.Addr { - if ws.IsClientConn() { - return &Addr{ws.config.Location} - } - return &Addr{ws.config.Origin} -} - -var errSetDeadline = errors.New("websocket: cannot set deadline: not using a net.Conn") - -// SetDeadline sets the connection's network read & write deadlines. -func (ws *Conn) SetDeadline(t time.Time) error { - if conn, ok := ws.rwc.(net.Conn); ok { - return conn.SetDeadline(t) - } - return errSetDeadline -} - -// SetReadDeadline sets the connection's network read deadline. -func (ws *Conn) SetReadDeadline(t time.Time) error { - if conn, ok := ws.rwc.(net.Conn); ok { - return conn.SetReadDeadline(t) - } - return errSetDeadline -} - -// SetWriteDeadline sets the connection's network write deadline. -func (ws *Conn) SetWriteDeadline(t time.Time) error { - if conn, ok := ws.rwc.(net.Conn); ok { - return conn.SetWriteDeadline(t) - } - return errSetDeadline -} - -// Config returns the WebSocket config. -func (ws *Conn) Config() *Config { return ws.config } - -// Request returns the http request upgraded to the WebSocket. -// It is nil for client side. -func (ws *Conn) Request() *http.Request { return ws.request } - -// Codec represents a symmetric pair of functions that implement a codec. -type Codec struct { - Marshal func(v interface{}) (data []byte, payloadType byte, err error) - Unmarshal func(data []byte, payloadType byte, v interface{}) (err error) -} - -// Send sends v marshaled by cd.Marshal as single frame to ws. -func (cd Codec) Send(ws *Conn, v interface{}) (err error) { - data, payloadType, err := cd.Marshal(v) - if err != nil { - return err - } - ws.wio.Lock() - defer ws.wio.Unlock() - w, err := ws.frameWriterFactory.NewFrameWriter(payloadType) - if err != nil { - return err - } - _, err = w.Write(data) - w.Close() - return err -} - -// Receive receives single frame from ws, unmarshaled by cd.Unmarshal and stores -// in v. The whole frame payload is read to an in-memory buffer; max size of -// payload is defined by ws.MaxPayloadBytes. If frame payload size exceeds -// limit, ErrFrameTooLarge is returned; in this case frame is not read off wire -// completely. The next call to Receive would read and discard leftover data of -// previous oversized frame before processing next frame. -func (cd Codec) Receive(ws *Conn, v interface{}) (err error) { - ws.rio.Lock() - defer ws.rio.Unlock() - if ws.frameReader != nil { - _, err = io.Copy(ioutil.Discard, ws.frameReader) - if err != nil { - return err - } - ws.frameReader = nil - } -again: - frame, err := ws.frameReaderFactory.NewFrameReader() - if err != nil { - return err - } - frame, err = ws.frameHandler.HandleFrame(frame) - if err != nil { - return err - } - if frame == nil { - goto again - } - maxPayloadBytes := ws.MaxPayloadBytes - if maxPayloadBytes == 0 { - maxPayloadBytes = DefaultMaxPayloadBytes - } - if hf, ok := frame.(*hybiFrameReader); ok && hf.header.Length > int64(maxPayloadBytes) { - // payload size exceeds limit, no need to call Unmarshal - // - // set frameReader to current oversized frame so that - // the next call to this function can drain leftover - // data before processing the next frame - ws.frameReader = frame - return ErrFrameTooLarge - } - payloadType := frame.PayloadType() - data, err := ioutil.ReadAll(frame) - if err != nil { - return err - } - return cd.Unmarshal(data, payloadType, v) -} - -func marshal(v interface{}) (msg []byte, payloadType byte, err error) { - switch data := v.(type) { - case string: - return []byte(data), TextFrame, nil - case []byte: - return data, BinaryFrame, nil - } - return nil, UnknownFrame, ErrNotSupported -} - -func unmarshal(msg []byte, payloadType byte, v interface{}) (err error) { - switch data := v.(type) { - case *string: - *data = string(msg) - return nil - case *[]byte: - *data = msg - return nil - } - return ErrNotSupported -} - -/* -Message is a codec to send/receive text/binary data in a frame on WebSocket connection. -To send/receive text frame, use string type. -To send/receive binary frame, use []byte type. - -Trivial usage: - - import "websocket" - - // receive text frame - var message string - websocket.Message.Receive(ws, &message) - - // send text frame - message = "hello" - websocket.Message.Send(ws, message) - - // receive binary frame - var data []byte - websocket.Message.Receive(ws, &data) - - // send binary frame - data = []byte{0, 1, 2} - websocket.Message.Send(ws, data) - -*/ -var Message = Codec{marshal, unmarshal} - -func jsonMarshal(v interface{}) (msg []byte, payloadType byte, err error) { - msg, err = json.Marshal(v) - return msg, TextFrame, err -} - -func jsonUnmarshal(msg []byte, payloadType byte, v interface{}) (err error) { - return json.Unmarshal(msg, v) -} - -/* -JSON is a codec to send/receive JSON data in a frame from a WebSocket connection. - -Trivial usage: - - import "websocket" - - type T struct { - Msg string - Count int - } - - // receive JSON type T - var data T - websocket.JSON.Receive(ws, &data) - - // send JSON type T - websocket.JSON.Send(ws, data) -*/ -var JSON = Codec{jsonMarshal, jsonUnmarshal} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/modules.txt b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/modules.txt index 6551554790e..319b30b771b 100644 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/modules.txt +++ b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/modules.txt @@ -1,30 +1,15 @@ -# github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee -github.com/gobwas/httphead -# github.com/gobwas/pool v0.2.0 -github.com/gobwas/pool -github.com/gobwas/pool/internal/pmath -github.com/gobwas/pool/pbufio # github.com/gobwas/ws v1.0.3 ## explicit github.com/gobwas/ws # github.com/gorilla/websocket v1.4.2 ## explicit github.com/gorilla/websocket -# github.com/klauspost/compress v1.10.3 -github.com/klauspost/compress/flate -# github.com/sacOO7/go-logger v0.0.0-20180719173527-9ac9add5a50d -## explicit -github.com/sacOO7/go-logger # github.com/sacOO7/gowebsocket v0.0.0-20180719182212-1436bb906a4e ## explicit github.com/sacOO7/gowebsocket # golang.org/x/net v0.0.0-20200421231249-e086a090c8fd ## explicit -golang.org/x/net/websocket +golang.org/x/net # nhooyr.io/websocket v1.8.5 ## explicit nhooyr.io/websocket -nhooyr.io/websocket/internal/bpool -nhooyr.io/websocket/internal/errd -nhooyr.io/websocket/internal/wsjs -nhooyr.io/websocket/internal/xsync diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/.gitignore b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/.gitignore deleted file mode 100644 index 6961e5c894a..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/.gitignore +++ /dev/null @@ -1 +0,0 @@ -websocket.test diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/.travis.yml b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/.travis.yml deleted file mode 100644 index 41d3c201468..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/.travis.yml +++ /dev/null @@ -1,40 +0,0 @@ -language: go -go: 1.x -dist: bionic - -env: - global: - - SHFMT_URL=https://github.com/mvdan/sh/releases/download/v3.0.1/shfmt_v3.0.1_linux_amd64 - - GOFLAGS="-mod=readonly" - -jobs: - include: - - name: Format - before_script: - - sudo apt-get install -y npm - - sudo npm install -g prettier - - sudo curl -L "$SHFMT_URL" > /usr/local/bin/shfmt && sudo chmod +x /usr/local/bin/shfmt - - go get golang.org/x/tools/cmd/stringer - - go get golang.org/x/tools/cmd/goimports - script: make -j16 fmt - - name: Lint - before_script: - - sudo apt-get install -y shellcheck - - go get golang.org/x/lint/golint - script: make -j16 lint - - name: Test - before_script: - - sudo apt-get install -y chromium-browser - - go get github.com/agnivade/wasmbrowsertest - - go get github.com/mattn/goveralls - script: make -j16 test - -addons: - apt: - update: true - -cache: - npm: true - directories: - - ~/.cache - - ~/gopath/pkg diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/LICENSE.txt b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/LICENSE similarity index 100% rename from ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/LICENSE.txt rename to ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/LICENSE diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/Makefile b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/Makefile deleted file mode 100644 index f9f31c49f1c..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -all: fmt lint test - -.SILENT: - -include ci/fmt.mk -include ci/lint.mk -include ci/test.mk diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/README.md b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/README.md deleted file mode 100644 index 14c392935e1..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/README.md +++ /dev/null @@ -1,132 +0,0 @@ -# websocket - -[![godoc](https://godoc.org/nhooyr.io/websocket?status.svg)](https://pkg.go.dev/nhooyr.io/websocket) - -websocket is a minimal and idiomatic WebSocket library for Go. - -## Install - -```bash -go get nhooyr.io/websocket -``` - -## Features - -- Minimal and idiomatic API -- First class [context.Context](https://blog.golang.org/context) support -- Fully passes the WebSocket [autobahn-testsuite](https://github.com/crossbario/autobahn-testsuite) -- Thorough tests with [90% coverage](https://coveralls.io/github/nhooyr/websocket) -- [Single dependency](https://pkg.go.dev/nhooyr.io/websocket?tab=imports) -- JSON and protobuf helpers in the [wsjson](https://pkg.go.dev/nhooyr.io/websocket/wsjson) and [wspb](https://pkg.go.dev/nhooyr.io/websocket/wspb) subpackages -- Zero alloc reads and writes -- Concurrent writes -- [Close handshake](https://pkg.go.dev/nhooyr.io/websocket#Conn.Close) -- [net.Conn](https://pkg.go.dev/nhooyr.io/websocket#NetConn) wrapper -- [Ping pong](https://pkg.go.dev/nhooyr.io/websocket#Conn.Ping) API -- [RFC 7692](https://tools.ietf.org/html/rfc7692) permessage-deflate compression -- Compile to [Wasm](https://pkg.go.dev/nhooyr.io/websocket#hdr-Wasm) - -## Roadmap - -- [ ] HTTP/2 [#4](https://github.com/nhooyr/websocket/issues/4) - -## Examples - -For a production quality example that demonstrates the complete API, see the -[echo example](./examples/echo). - -For a full stack example, see the [chat example](./examples/chat). - -### Server - -```go -http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) { - c, err := websocket.Accept(w, r, nil) - if err != nil { - // ... - } - defer c.Close(websocket.StatusInternalError, "the sky is falling") - - ctx, cancel := context.WithTimeout(r.Context(), time.Second*10) - defer cancel() - - var v interface{} - err = wsjson.Read(ctx, c, &v) - if err != nil { - // ... - } - - log.Printf("received: %v", v) - - c.Close(websocket.StatusNormalClosure, "") -}) -``` - -### Client - -```go -ctx, cancel := context.WithTimeout(context.Background(), time.Minute) -defer cancel() - -c, _, err := websocket.Dial(ctx, "ws://localhost:8080", nil) -if err != nil { - // ... -} -defer c.Close(websocket.StatusInternalError, "the sky is falling") - -err = wsjson.Write(ctx, c, "hi") -if err != nil { - // ... -} - -c.Close(websocket.StatusNormalClosure, "") -``` - -## Comparison - -### gorilla/websocket - -Advantages of [gorilla/websocket](https://github.com/gorilla/websocket): - -- Mature and widely used -- [Prepared writes](https://pkg.go.dev/github.com/gorilla/websocket#PreparedMessage) -- Configurable [buffer sizes](https://pkg.go.dev/github.com/gorilla/websocket#hdr-Buffers) - -Advantages of nhooyr.io/websocket: - -- Minimal and idiomatic API - - Compare godoc of [nhooyr.io/websocket](https://pkg.go.dev/nhooyr.io/websocket) with [gorilla/websocket](https://pkg.go.dev/github.com/gorilla/websocket) side by side. -- [net.Conn](https://pkg.go.dev/nhooyr.io/websocket#NetConn) wrapper -- Zero alloc reads and writes ([gorilla/websocket#535](https://github.com/gorilla/websocket/issues/535)) -- Full [context.Context](https://blog.golang.org/context) support -- Dial uses [net/http.Client](https://golang.org/pkg/net/http/#Client) - - Will enable easy HTTP/2 support in the future - - Gorilla writes directly to a net.Conn and so duplicates features of net/http.Client. -- Concurrent writes -- Close handshake ([gorilla/websocket#448](https://github.com/gorilla/websocket/issues/448)) -- Idiomatic [ping pong](https://pkg.go.dev/nhooyr.io/websocket#Conn.Ping) API - - Gorilla requires registering a pong callback before sending a Ping -- Can target Wasm ([gorilla/websocket#432](https://github.com/gorilla/websocket/issues/432)) -- Transparent message buffer reuse with [wsjson](https://pkg.go.dev/nhooyr.io/websocket/wsjson) and [wspb](https://pkg.go.dev/nhooyr.io/websocket/wspb) subpackages -- [1.75x](https://github.com/nhooyr/websocket/releases/tag/v1.7.4) faster WebSocket masking implementation in pure Go - - Gorilla's implementation is slower and uses [unsafe](https://golang.org/pkg/unsafe/). -- Full [permessage-deflate](https://tools.ietf.org/html/rfc7692) compression extension support - - Gorilla only supports no context takeover mode - - We use a vendored [klauspost/compress](https://github.com/klauspost/compress) for much lower memory usage ([gorilla/websocket#203](https://github.com/gorilla/websocket/issues/203)) -- [CloseRead](https://pkg.go.dev/nhooyr.io/websocket#Conn.CloseRead) helper ([gorilla/websocket#492](https://github.com/gorilla/websocket/issues/492)) -- Actively maintained ([gorilla/websocket#370](https://github.com/gorilla/websocket/issues/370)) - -#### golang.org/x/net/websocket - -[golang.org/x/net/websocket](https://pkg.go.dev/golang.org/x/net/websocket) is deprecated. -See [golang/go/issues/18152](https://github.com/golang/go/issues/18152). - -The [net.Conn](https://pkg.go.dev/nhooyr.io/websocket#NetConn) can help in transitioning -to nhooyr.io/websocket. - -#### gobwas/ws - -[gobwas/ws](https://github.com/gobwas/ws) has an extremely flexible API that allows it to be used -in an event driven style for performance. See the author's [blog post](https://medium.freecodecamp.org/million-websockets-and-go-cc58418460bb). - -However when writing idiomatic Go, nhooyr.io/websocket will be faster and easier to use. diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/accept.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/accept.go deleted file mode 100644 index 6bed54da028..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/accept.go +++ /dev/null @@ -1,365 +0,0 @@ -// +build !js - -package websocket - -import ( - "bytes" - "crypto/sha1" - "encoding/base64" - "errors" - "fmt" - "io" - "log" - "net/http" - "net/textproto" - "net/url" - "path/filepath" - "strings" - - "nhooyr.io/websocket/internal/errd" -) - -// AcceptOptions represents Accept's options. -type AcceptOptions struct { - // Subprotocols lists the WebSocket subprotocols that Accept will negotiate with the client. - // The empty subprotocol will always be negotiated as per RFC 6455. If you would like to - // reject it, close the connection when c.Subprotocol() == "". - Subprotocols []string - - // InsecureSkipVerify is used to disable Accept's origin verification behaviour. - // - // Deprecated: Use OriginPatterns with a match all pattern of * instead to control - // origin authorization yourself. - InsecureSkipVerify bool - - // OriginPatterns lists the host patterns for authorized origins. - // The request host is always authorized. - // Use this to enable cross origin WebSockets. - // - // i.e javascript running on example.com wants to access a WebSocket server at chat.example.com. - // In such a case, example.com is the origin and chat.example.com is the request host. - // One would set this field to []string{"example.com"} to authorize example.com to connect. - // - // Each pattern is matched case insensitively against the request origin host - // with filepath.Match. - // See https://golang.org/pkg/path/filepath/#Match - // - // Please ensure you understand the ramifications of enabling this. - // If used incorrectly your WebSocket server will be open to CSRF attacks. - OriginPatterns []string - - // CompressionMode controls the compression mode. - // Defaults to CompressionNoContextTakeover. - // - // See docs on CompressionMode for details. - CompressionMode CompressionMode - - // CompressionThreshold controls the minimum size of a message before compression is applied. - // - // Defaults to 512 bytes for CompressionNoContextTakeover and 128 bytes - // for CompressionContextTakeover. - CompressionThreshold int -} - -// Accept accepts a WebSocket handshake from a client and upgrades the -// the connection to a WebSocket. -// -// Accept will not allow cross origin requests by default. -// See the InsecureSkipVerify option to allow cross origin requests. -// -// Accept will write a response to w on all errors. -func Accept(w http.ResponseWriter, r *http.Request, opts *AcceptOptions) (*Conn, error) { - return accept(w, r, opts) -} - -func accept(w http.ResponseWriter, r *http.Request, opts *AcceptOptions) (_ *Conn, err error) { - defer errd.Wrap(&err, "failed to accept WebSocket connection") - - if opts == nil { - opts = &AcceptOptions{} - } - opts = &*opts - - errCode, err := verifyClientRequest(w, r) - if err != nil { - http.Error(w, err.Error(), errCode) - return nil, err - } - - if !opts.InsecureSkipVerify { - err = authenticateOrigin(r, opts.OriginPatterns) - if err != nil { - if errors.Is(err, filepath.ErrBadPattern) { - log.Printf("websocket: %v", err) - err = errors.New(http.StatusText(http.StatusForbidden)) - } - http.Error(w, err.Error(), http.StatusForbidden) - return nil, err - } - } - - hj, ok := w.(http.Hijacker) - if !ok { - err = errors.New("http.ResponseWriter does not implement http.Hijacker") - http.Error(w, http.StatusText(http.StatusNotImplemented), http.StatusNotImplemented) - return nil, err - } - - w.Header().Set("Upgrade", "websocket") - w.Header().Set("Connection", "Upgrade") - - key := r.Header.Get("Sec-WebSocket-Key") - w.Header().Set("Sec-WebSocket-Accept", secWebSocketAccept(key)) - - subproto := selectSubprotocol(r, opts.Subprotocols) - if subproto != "" { - w.Header().Set("Sec-WebSocket-Protocol", subproto) - } - - copts, err := acceptCompression(r, w, opts.CompressionMode) - if err != nil { - return nil, err - } - - w.WriteHeader(http.StatusSwitchingProtocols) - - netConn, brw, err := hj.Hijack() - if err != nil { - err = fmt.Errorf("failed to hijack connection: %w", err) - http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) - return nil, err - } - - // https://github.com/golang/go/issues/32314 - b, _ := brw.Reader.Peek(brw.Reader.Buffered()) - brw.Reader.Reset(io.MultiReader(bytes.NewReader(b), netConn)) - - return newConn(connConfig{ - subprotocol: w.Header().Get("Sec-WebSocket-Protocol"), - rwc: netConn, - client: false, - copts: copts, - flateThreshold: opts.CompressionThreshold, - - br: brw.Reader, - bw: brw.Writer, - }), nil -} - -func verifyClientRequest(w http.ResponseWriter, r *http.Request) (errCode int, _ error) { - if !r.ProtoAtLeast(1, 1) { - return http.StatusUpgradeRequired, fmt.Errorf("WebSocket protocol violation: handshake request must be at least HTTP/1.1: %q", r.Proto) - } - - if !headerContainsToken(r.Header, "Connection", "Upgrade") { - w.Header().Set("Connection", "Upgrade") - w.Header().Set("Upgrade", "websocket") - return http.StatusUpgradeRequired, fmt.Errorf("WebSocket protocol violation: Connection header %q does not contain Upgrade", r.Header.Get("Connection")) - } - - if !headerContainsToken(r.Header, "Upgrade", "websocket") { - w.Header().Set("Connection", "Upgrade") - w.Header().Set("Upgrade", "websocket") - return http.StatusUpgradeRequired, fmt.Errorf("WebSocket protocol violation: Upgrade header %q does not contain websocket", r.Header.Get("Upgrade")) - } - - if r.Method != "GET" { - return http.StatusMethodNotAllowed, fmt.Errorf("WebSocket protocol violation: handshake request method is not GET but %q", r.Method) - } - - if r.Header.Get("Sec-WebSocket-Version") != "13" { - w.Header().Set("Sec-WebSocket-Version", "13") - return http.StatusBadRequest, fmt.Errorf("unsupported WebSocket protocol version (only 13 is supported): %q", r.Header.Get("Sec-WebSocket-Version")) - } - - if r.Header.Get("Sec-WebSocket-Key") == "" { - return http.StatusBadRequest, errors.New("WebSocket protocol violation: missing Sec-WebSocket-Key") - } - - return 0, nil -} - -func authenticateOrigin(r *http.Request, originHosts []string) error { - origin := r.Header.Get("Origin") - if origin == "" { - return nil - } - - u, err := url.Parse(origin) - if err != nil { - return fmt.Errorf("failed to parse Origin header %q: %w", origin, err) - } - - if strings.EqualFold(r.Host, u.Host) { - return nil - } - - for _, hostPattern := range originHosts { - matched, err := match(hostPattern, u.Host) - if err != nil { - return fmt.Errorf("failed to parse filepath pattern %q: %w", hostPattern, err) - } - if matched { - return nil - } - } - return fmt.Errorf("request Origin %q is not authorized for Host %q", origin, r.Host) -} - -func match(pattern, s string) (bool, error) { - return filepath.Match(strings.ToLower(pattern), strings.ToLower(s)) -} - -func selectSubprotocol(r *http.Request, subprotocols []string) string { - cps := headerTokens(r.Header, "Sec-WebSocket-Protocol") - for _, sp := range subprotocols { - for _, cp := range cps { - if strings.EqualFold(sp, cp) { - return cp - } - } - } - return "" -} - -func acceptCompression(r *http.Request, w http.ResponseWriter, mode CompressionMode) (*compressionOptions, error) { - if mode == CompressionDisabled { - return nil, nil - } - - for _, ext := range websocketExtensions(r.Header) { - switch ext.name { - case "permessage-deflate": - return acceptDeflate(w, ext, mode) - // Disabled for now, see https://github.com/nhooyr/websocket/issues/218 - // case "x-webkit-deflate-frame": - // return acceptWebkitDeflate(w, ext, mode) - } - } - return nil, nil -} - -func acceptDeflate(w http.ResponseWriter, ext websocketExtension, mode CompressionMode) (*compressionOptions, error) { - copts := mode.opts() - - for _, p := range ext.params { - switch p { - case "client_no_context_takeover": - copts.clientNoContextTakeover = true - continue - case "server_no_context_takeover": - copts.serverNoContextTakeover = true - continue - } - - if strings.HasPrefix(p, "client_max_window_bits") { - // We cannot adjust the read sliding window so cannot make use of this. - continue - } - - err := fmt.Errorf("unsupported permessage-deflate parameter: %q", p) - http.Error(w, err.Error(), http.StatusBadRequest) - return nil, err - } - - copts.setHeader(w.Header()) - - return copts, nil -} - -func acceptWebkitDeflate(w http.ResponseWriter, ext websocketExtension, mode CompressionMode) (*compressionOptions, error) { - copts := mode.opts() - // The peer must explicitly request it. - copts.serverNoContextTakeover = false - - for _, p := range ext.params { - if p == "no_context_takeover" { - copts.serverNoContextTakeover = true - continue - } - - // We explicitly fail on x-webkit-deflate-frame's max_window_bits parameter instead - // of ignoring it as the draft spec is unclear. It says the server can ignore it - // but the server has no way of signalling to the client it was ignored as the parameters - // are set one way. - // Thus us ignoring it would make the client think we understood it which would cause issues. - // See https://tools.ietf.org/html/draft-tyoshino-hybi-websocket-perframe-deflate-06#section-4.1 - // - // Either way, we're only implementing this for webkit which never sends the max_window_bits - // parameter so we don't need to worry about it. - err := fmt.Errorf("unsupported x-webkit-deflate-frame parameter: %q", p) - http.Error(w, err.Error(), http.StatusBadRequest) - return nil, err - } - - s := "x-webkit-deflate-frame" - if copts.clientNoContextTakeover { - s += "; no_context_takeover" - } - w.Header().Set("Sec-WebSocket-Extensions", s) - - return copts, nil -} - -func headerContainsToken(h http.Header, key, token string) bool { - token = strings.ToLower(token) - - for _, t := range headerTokens(h, key) { - if t == token { - return true - } - } - return false -} - -type websocketExtension struct { - name string - params []string -} - -func websocketExtensions(h http.Header) []websocketExtension { - var exts []websocketExtension - extStrs := headerTokens(h, "Sec-WebSocket-Extensions") - for _, extStr := range extStrs { - if extStr == "" { - continue - } - - vals := strings.Split(extStr, ";") - for i := range vals { - vals[i] = strings.TrimSpace(vals[i]) - } - - e := websocketExtension{ - name: vals[0], - params: vals[1:], - } - - exts = append(exts, e) - } - return exts -} - -func headerTokens(h http.Header, key string) []string { - key = textproto.CanonicalMIMEHeaderKey(key) - var tokens []string - for _, v := range h[key] { - v = strings.TrimSpace(v) - for _, t := range strings.Split(v, ",") { - t = strings.ToLower(t) - t = strings.TrimSpace(t) - tokens = append(tokens, t) - } - } - return tokens -} - -var keyGUID = []byte("258EAFA5-E914-47DA-95CA-C5AB0DC85B11") - -func secWebSocketAccept(secWebSocketKey string) string { - h := sha1.New() - h.Write([]byte(secWebSocketKey)) - h.Write(keyGUID) - - return base64.StdEncoding.EncodeToString(h.Sum(nil)) -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/accept_js.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/accept_js.go deleted file mode 100644 index daad4b79fec..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/accept_js.go +++ /dev/null @@ -1,20 +0,0 @@ -package websocket - -import ( - "errors" - "net/http" -) - -// AcceptOptions represents Accept's options. -type AcceptOptions struct { - Subprotocols []string - InsecureSkipVerify bool - OriginPatterns []string - CompressionMode CompressionMode - CompressionThreshold int -} - -// Accept is stubbed out for Wasm. -func Accept(w http.ResponseWriter, r *http.Request, opts *AcceptOptions) (*Conn, error) { - return nil, errors.New("unimplemented") -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/close.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/close.go deleted file mode 100644 index 7cbc19e9def..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/close.go +++ /dev/null @@ -1,76 +0,0 @@ -package websocket - -import ( - "errors" - "fmt" -) - -// StatusCode represents a WebSocket status code. -// https://tools.ietf.org/html/rfc6455#section-7.4 -type StatusCode int - -// https://www.iana.org/assignments/websocket/websocket.xhtml#close-code-number -// -// These are only the status codes defined by the protocol. -// -// You can define custom codes in the 3000-4999 range. -// The 3000-3999 range is reserved for use by libraries, frameworks and applications. -// The 4000-4999 range is reserved for private use. -const ( - StatusNormalClosure StatusCode = 1000 - StatusGoingAway StatusCode = 1001 - StatusProtocolError StatusCode = 1002 - StatusUnsupportedData StatusCode = 1003 - - // 1004 is reserved and so unexported. - statusReserved StatusCode = 1004 - - // StatusNoStatusRcvd cannot be sent in a close message. - // It is reserved for when a close message is received without - // a status code. - StatusNoStatusRcvd StatusCode = 1005 - - // StatusAbnormalClosure is exported for use only with Wasm. - // In non Wasm Go, the returned error will indicate whether the - // connection was closed abnormally. - StatusAbnormalClosure StatusCode = 1006 - - StatusInvalidFramePayloadData StatusCode = 1007 - StatusPolicyViolation StatusCode = 1008 - StatusMessageTooBig StatusCode = 1009 - StatusMandatoryExtension StatusCode = 1010 - StatusInternalError StatusCode = 1011 - StatusServiceRestart StatusCode = 1012 - StatusTryAgainLater StatusCode = 1013 - StatusBadGateway StatusCode = 1014 - - // StatusTLSHandshake is only exported for use with Wasm. - // In non Wasm Go, the returned error will indicate whether there was - // a TLS handshake failure. - StatusTLSHandshake StatusCode = 1015 -) - -// CloseError is returned when the connection is closed with a status and reason. -// -// Use Go 1.13's errors.As to check for this error. -// Also see the CloseStatus helper. -type CloseError struct { - Code StatusCode - Reason string -} - -func (ce CloseError) Error() string { - return fmt.Sprintf("status = %v and reason = %q", ce.Code, ce.Reason) -} - -// CloseStatus is a convenience wrapper around Go 1.13's errors.As to grab -// the status code from a CloseError. -// -// -1 will be returned if the passed error is nil or not a CloseError. -func CloseStatus(err error) StatusCode { - var ce CloseError - if errors.As(err, &ce) { - return ce.Code - } - return -1 -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/close_notjs.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/close_notjs.go deleted file mode 100644 index 4251311d2e6..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/close_notjs.go +++ /dev/null @@ -1,211 +0,0 @@ -// +build !js - -package websocket - -import ( - "context" - "encoding/binary" - "errors" - "fmt" - "log" - "time" - - "nhooyr.io/websocket/internal/errd" -) - -// Close performs the WebSocket close handshake with the given status code and reason. -// -// It will write a WebSocket close frame with a timeout of 5s and then wait 5s for -// the peer to send a close frame. -// All data messages received from the peer during the close handshake will be discarded. -// -// The connection can only be closed once. Additional calls to Close -// are no-ops. -// -// The maximum length of reason must be 125 bytes. Avoid -// sending a dynamic reason. -// -// Close will unblock all goroutines interacting with the connection once -// complete. -func (c *Conn) Close(code StatusCode, reason string) error { - return c.closeHandshake(code, reason) -} - -func (c *Conn) closeHandshake(code StatusCode, reason string) (err error) { - defer errd.Wrap(&err, "failed to close WebSocket") - - writeErr := c.writeClose(code, reason) - closeHandshakeErr := c.waitCloseHandshake() - - if writeErr != nil { - return writeErr - } - - if CloseStatus(closeHandshakeErr) == -1 { - return closeHandshakeErr - } - - return nil -} - -var errAlreadyWroteClose = errors.New("already wrote close") - -func (c *Conn) writeClose(code StatusCode, reason string) error { - c.closeMu.Lock() - wroteClose := c.wroteClose - c.wroteClose = true - c.closeMu.Unlock() - if wroteClose { - return errAlreadyWroteClose - } - - ce := CloseError{ - Code: code, - Reason: reason, - } - - var p []byte - var marshalErr error - if ce.Code != StatusNoStatusRcvd { - p, marshalErr = ce.bytes() - if marshalErr != nil { - log.Printf("websocket: %v", marshalErr) - } - } - - writeErr := c.writeControl(context.Background(), opClose, p) - if CloseStatus(writeErr) != -1 { - // Not a real error if it's due to a close frame being received. - writeErr = nil - } - - // We do this after in case there was an error writing the close frame. - c.setCloseErr(fmt.Errorf("sent close frame: %w", ce)) - - if marshalErr != nil { - return marshalErr - } - return writeErr -} - -func (c *Conn) waitCloseHandshake() error { - defer c.close(nil) - - ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) - defer cancel() - - err := c.readMu.lock(ctx) - if err != nil { - return err - } - defer c.readMu.unlock() - - if c.readCloseFrameErr != nil { - return c.readCloseFrameErr - } - - for { - h, err := c.readLoop(ctx) - if err != nil { - return err - } - - for i := int64(0); i < h.payloadLength; i++ { - _, err := c.br.ReadByte() - if err != nil { - return err - } - } - } -} - -func parseClosePayload(p []byte) (CloseError, error) { - if len(p) == 0 { - return CloseError{ - Code: StatusNoStatusRcvd, - }, nil - } - - if len(p) < 2 { - return CloseError{}, fmt.Errorf("close payload %q too small, cannot even contain the 2 byte status code", p) - } - - ce := CloseError{ - Code: StatusCode(binary.BigEndian.Uint16(p)), - Reason: string(p[2:]), - } - - if !validWireCloseCode(ce.Code) { - return CloseError{}, fmt.Errorf("invalid status code %v", ce.Code) - } - - return ce, nil -} - -// See http://www.iana.org/assignments/websocket/websocket.xhtml#close-code-number -// and https://tools.ietf.org/html/rfc6455#section-7.4.1 -func validWireCloseCode(code StatusCode) bool { - switch code { - case statusReserved, StatusNoStatusRcvd, StatusAbnormalClosure, StatusTLSHandshake: - return false - } - - if code >= StatusNormalClosure && code <= StatusBadGateway { - return true - } - if code >= 3000 && code <= 4999 { - return true - } - - return false -} - -func (ce CloseError) bytes() ([]byte, error) { - p, err := ce.bytesErr() - if err != nil { - err = fmt.Errorf("failed to marshal close frame: %w", err) - ce = CloseError{ - Code: StatusInternalError, - } - p, _ = ce.bytesErr() - } - return p, err -} - -const maxCloseReason = maxControlPayload - 2 - -func (ce CloseError) bytesErr() ([]byte, error) { - if len(ce.Reason) > maxCloseReason { - return nil, fmt.Errorf("reason string max is %v but got %q with length %v", maxCloseReason, ce.Reason, len(ce.Reason)) - } - - if !validWireCloseCode(ce.Code) { - return nil, fmt.Errorf("status code %v cannot be set", ce.Code) - } - - buf := make([]byte, 2+len(ce.Reason)) - binary.BigEndian.PutUint16(buf, uint16(ce.Code)) - copy(buf[2:], ce.Reason) - return buf, nil -} - -func (c *Conn) setCloseErr(err error) { - c.closeMu.Lock() - c.setCloseErrLocked(err) - c.closeMu.Unlock() -} - -func (c *Conn) setCloseErrLocked(err error) { - if c.closeErr == nil { - c.closeErr = fmt.Errorf("WebSocket closed: %w", err) - } -} - -func (c *Conn) isClosed() bool { - select { - case <-c.closed: - return true - default: - return false - } -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/compress.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/compress.go deleted file mode 100644 index 80b46d1c1d3..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/compress.go +++ /dev/null @@ -1,39 +0,0 @@ -package websocket - -// CompressionMode represents the modes available to the deflate extension. -// See https://tools.ietf.org/html/rfc7692 -// -// A compatibility layer is implemented for the older deflate-frame extension used -// by safari. See https://tools.ietf.org/html/draft-tyoshino-hybi-websocket-perframe-deflate-06 -// It will work the same in every way except that we cannot signal to the peer we -// want to use no context takeover on our side, we can only signal that they should. -// It is however currently disabled due to Safari bugs. See https://github.com/nhooyr/websocket/issues/218 -type CompressionMode int - -const ( - // CompressionNoContextTakeover grabs a new flate.Reader and flate.Writer as needed - // for every message. This applies to both server and client side. - // - // This means less efficient compression as the sliding window from previous messages - // will not be used but the memory overhead will be lower if the connections - // are long lived and seldom used. - // - // The message will only be compressed if greater than 512 bytes. - CompressionNoContextTakeover CompressionMode = iota - - // CompressionContextTakeover uses a flate.Reader and flate.Writer per connection. - // This enables reusing the sliding window from previous messages. - // As most WebSocket protocols are repetitive, this can be very efficient. - // It carries an overhead of 8 kB for every connection compared to CompressionNoContextTakeover. - // - // If the peer negotiates NoContextTakeover on the client or server side, it will be - // used instead as this is required by the RFC. - CompressionContextTakeover - - // CompressionDisabled disables the deflate extension. - // - // Use this if you are using a predominantly binary protocol with very - // little duplication in between messages or CPU and memory are more - // important than bandwidth. - CompressionDisabled -) diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/compress_notjs.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/compress_notjs.go deleted file mode 100644 index 809a272c3d1..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/compress_notjs.go +++ /dev/null @@ -1,181 +0,0 @@ -// +build !js - -package websocket - -import ( - "io" - "net/http" - "sync" - - "github.com/klauspost/compress/flate" -) - -func (m CompressionMode) opts() *compressionOptions { - return &compressionOptions{ - clientNoContextTakeover: m == CompressionNoContextTakeover, - serverNoContextTakeover: m == CompressionNoContextTakeover, - } -} - -type compressionOptions struct { - clientNoContextTakeover bool - serverNoContextTakeover bool -} - -func (copts *compressionOptions) setHeader(h http.Header) { - s := "permessage-deflate" - if copts.clientNoContextTakeover { - s += "; client_no_context_takeover" - } - if copts.serverNoContextTakeover { - s += "; server_no_context_takeover" - } - h.Set("Sec-WebSocket-Extensions", s) -} - -// These bytes are required to get flate.Reader to return. -// They are removed when sending to avoid the overhead as -// WebSocket framing tell's when the message has ended but then -// we need to add them back otherwise flate.Reader keeps -// trying to return more bytes. -const deflateMessageTail = "\x00\x00\xff\xff" - -type trimLastFourBytesWriter struct { - w io.Writer - tail []byte -} - -func (tw *trimLastFourBytesWriter) reset() { - if tw != nil && tw.tail != nil { - tw.tail = tw.tail[:0] - } -} - -func (tw *trimLastFourBytesWriter) Write(p []byte) (int, error) { - if tw.tail == nil { - tw.tail = make([]byte, 0, 4) - } - - extra := len(tw.tail) + len(p) - 4 - - if extra <= 0 { - tw.tail = append(tw.tail, p...) - return len(p), nil - } - - // Now we need to write as many extra bytes as we can from the previous tail. - if extra > len(tw.tail) { - extra = len(tw.tail) - } - if extra > 0 { - _, err := tw.w.Write(tw.tail[:extra]) - if err != nil { - return 0, err - } - - // Shift remaining bytes in tail over. - n := copy(tw.tail, tw.tail[extra:]) - tw.tail = tw.tail[:n] - } - - // If p is less than or equal to 4 bytes, - // all of it is is part of the tail. - if len(p) <= 4 { - tw.tail = append(tw.tail, p...) - return len(p), nil - } - - // Otherwise, only the last 4 bytes are. - tw.tail = append(tw.tail, p[len(p)-4:]...) - - p = p[:len(p)-4] - n, err := tw.w.Write(p) - return n + 4, err -} - -var flateReaderPool sync.Pool - -func getFlateReader(r io.Reader, dict []byte) io.Reader { - fr, ok := flateReaderPool.Get().(io.Reader) - if !ok { - return flate.NewReaderDict(r, dict) - } - fr.(flate.Resetter).Reset(r, dict) - return fr -} - -func putFlateReader(fr io.Reader) { - flateReaderPool.Put(fr) -} - -type slidingWindow struct { - buf []byte -} - -var swPoolMu sync.RWMutex -var swPool = map[int]*sync.Pool{} - -func slidingWindowPool(n int) *sync.Pool { - swPoolMu.RLock() - p, ok := swPool[n] - swPoolMu.RUnlock() - if ok { - return p - } - - p = &sync.Pool{} - - swPoolMu.Lock() - swPool[n] = p - swPoolMu.Unlock() - - return p -} - -func (sw *slidingWindow) init(n int) { - if sw.buf != nil { - return - } - - if n == 0 { - n = 32768 - } - - p := slidingWindowPool(n) - buf, ok := p.Get().([]byte) - if ok { - sw.buf = buf[:0] - } else { - sw.buf = make([]byte, 0, n) - } -} - -func (sw *slidingWindow) close() { - if sw.buf == nil { - return - } - - swPoolMu.Lock() - swPool[cap(sw.buf)].Put(sw.buf) - swPoolMu.Unlock() - sw.buf = nil -} - -func (sw *slidingWindow) write(p []byte) { - if len(p) >= cap(sw.buf) { - sw.buf = sw.buf[:cap(sw.buf)] - p = p[len(p)-cap(sw.buf):] - copy(sw.buf, p) - return - } - - left := cap(sw.buf) - len(sw.buf) - if left < len(p) { - // We need to shift spaceNeeded bytes from the end to make room for p at the end. - spaceNeeded := len(p) - left - copy(sw.buf, sw.buf[spaceNeeded:]) - sw.buf = sw.buf[:len(sw.buf)-spaceNeeded] - } - - sw.buf = append(sw.buf, p...) -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/conn.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/conn.go deleted file mode 100644 index a41808be3fa..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/conn.go +++ /dev/null @@ -1,13 +0,0 @@ -package websocket - -// MessageType represents the type of a WebSocket message. -// See https://tools.ietf.org/html/rfc6455#section-5.6 -type MessageType int - -// MessageType constants. -const ( - // MessageText is for UTF-8 encoded text messages like JSON. - MessageText MessageType = iota + 1 - // MessageBinary is for binary messages like protobufs. - MessageBinary -) diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/conn_notjs.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/conn_notjs.go deleted file mode 100644 index bb2eb22f7db..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/conn_notjs.go +++ /dev/null @@ -1,265 +0,0 @@ -// +build !js - -package websocket - -import ( - "bufio" - "context" - "errors" - "fmt" - "io" - "runtime" - "strconv" - "sync" - "sync/atomic" -) - -// Conn represents a WebSocket connection. -// All methods may be called concurrently except for Reader and Read. -// -// You must always read from the connection. Otherwise control -// frames will not be handled. See Reader and CloseRead. -// -// Be sure to call Close on the connection when you -// are finished with it to release associated resources. -// -// On any error from any method, the connection is closed -// with an appropriate reason. -type Conn struct { - subprotocol string - rwc io.ReadWriteCloser - client bool - copts *compressionOptions - flateThreshold int - br *bufio.Reader - bw *bufio.Writer - - readTimeout chan context.Context - writeTimeout chan context.Context - - // Read state. - readMu *mu - readHeaderBuf [8]byte - readControlBuf [maxControlPayload]byte - msgReader *msgReader - readCloseFrameErr error - - // Write state. - msgWriterState *msgWriterState - writeFrameMu *mu - writeBuf []byte - writeHeaderBuf [8]byte - writeHeader header - - closed chan struct{} - closeMu sync.Mutex - closeErr error - wroteClose bool - - pingCounter int32 - activePingsMu sync.Mutex - activePings map[string]chan<- struct{} -} - -type connConfig struct { - subprotocol string - rwc io.ReadWriteCloser - client bool - copts *compressionOptions - flateThreshold int - - br *bufio.Reader - bw *bufio.Writer -} - -func newConn(cfg connConfig) *Conn { - c := &Conn{ - subprotocol: cfg.subprotocol, - rwc: cfg.rwc, - client: cfg.client, - copts: cfg.copts, - flateThreshold: cfg.flateThreshold, - - br: cfg.br, - bw: cfg.bw, - - readTimeout: make(chan context.Context), - writeTimeout: make(chan context.Context), - - closed: make(chan struct{}), - activePings: make(map[string]chan<- struct{}), - } - - c.readMu = newMu(c) - c.writeFrameMu = newMu(c) - - c.msgReader = newMsgReader(c) - - c.msgWriterState = newMsgWriterState(c) - if c.client { - c.writeBuf = extractBufioWriterBuf(c.bw, c.rwc) - } - - if c.flate() && c.flateThreshold == 0 { - c.flateThreshold = 128 - if !c.msgWriterState.flateContextTakeover() { - c.flateThreshold = 512 - } - } - - runtime.SetFinalizer(c, func(c *Conn) { - c.close(errors.New("connection garbage collected")) - }) - - go c.timeoutLoop() - - return c -} - -// Subprotocol returns the negotiated subprotocol. -// An empty string means the default protocol. -func (c *Conn) Subprotocol() string { - return c.subprotocol -} - -func (c *Conn) close(err error) { - c.closeMu.Lock() - defer c.closeMu.Unlock() - - if c.isClosed() { - return - } - c.setCloseErrLocked(err) - close(c.closed) - runtime.SetFinalizer(c, nil) - - // Have to close after c.closed is closed to ensure any goroutine that wakes up - // from the connection being closed also sees that c.closed is closed and returns - // closeErr. - c.rwc.Close() - - go func() { - c.msgWriterState.close() - - c.msgReader.close() - }() -} - -func (c *Conn) timeoutLoop() { - readCtx := context.Background() - writeCtx := context.Background() - - for { - select { - case <-c.closed: - return - - case writeCtx = <-c.writeTimeout: - case readCtx = <-c.readTimeout: - - case <-readCtx.Done(): - c.setCloseErr(fmt.Errorf("read timed out: %w", readCtx.Err())) - go c.writeError(StatusPolicyViolation, errors.New("timed out")) - case <-writeCtx.Done(): - c.close(fmt.Errorf("write timed out: %w", writeCtx.Err())) - return - } - } -} - -func (c *Conn) flate() bool { - return c.copts != nil -} - -// Ping sends a ping to the peer and waits for a pong. -// Use this to measure latency or ensure the peer is responsive. -// Ping must be called concurrently with Reader as it does -// not read from the connection but instead waits for a Reader call -// to read the pong. -// -// TCP Keepalives should suffice for most use cases. -func (c *Conn) Ping(ctx context.Context) error { - p := atomic.AddInt32(&c.pingCounter, 1) - - err := c.ping(ctx, strconv.Itoa(int(p))) - if err != nil { - return fmt.Errorf("failed to ping: %w", err) - } - return nil -} - -func (c *Conn) ping(ctx context.Context, p string) error { - pong := make(chan struct{}) - - c.activePingsMu.Lock() - c.activePings[p] = pong - c.activePingsMu.Unlock() - - defer func() { - c.activePingsMu.Lock() - delete(c.activePings, p) - c.activePingsMu.Unlock() - }() - - err := c.writeControl(ctx, opPing, []byte(p)) - if err != nil { - return err - } - - select { - case <-c.closed: - return c.closeErr - case <-ctx.Done(): - err := fmt.Errorf("failed to wait for pong: %w", ctx.Err()) - c.close(err) - return err - case <-pong: - return nil - } -} - -type mu struct { - c *Conn - ch chan struct{} -} - -func newMu(c *Conn) *mu { - return &mu{ - c: c, - ch: make(chan struct{}, 1), - } -} - -func (m *mu) forceLock() { - m.ch <- struct{}{} -} - -func (m *mu) lock(ctx context.Context) error { - select { - case <-m.c.closed: - return m.c.closeErr - case <-ctx.Done(): - err := fmt.Errorf("failed to acquire lock: %w", ctx.Err()) - m.c.close(err) - return err - case m.ch <- struct{}{}: - // To make sure the connection is certainly alive. - // As it's possible the send on m.ch was selected - // over the receive on closed. - select { - case <-m.c.closed: - // Make sure to release. - m.unlock() - return m.c.closeErr - default: - } - return nil - } -} - -func (m *mu) unlock() { - select { - case <-m.ch: - default: - } -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/dial.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/dial.go deleted file mode 100644 index 2b25e3517d6..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/dial.go +++ /dev/null @@ -1,287 +0,0 @@ -// +build !js - -package websocket - -import ( - "bufio" - "bytes" - "context" - "crypto/rand" - "encoding/base64" - "errors" - "fmt" - "io" - "io/ioutil" - "net/http" - "net/url" - "strings" - "sync" - "time" - - "nhooyr.io/websocket/internal/errd" -) - -// DialOptions represents Dial's options. -type DialOptions struct { - // HTTPClient is used for the connection. - // Its Transport must return writable bodies for WebSocket handshakes. - // http.Transport does beginning with Go 1.12. - HTTPClient *http.Client - - // HTTPHeader specifies the HTTP headers included in the handshake request. - HTTPHeader http.Header - - // Subprotocols lists the WebSocket subprotocols to negotiate with the server. - Subprotocols []string - - // CompressionMode controls the compression mode. - // Defaults to CompressionNoContextTakeover. - // - // See docs on CompressionMode for details. - CompressionMode CompressionMode - - // CompressionThreshold controls the minimum size of a message before compression is applied. - // - // Defaults to 512 bytes for CompressionNoContextTakeover and 128 bytes - // for CompressionContextTakeover. - CompressionThreshold int -} - -// Dial performs a WebSocket handshake on url. -// -// The response is the WebSocket handshake response from the server. -// You never need to close resp.Body yourself. -// -// If an error occurs, the returned response may be non nil. -// However, you can only read the first 1024 bytes of the body. -// -// This function requires at least Go 1.12 as it uses a new feature -// in net/http to perform WebSocket handshakes. -// See docs on the HTTPClient option and https://github.com/golang/go/issues/26937#issuecomment-415855861 -// -// URLs with http/https schemes will work and are interpreted as ws/wss. -func Dial(ctx context.Context, u string, opts *DialOptions) (*Conn, *http.Response, error) { - return dial(ctx, u, opts, nil) -} - -func dial(ctx context.Context, urls string, opts *DialOptions, rand io.Reader) (_ *Conn, _ *http.Response, err error) { - defer errd.Wrap(&err, "failed to WebSocket dial") - - if opts == nil { - opts = &DialOptions{} - } - - opts = &*opts - if opts.HTTPClient == nil { - opts.HTTPClient = http.DefaultClient - } - if opts.HTTPHeader == nil { - opts.HTTPHeader = http.Header{} - } - - secWebSocketKey, err := secWebSocketKey(rand) - if err != nil { - return nil, nil, fmt.Errorf("failed to generate Sec-WebSocket-Key: %w", err) - } - - var copts *compressionOptions - if opts.CompressionMode != CompressionDisabled { - copts = opts.CompressionMode.opts() - } - - resp, err := handshakeRequest(ctx, urls, opts, copts, secWebSocketKey) - if err != nil { - return nil, resp, err - } - respBody := resp.Body - resp.Body = nil - defer func() { - if err != nil { - // We read a bit of the body for easier debugging. - r := io.LimitReader(respBody, 1024) - - timer := time.AfterFunc(time.Second*3, func() { - respBody.Close() - }) - defer timer.Stop() - - b, _ := ioutil.ReadAll(r) - respBody.Close() - resp.Body = ioutil.NopCloser(bytes.NewReader(b)) - } - }() - - copts, err = verifyServerResponse(opts, copts, secWebSocketKey, resp) - if err != nil { - return nil, resp, err - } - - rwc, ok := respBody.(io.ReadWriteCloser) - if !ok { - return nil, resp, fmt.Errorf("response body is not a io.ReadWriteCloser: %T", respBody) - } - - return newConn(connConfig{ - subprotocol: resp.Header.Get("Sec-WebSocket-Protocol"), - rwc: rwc, - client: true, - copts: copts, - flateThreshold: opts.CompressionThreshold, - br: getBufioReader(rwc), - bw: getBufioWriter(rwc), - }), resp, nil -} - -func handshakeRequest(ctx context.Context, urls string, opts *DialOptions, copts *compressionOptions, secWebSocketKey string) (*http.Response, error) { - if opts.HTTPClient.Timeout > 0 { - return nil, errors.New("use context for cancellation instead of http.Client.Timeout; see https://github.com/nhooyr/websocket/issues/67") - } - - u, err := url.Parse(urls) - if err != nil { - return nil, fmt.Errorf("failed to parse url: %w", err) - } - - switch u.Scheme { - case "ws": - u.Scheme = "http" - case "wss": - u.Scheme = "https" - case "http", "https": - default: - return nil, fmt.Errorf("unexpected url scheme: %q", u.Scheme) - } - - req, _ := http.NewRequestWithContext(ctx, "GET", u.String(), nil) - req.Header = opts.HTTPHeader.Clone() - req.Header.Set("Connection", "Upgrade") - req.Header.Set("Upgrade", "websocket") - req.Header.Set("Sec-WebSocket-Version", "13") - req.Header.Set("Sec-WebSocket-Key", secWebSocketKey) - if len(opts.Subprotocols) > 0 { - req.Header.Set("Sec-WebSocket-Protocol", strings.Join(opts.Subprotocols, ",")) - } - if copts != nil { - copts.setHeader(req.Header) - } - - resp, err := opts.HTTPClient.Do(req) - if err != nil { - return nil, fmt.Errorf("failed to send handshake request: %w", err) - } - return resp, nil -} - -func secWebSocketKey(rr io.Reader) (string, error) { - if rr == nil { - rr = rand.Reader - } - b := make([]byte, 16) - _, err := io.ReadFull(rr, b) - if err != nil { - return "", fmt.Errorf("failed to read random data from rand.Reader: %w", err) - } - return base64.StdEncoding.EncodeToString(b), nil -} - -func verifyServerResponse(opts *DialOptions, copts *compressionOptions, secWebSocketKey string, resp *http.Response) (*compressionOptions, error) { - if resp.StatusCode != http.StatusSwitchingProtocols { - return nil, fmt.Errorf("expected handshake response status code %v but got %v", http.StatusSwitchingProtocols, resp.StatusCode) - } - - if !headerContainsToken(resp.Header, "Connection", "Upgrade") { - return nil, fmt.Errorf("WebSocket protocol violation: Connection header %q does not contain Upgrade", resp.Header.Get("Connection")) - } - - if !headerContainsToken(resp.Header, "Upgrade", "WebSocket") { - return nil, fmt.Errorf("WebSocket protocol violation: Upgrade header %q does not contain websocket", resp.Header.Get("Upgrade")) - } - - if resp.Header.Get("Sec-WebSocket-Accept") != secWebSocketAccept(secWebSocketKey) { - return nil, fmt.Errorf("WebSocket protocol violation: invalid Sec-WebSocket-Accept %q, key %q", - resp.Header.Get("Sec-WebSocket-Accept"), - secWebSocketKey, - ) - } - - err := verifySubprotocol(opts.Subprotocols, resp) - if err != nil { - return nil, err - } - - return verifyServerExtensions(copts, resp.Header) -} - -func verifySubprotocol(subprotos []string, resp *http.Response) error { - proto := resp.Header.Get("Sec-WebSocket-Protocol") - if proto == "" { - return nil - } - - for _, sp2 := range subprotos { - if strings.EqualFold(sp2, proto) { - return nil - } - } - - return fmt.Errorf("WebSocket protocol violation: unexpected Sec-WebSocket-Protocol from server: %q", proto) -} - -func verifyServerExtensions(copts *compressionOptions, h http.Header) (*compressionOptions, error) { - exts := websocketExtensions(h) - if len(exts) == 0 { - return nil, nil - } - - ext := exts[0] - if ext.name != "permessage-deflate" || len(exts) > 1 || copts == nil { - return nil, fmt.Errorf("WebSocket protcol violation: unsupported extensions from server: %+v", exts[1:]) - } - - copts = &*copts - - for _, p := range ext.params { - switch p { - case "client_no_context_takeover": - copts.clientNoContextTakeover = true - continue - case "server_no_context_takeover": - copts.serverNoContextTakeover = true - continue - } - - return nil, fmt.Errorf("unsupported permessage-deflate parameter: %q", p) - } - - return copts, nil -} - -var bufioReaderPool sync.Pool - -func getBufioReader(r io.Reader) *bufio.Reader { - br, ok := bufioReaderPool.Get().(*bufio.Reader) - if !ok { - return bufio.NewReader(r) - } - br.Reset(r) - return br -} - -func putBufioReader(br *bufio.Reader) { - bufioReaderPool.Put(br) -} - -var bufioWriterPool sync.Pool - -func getBufioWriter(w io.Writer) *bufio.Writer { - bw, ok := bufioWriterPool.Get().(*bufio.Writer) - if !ok { - return bufio.NewWriter(w) - } - bw.Reset(w) - return bw -} - -func putBufioWriter(bw *bufio.Writer) { - bufioWriterPool.Put(bw) -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/doc.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/doc.go deleted file mode 100644 index efa920e3b61..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/doc.go +++ /dev/null @@ -1,32 +0,0 @@ -// +build !js - -// Package websocket implements the RFC 6455 WebSocket protocol. -// -// https://tools.ietf.org/html/rfc6455 -// -// Use Dial to dial a WebSocket server. -// -// Use Accept to accept a WebSocket client. -// -// Conn represents the resulting WebSocket connection. -// -// The examples are the best way to understand how to correctly use the library. -// -// The wsjson and wspb subpackages contain helpers for JSON and protobuf messages. -// -// More documentation at https://nhooyr.io/websocket. -// -// Wasm -// -// The client side supports compiling to Wasm. -// It wraps the WebSocket browser API. -// -// See https://developer.mozilla.org/en-US/docs/Web/API/WebSocket -// -// Some important caveats to be aware of: -// -// - Accept always errors out -// - Conn.Ping is no-op -// - HTTPClient, HTTPHeader and CompressionMode in DialOptions are no-op -// - *http.Response from Dial is &http.Response{} with a 101 status code on success -package websocket // import "nhooyr.io/websocket" diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/frame.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/frame.go deleted file mode 100644 index 2a036f944ac..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/frame.go +++ /dev/null @@ -1,294 +0,0 @@ -package websocket - -import ( - "bufio" - "encoding/binary" - "fmt" - "io" - "math" - "math/bits" - - "nhooyr.io/websocket/internal/errd" -) - -// opcode represents a WebSocket opcode. -type opcode int - -// https://tools.ietf.org/html/rfc6455#section-11.8. -const ( - opContinuation opcode = iota - opText - opBinary - // 3 - 7 are reserved for further non-control frames. - _ - _ - _ - _ - _ - opClose - opPing - opPong - // 11-16 are reserved for further control frames. -) - -// header represents a WebSocket frame header. -// See https://tools.ietf.org/html/rfc6455#section-5.2. -type header struct { - fin bool - rsv1 bool - rsv2 bool - rsv3 bool - opcode opcode - - payloadLength int64 - - masked bool - maskKey uint32 -} - -// readFrameHeader reads a header from the reader. -// See https://tools.ietf.org/html/rfc6455#section-5.2. -func readFrameHeader(r *bufio.Reader, readBuf []byte) (h header, err error) { - defer errd.Wrap(&err, "failed to read frame header") - - b, err := r.ReadByte() - if err != nil { - return header{}, err - } - - h.fin = b&(1<<7) != 0 - h.rsv1 = b&(1<<6) != 0 - h.rsv2 = b&(1<<5) != 0 - h.rsv3 = b&(1<<4) != 0 - - h.opcode = opcode(b & 0xf) - - b, err = r.ReadByte() - if err != nil { - return header{}, err - } - - h.masked = b&(1<<7) != 0 - - payloadLength := b &^ (1 << 7) - switch { - case payloadLength < 126: - h.payloadLength = int64(payloadLength) - case payloadLength == 126: - _, err = io.ReadFull(r, readBuf[:2]) - h.payloadLength = int64(binary.BigEndian.Uint16(readBuf)) - case payloadLength == 127: - _, err = io.ReadFull(r, readBuf) - h.payloadLength = int64(binary.BigEndian.Uint64(readBuf)) - } - if err != nil { - return header{}, err - } - - if h.payloadLength < 0 { - return header{}, fmt.Errorf("received negative payload length: %v", h.payloadLength) - } - - if h.masked { - _, err = io.ReadFull(r, readBuf[:4]) - if err != nil { - return header{}, err - } - h.maskKey = binary.LittleEndian.Uint32(readBuf) - } - - return h, nil -} - -// maxControlPayload is the maximum length of a control frame payload. -// See https://tools.ietf.org/html/rfc6455#section-5.5. -const maxControlPayload = 125 - -// writeFrameHeader writes the bytes of the header to w. -// See https://tools.ietf.org/html/rfc6455#section-5.2 -func writeFrameHeader(h header, w *bufio.Writer, buf []byte) (err error) { - defer errd.Wrap(&err, "failed to write frame header") - - var b byte - if h.fin { - b |= 1 << 7 - } - if h.rsv1 { - b |= 1 << 6 - } - if h.rsv2 { - b |= 1 << 5 - } - if h.rsv3 { - b |= 1 << 4 - } - - b |= byte(h.opcode) - - err = w.WriteByte(b) - if err != nil { - return err - } - - lengthByte := byte(0) - if h.masked { - lengthByte |= 1 << 7 - } - - switch { - case h.payloadLength > math.MaxUint16: - lengthByte |= 127 - case h.payloadLength > 125: - lengthByte |= 126 - case h.payloadLength >= 0: - lengthByte |= byte(h.payloadLength) - } - err = w.WriteByte(lengthByte) - if err != nil { - return err - } - - switch { - case h.payloadLength > math.MaxUint16: - binary.BigEndian.PutUint64(buf, uint64(h.payloadLength)) - _, err = w.Write(buf) - case h.payloadLength > 125: - binary.BigEndian.PutUint16(buf, uint16(h.payloadLength)) - _, err = w.Write(buf[:2]) - } - if err != nil { - return err - } - - if h.masked { - binary.LittleEndian.PutUint32(buf, h.maskKey) - _, err = w.Write(buf[:4]) - if err != nil { - return err - } - } - - return nil -} - -// mask applies the WebSocket masking algorithm to p -// with the given key. -// See https://tools.ietf.org/html/rfc6455#section-5.3 -// -// The returned value is the correctly rotated key to -// to continue to mask/unmask the message. -// -// It is optimized for LittleEndian and expects the key -// to be in little endian. -// -// See https://github.com/golang/go/issues/31586 -func mask(key uint32, b []byte) uint32 { - if len(b) >= 8 { - key64 := uint64(key)<<32 | uint64(key) - - // At some point in the future we can clean these unrolled loops up. - // See https://github.com/golang/go/issues/31586#issuecomment-487436401 - - // Then we xor until b is less than 128 bytes. - for len(b) >= 128 { - v := binary.LittleEndian.Uint64(b) - binary.LittleEndian.PutUint64(b, v^key64) - v = binary.LittleEndian.Uint64(b[8:16]) - binary.LittleEndian.PutUint64(b[8:16], v^key64) - v = binary.LittleEndian.Uint64(b[16:24]) - binary.LittleEndian.PutUint64(b[16:24], v^key64) - v = binary.LittleEndian.Uint64(b[24:32]) - binary.LittleEndian.PutUint64(b[24:32], v^key64) - v = binary.LittleEndian.Uint64(b[32:40]) - binary.LittleEndian.PutUint64(b[32:40], v^key64) - v = binary.LittleEndian.Uint64(b[40:48]) - binary.LittleEndian.PutUint64(b[40:48], v^key64) - v = binary.LittleEndian.Uint64(b[48:56]) - binary.LittleEndian.PutUint64(b[48:56], v^key64) - v = binary.LittleEndian.Uint64(b[56:64]) - binary.LittleEndian.PutUint64(b[56:64], v^key64) - v = binary.LittleEndian.Uint64(b[64:72]) - binary.LittleEndian.PutUint64(b[64:72], v^key64) - v = binary.LittleEndian.Uint64(b[72:80]) - binary.LittleEndian.PutUint64(b[72:80], v^key64) - v = binary.LittleEndian.Uint64(b[80:88]) - binary.LittleEndian.PutUint64(b[80:88], v^key64) - v = binary.LittleEndian.Uint64(b[88:96]) - binary.LittleEndian.PutUint64(b[88:96], v^key64) - v = binary.LittleEndian.Uint64(b[96:104]) - binary.LittleEndian.PutUint64(b[96:104], v^key64) - v = binary.LittleEndian.Uint64(b[104:112]) - binary.LittleEndian.PutUint64(b[104:112], v^key64) - v = binary.LittleEndian.Uint64(b[112:120]) - binary.LittleEndian.PutUint64(b[112:120], v^key64) - v = binary.LittleEndian.Uint64(b[120:128]) - binary.LittleEndian.PutUint64(b[120:128], v^key64) - b = b[128:] - } - - // Then we xor until b is less than 64 bytes. - for len(b) >= 64 { - v := binary.LittleEndian.Uint64(b) - binary.LittleEndian.PutUint64(b, v^key64) - v = binary.LittleEndian.Uint64(b[8:16]) - binary.LittleEndian.PutUint64(b[8:16], v^key64) - v = binary.LittleEndian.Uint64(b[16:24]) - binary.LittleEndian.PutUint64(b[16:24], v^key64) - v = binary.LittleEndian.Uint64(b[24:32]) - binary.LittleEndian.PutUint64(b[24:32], v^key64) - v = binary.LittleEndian.Uint64(b[32:40]) - binary.LittleEndian.PutUint64(b[32:40], v^key64) - v = binary.LittleEndian.Uint64(b[40:48]) - binary.LittleEndian.PutUint64(b[40:48], v^key64) - v = binary.LittleEndian.Uint64(b[48:56]) - binary.LittleEndian.PutUint64(b[48:56], v^key64) - v = binary.LittleEndian.Uint64(b[56:64]) - binary.LittleEndian.PutUint64(b[56:64], v^key64) - b = b[64:] - } - - // Then we xor until b is less than 32 bytes. - for len(b) >= 32 { - v := binary.LittleEndian.Uint64(b) - binary.LittleEndian.PutUint64(b, v^key64) - v = binary.LittleEndian.Uint64(b[8:16]) - binary.LittleEndian.PutUint64(b[8:16], v^key64) - v = binary.LittleEndian.Uint64(b[16:24]) - binary.LittleEndian.PutUint64(b[16:24], v^key64) - v = binary.LittleEndian.Uint64(b[24:32]) - binary.LittleEndian.PutUint64(b[24:32], v^key64) - b = b[32:] - } - - // Then we xor until b is less than 16 bytes. - for len(b) >= 16 { - v := binary.LittleEndian.Uint64(b) - binary.LittleEndian.PutUint64(b, v^key64) - v = binary.LittleEndian.Uint64(b[8:16]) - binary.LittleEndian.PutUint64(b[8:16], v^key64) - b = b[16:] - } - - // Then we xor until b is less than 8 bytes. - for len(b) >= 8 { - v := binary.LittleEndian.Uint64(b) - binary.LittleEndian.PutUint64(b, v^key64) - b = b[8:] - } - } - - // Then we xor until b is less than 4 bytes. - for len(b) >= 4 { - v := binary.LittleEndian.Uint32(b) - binary.LittleEndian.PutUint32(b, v^key) - b = b[4:] - } - - // xor remaining bytes. - for i := range b { - b[i] ^= byte(key) - key = bits.RotateLeft32(key, -8) - } - - return key -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/go.mod b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/go.mod deleted file mode 100644 index 60377823cba..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/go.mod +++ /dev/null @@ -1,14 +0,0 @@ -module nhooyr.io/websocket - -go 1.13 - -require ( - github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee // indirect - github.com/gobwas/pool v0.2.0 // indirect - github.com/gobwas/ws v1.0.2 - github.com/golang/protobuf v1.3.5 - github.com/google/go-cmp v0.4.0 - github.com/gorilla/websocket v1.4.1 - github.com/klauspost/compress v1.10.3 - golang.org/x/time v0.0.0-20191024005414-555d28b269f0 -) diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/internal/bpool/bpool.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/internal/bpool/bpool.go deleted file mode 100644 index aa826fba2b1..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/internal/bpool/bpool.go +++ /dev/null @@ -1,24 +0,0 @@ -package bpool - -import ( - "bytes" - "sync" -) - -var bpool sync.Pool - -// Get returns a buffer from the pool or creates a new one if -// the pool is empty. -func Get() *bytes.Buffer { - b := bpool.Get() - if b == nil { - return &bytes.Buffer{} - } - return b.(*bytes.Buffer) -} - -// Put returns a buffer into the pool. -func Put(b *bytes.Buffer) { - b.Reset() - bpool.Put(b) -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/internal/errd/wrap.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/internal/errd/wrap.go deleted file mode 100644 index 6e779131af8..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/internal/errd/wrap.go +++ /dev/null @@ -1,14 +0,0 @@ -package errd - -import ( - "fmt" -) - -// Wrap wraps err with fmt.Errorf if err is non nil. -// Intended for use with defer and a named error return. -// Inspired by https://github.com/golang/go/issues/32676. -func Wrap(err *error, f string, v ...interface{}) { - if *err != nil { - *err = fmt.Errorf(f+": %w", append(v, *err)...) - } -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/internal/wsjs/wsjs_js.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/internal/wsjs/wsjs_js.go deleted file mode 100644 index 26ffb45625b..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/internal/wsjs/wsjs_js.go +++ /dev/null @@ -1,170 +0,0 @@ -// +build js - -// Package wsjs implements typed access to the browser javascript WebSocket API. -// -// https://developer.mozilla.org/en-US/docs/Web/API/WebSocket -package wsjs - -import ( - "syscall/js" -) - -func handleJSError(err *error, onErr func()) { - r := recover() - - if jsErr, ok := r.(js.Error); ok { - *err = jsErr - - if onErr != nil { - onErr() - } - return - } - - if r != nil { - panic(r) - } -} - -// New is a wrapper around the javascript WebSocket constructor. -func New(url string, protocols []string) (c WebSocket, err error) { - defer handleJSError(&err, func() { - c = WebSocket{} - }) - - jsProtocols := make([]interface{}, len(protocols)) - for i, p := range protocols { - jsProtocols[i] = p - } - - c = WebSocket{ - v: js.Global().Get("WebSocket").New(url, jsProtocols), - } - - c.setBinaryType("arraybuffer") - - return c, nil -} - -// WebSocket is a wrapper around a javascript WebSocket object. -type WebSocket struct { - v js.Value -} - -func (c WebSocket) setBinaryType(typ string) { - c.v.Set("binaryType", string(typ)) -} - -func (c WebSocket) addEventListener(eventType string, fn func(e js.Value)) func() { - f := js.FuncOf(func(this js.Value, args []js.Value) interface{} { - fn(args[0]) - return nil - }) - c.v.Call("addEventListener", eventType, f) - - return func() { - c.v.Call("removeEventListener", eventType, f) - f.Release() - } -} - -// CloseEvent is the type passed to a WebSocket close handler. -type CloseEvent struct { - Code uint16 - Reason string - WasClean bool -} - -// OnClose registers a function to be called when the WebSocket is closed. -func (c WebSocket) OnClose(fn func(CloseEvent)) (remove func()) { - return c.addEventListener("close", func(e js.Value) { - ce := CloseEvent{ - Code: uint16(e.Get("code").Int()), - Reason: e.Get("reason").String(), - WasClean: e.Get("wasClean").Bool(), - } - fn(ce) - }) -} - -// OnError registers a function to be called when there is an error -// with the WebSocket. -func (c WebSocket) OnError(fn func(e js.Value)) (remove func()) { - return c.addEventListener("error", fn) -} - -// MessageEvent is the type passed to a message handler. -type MessageEvent struct { - // string or []byte. - Data interface{} - - // There are more fields to the interface but we don't use them. - // See https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent -} - -// OnMessage registers a function to be called when the WebSocket receives a message. -func (c WebSocket) OnMessage(fn func(m MessageEvent)) (remove func()) { - return c.addEventListener("message", func(e js.Value) { - var data interface{} - - arrayBuffer := e.Get("data") - if arrayBuffer.Type() == js.TypeString { - data = arrayBuffer.String() - } else { - data = extractArrayBuffer(arrayBuffer) - } - - me := MessageEvent{ - Data: data, - } - fn(me) - - return - }) -} - -// Subprotocol returns the WebSocket subprotocol in use. -func (c WebSocket) Subprotocol() string { - return c.v.Get("protocol").String() -} - -// OnOpen registers a function to be called when the WebSocket is opened. -func (c WebSocket) OnOpen(fn func(e js.Value)) (remove func()) { - return c.addEventListener("open", fn) -} - -// Close closes the WebSocket with the given code and reason. -func (c WebSocket) Close(code int, reason string) (err error) { - defer handleJSError(&err, nil) - c.v.Call("close", code, reason) - return err -} - -// SendText sends the given string as a text message -// on the WebSocket. -func (c WebSocket) SendText(v string) (err error) { - defer handleJSError(&err, nil) - c.v.Call("send", v) - return err -} - -// SendBytes sends the given message as a binary message -// on the WebSocket. -func (c WebSocket) SendBytes(v []byte) (err error) { - defer handleJSError(&err, nil) - c.v.Call("send", uint8Array(v)) - return err -} - -func extractArrayBuffer(arrayBuffer js.Value) []byte { - uint8Array := js.Global().Get("Uint8Array").New(arrayBuffer) - dst := make([]byte, uint8Array.Length()) - js.CopyBytesToGo(dst, uint8Array) - return dst -} - -func uint8Array(src []byte) js.Value { - uint8Array := js.Global().Get("Uint8Array").New(len(src)) - js.CopyBytesToJS(uint8Array, src) - return uint8Array -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/internal/xsync/go.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/internal/xsync/go.go deleted file mode 100644 index 7a61f27fa2a..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/internal/xsync/go.go +++ /dev/null @@ -1,25 +0,0 @@ -package xsync - -import ( - "fmt" -) - -// Go allows running a function in another goroutine -// and waiting for its error. -func Go(fn func() error) <-chan error { - errs := make(chan error, 1) - go func() { - defer func() { - r := recover() - if r != nil { - select { - case errs <- fmt.Errorf("panic in go fn: %v", r): - default: - } - } - }() - errs <- fn() - }() - - return errs -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/internal/xsync/int64.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/internal/xsync/int64.go deleted file mode 100644 index a0c40204156..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/internal/xsync/int64.go +++ /dev/null @@ -1,23 +0,0 @@ -package xsync - -import ( - "sync/atomic" -) - -// Int64 represents an atomic int64. -type Int64 struct { - // We do not use atomic.Load/StoreInt64 since it does not - // work on 32 bit computers but we need 64 bit integers. - i atomic.Value -} - -// Load loads the int64. -func (v *Int64) Load() int64 { - i, _ := v.i.Load().(int64) - return i -} - -// Store stores the int64. -func (v *Int64) Store(i int64) { - v.i.Store(i) -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/netconn.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/netconn.go deleted file mode 100644 index 64aadf0b998..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/netconn.go +++ /dev/null @@ -1,166 +0,0 @@ -package websocket - -import ( - "context" - "fmt" - "io" - "math" - "net" - "sync" - "time" -) - -// NetConn converts a *websocket.Conn into a net.Conn. -// -// It's for tunneling arbitrary protocols over WebSockets. -// Few users of the library will need this but it's tricky to implement -// correctly and so provided in the library. -// See https://github.com/nhooyr/websocket/issues/100. -// -// Every Write to the net.Conn will correspond to a message write of -// the given type on *websocket.Conn. -// -// The passed ctx bounds the lifetime of the net.Conn. If cancelled, -// all reads and writes on the net.Conn will be cancelled. -// -// If a message is read that is not of the correct type, the connection -// will be closed with StatusUnsupportedData and an error will be returned. -// -// Close will close the *websocket.Conn with StatusNormalClosure. -// -// When a deadline is hit, the connection will be closed. This is -// different from most net.Conn implementations where only the -// reading/writing goroutines are interrupted but the connection is kept alive. -// -// The Addr methods will return a mock net.Addr that returns "websocket" for Network -// and "websocket/unknown-addr" for String. -// -// A received StatusNormalClosure or StatusGoingAway close frame will be translated to -// io.EOF when reading. -func NetConn(ctx context.Context, c *Conn, msgType MessageType) net.Conn { - nc := &netConn{ - c: c, - msgType: msgType, - } - - var cancel context.CancelFunc - nc.writeContext, cancel = context.WithCancel(ctx) - nc.writeTimer = time.AfterFunc(math.MaxInt64, cancel) - if !nc.writeTimer.Stop() { - <-nc.writeTimer.C - } - - nc.readContext, cancel = context.WithCancel(ctx) - nc.readTimer = time.AfterFunc(math.MaxInt64, cancel) - if !nc.readTimer.Stop() { - <-nc.readTimer.C - } - - return nc -} - -type netConn struct { - c *Conn - msgType MessageType - - writeTimer *time.Timer - writeContext context.Context - - readTimer *time.Timer - readContext context.Context - - readMu sync.Mutex - eofed bool - reader io.Reader -} - -var _ net.Conn = &netConn{} - -func (c *netConn) Close() error { - return c.c.Close(StatusNormalClosure, "") -} - -func (c *netConn) Write(p []byte) (int, error) { - err := c.c.Write(c.writeContext, c.msgType, p) - if err != nil { - return 0, err - } - return len(p), nil -} - -func (c *netConn) Read(p []byte) (int, error) { - c.readMu.Lock() - defer c.readMu.Unlock() - - if c.eofed { - return 0, io.EOF - } - - if c.reader == nil { - typ, r, err := c.c.Reader(c.readContext) - if err != nil { - switch CloseStatus(err) { - case StatusNormalClosure, StatusGoingAway: - c.eofed = true - return 0, io.EOF - } - return 0, err - } - if typ != c.msgType { - err := fmt.Errorf("unexpected frame type read (expected %v): %v", c.msgType, typ) - c.c.Close(StatusUnsupportedData, err.Error()) - return 0, err - } - c.reader = r - } - - n, err := c.reader.Read(p) - if err == io.EOF { - c.reader = nil - err = nil - } - return n, err -} - -type websocketAddr struct { -} - -func (a websocketAddr) Network() string { - return "websocket" -} - -func (a websocketAddr) String() string { - return "websocket/unknown-addr" -} - -func (c *netConn) RemoteAddr() net.Addr { - return websocketAddr{} -} - -func (c *netConn) LocalAddr() net.Addr { - return websocketAddr{} -} - -func (c *netConn) SetDeadline(t time.Time) error { - c.SetWriteDeadline(t) - c.SetReadDeadline(t) - return nil -} - -func (c *netConn) SetWriteDeadline(t time.Time) error { - if t.IsZero() { - c.writeTimer.Stop() - } else { - c.writeTimer.Reset(t.Sub(time.Now())) - } - return nil -} - -func (c *netConn) SetReadDeadline(t time.Time) error { - if t.IsZero() { - c.readTimer.Stop() - } else { - c.readTimer.Reset(t.Sub(time.Now())) - } - return nil -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/read.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/read.go deleted file mode 100644 index afd08cc7cde..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/read.go +++ /dev/null @@ -1,471 +0,0 @@ -// +build !js - -package websocket - -import ( - "bufio" - "context" - "errors" - "fmt" - "io" - "io/ioutil" - "strings" - "time" - - "nhooyr.io/websocket/internal/errd" - "nhooyr.io/websocket/internal/xsync" -) - -// Reader reads from the connection until until there is a WebSocket -// data message to be read. It will handle ping, pong and close frames as appropriate. -// -// It returns the type of the message and an io.Reader to read it. -// The passed context will also bound the reader. -// Ensure you read to EOF otherwise the connection will hang. -// -// Call CloseRead if you do not expect any data messages from the peer. -// -// Only one Reader may be open at a time. -func (c *Conn) Reader(ctx context.Context) (MessageType, io.Reader, error) { - return c.reader(ctx) -} - -// Read is a convenience method around Reader to read a single message -// from the connection. -func (c *Conn) Read(ctx context.Context) (MessageType, []byte, error) { - typ, r, err := c.Reader(ctx) - if err != nil { - return 0, nil, err - } - - b, err := ioutil.ReadAll(r) - return typ, b, err -} - -// CloseRead starts a goroutine to read from the connection until it is closed -// or a data message is received. -// -// Once CloseRead is called you cannot read any messages from the connection. -// The returned context will be cancelled when the connection is closed. -// -// If a data message is received, the connection will be closed with StatusPolicyViolation. -// -// Call CloseRead when you do not expect to read any more messages. -// Since it actively reads from the connection, it will ensure that ping, pong and close -// frames are responded to. This means c.Ping and c.Close will still work as expected. -func (c *Conn) CloseRead(ctx context.Context) context.Context { - ctx, cancel := context.WithCancel(ctx) - go func() { - defer cancel() - c.Reader(ctx) - c.Close(StatusPolicyViolation, "unexpected data message") - }() - return ctx -} - -// SetReadLimit sets the max number of bytes to read for a single message. -// It applies to the Reader and Read methods. -// -// By default, the connection has a message read limit of 32768 bytes. -// -// When the limit is hit, the connection will be closed with StatusMessageTooBig. -func (c *Conn) SetReadLimit(n int64) { - // We add read one more byte than the limit in case - // there is a fin frame that needs to be read. - c.msgReader.limitReader.limit.Store(n + 1) -} - -const defaultReadLimit = 32768 - -func newMsgReader(c *Conn) *msgReader { - mr := &msgReader{ - c: c, - fin: true, - } - mr.readFunc = mr.read - - mr.limitReader = newLimitReader(c, mr.readFunc, defaultReadLimit+1) - return mr -} - -func (mr *msgReader) resetFlate() { - if mr.flateContextTakeover() { - mr.dict.init(32768) - } - if mr.flateBufio == nil { - mr.flateBufio = getBufioReader(mr.readFunc) - } - - mr.flateReader = getFlateReader(mr.flateBufio, mr.dict.buf) - mr.limitReader.r = mr.flateReader - mr.flateTail.Reset(deflateMessageTail) -} - -func (mr *msgReader) putFlateReader() { - if mr.flateReader != nil { - putFlateReader(mr.flateReader) - mr.flateReader = nil - } -} - -func (mr *msgReader) close() { - mr.c.readMu.forceLock() - mr.putFlateReader() - mr.dict.close() - if mr.flateBufio != nil { - putBufioReader(mr.flateBufio) - } - - if mr.c.client { - putBufioReader(mr.c.br) - mr.c.br = nil - } -} - -func (mr *msgReader) flateContextTakeover() bool { - if mr.c.client { - return !mr.c.copts.serverNoContextTakeover - } - return !mr.c.copts.clientNoContextTakeover -} - -func (c *Conn) readRSV1Illegal(h header) bool { - // If compression is disabled, rsv1 is illegal. - if !c.flate() { - return true - } - // rsv1 is only allowed on data frames beginning messages. - if h.opcode != opText && h.opcode != opBinary { - return true - } - return false -} - -func (c *Conn) readLoop(ctx context.Context) (header, error) { - for { - h, err := c.readFrameHeader(ctx) - if err != nil { - return header{}, err - } - - if h.rsv1 && c.readRSV1Illegal(h) || h.rsv2 || h.rsv3 { - err := fmt.Errorf("received header with unexpected rsv bits set: %v:%v:%v", h.rsv1, h.rsv2, h.rsv3) - c.writeError(StatusProtocolError, err) - return header{}, err - } - - if !c.client && !h.masked { - return header{}, errors.New("received unmasked frame from client") - } - - switch h.opcode { - case opClose, opPing, opPong: - err = c.handleControl(ctx, h) - if err != nil { - // Pass through CloseErrors when receiving a close frame. - if h.opcode == opClose && CloseStatus(err) != -1 { - return header{}, err - } - return header{}, fmt.Errorf("failed to handle control frame %v: %w", h.opcode, err) - } - case opContinuation, opText, opBinary: - return h, nil - default: - err := fmt.Errorf("received unknown opcode %v", h.opcode) - c.writeError(StatusProtocolError, err) - return header{}, err - } - } -} - -func (c *Conn) readFrameHeader(ctx context.Context) (header, error) { - select { - case <-c.closed: - return header{}, c.closeErr - case c.readTimeout <- ctx: - } - - h, err := readFrameHeader(c.br, c.readHeaderBuf[:]) - if err != nil { - select { - case <-c.closed: - return header{}, c.closeErr - case <-ctx.Done(): - return header{}, ctx.Err() - default: - c.close(err) - return header{}, err - } - } - - select { - case <-c.closed: - return header{}, c.closeErr - case c.readTimeout <- context.Background(): - } - - return h, nil -} - -func (c *Conn) readFramePayload(ctx context.Context, p []byte) (int, error) { - select { - case <-c.closed: - return 0, c.closeErr - case c.readTimeout <- ctx: - } - - n, err := io.ReadFull(c.br, p) - if err != nil { - select { - case <-c.closed: - return n, c.closeErr - case <-ctx.Done(): - return n, ctx.Err() - default: - err = fmt.Errorf("failed to read frame payload: %w", err) - c.close(err) - return n, err - } - } - - select { - case <-c.closed: - return n, c.closeErr - case c.readTimeout <- context.Background(): - } - - return n, err -} - -func (c *Conn) handleControl(ctx context.Context, h header) (err error) { - if h.payloadLength < 0 || h.payloadLength > maxControlPayload { - err := fmt.Errorf("received control frame payload with invalid length: %d", h.payloadLength) - c.writeError(StatusProtocolError, err) - return err - } - - if !h.fin { - err := errors.New("received fragmented control frame") - c.writeError(StatusProtocolError, err) - return err - } - - ctx, cancel := context.WithTimeout(ctx, time.Second*5) - defer cancel() - - b := c.readControlBuf[:h.payloadLength] - _, err = c.readFramePayload(ctx, b) - if err != nil { - return err - } - - if h.masked { - mask(h.maskKey, b) - } - - switch h.opcode { - case opPing: - return c.writeControl(ctx, opPong, b) - case opPong: - c.activePingsMu.Lock() - pong, ok := c.activePings[string(b)] - c.activePingsMu.Unlock() - if ok { - close(pong) - } - return nil - } - - defer func() { - c.readCloseFrameErr = err - }() - - ce, err := parseClosePayload(b) - if err != nil { - err = fmt.Errorf("received invalid close payload: %w", err) - c.writeError(StatusProtocolError, err) - return err - } - - err = fmt.Errorf("received close frame: %w", ce) - c.setCloseErr(err) - c.writeClose(ce.Code, ce.Reason) - c.close(err) - return err -} - -func (c *Conn) reader(ctx context.Context) (_ MessageType, _ io.Reader, err error) { - defer errd.Wrap(&err, "failed to get reader") - - err = c.readMu.lock(ctx) - if err != nil { - return 0, nil, err - } - defer c.readMu.unlock() - - if !c.msgReader.fin { - err = errors.New("previous message not read to completion") - c.close(fmt.Errorf("failed to get reader: %w", err)) - return 0, nil, err - } - - h, err := c.readLoop(ctx) - if err != nil { - return 0, nil, err - } - - if h.opcode == opContinuation { - err := errors.New("received continuation frame without text or binary frame") - c.writeError(StatusProtocolError, err) - return 0, nil, err - } - - c.msgReader.reset(ctx, h) - - return MessageType(h.opcode), c.msgReader, nil -} - -type msgReader struct { - c *Conn - - ctx context.Context - flate bool - flateReader io.Reader - flateBufio *bufio.Reader - flateTail strings.Reader - limitReader *limitReader - dict slidingWindow - - fin bool - payloadLength int64 - maskKey uint32 - - // readerFunc(mr.Read) to avoid continuous allocations. - readFunc readerFunc -} - -func (mr *msgReader) reset(ctx context.Context, h header) { - mr.ctx = ctx - mr.flate = h.rsv1 - mr.limitReader.reset(mr.readFunc) - - if mr.flate { - mr.resetFlate() - } - - mr.setFrame(h) -} - -func (mr *msgReader) setFrame(h header) { - mr.fin = h.fin - mr.payloadLength = h.payloadLength - mr.maskKey = h.maskKey -} - -func (mr *msgReader) Read(p []byte) (n int, err error) { - err = mr.c.readMu.lock(mr.ctx) - if err != nil { - return 0, fmt.Errorf("failed to read: %w", err) - } - defer mr.c.readMu.unlock() - - n, err = mr.limitReader.Read(p) - if mr.flate && mr.flateContextTakeover() { - p = p[:n] - mr.dict.write(p) - } - if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) && mr.fin && mr.flate { - mr.putFlateReader() - return n, io.EOF - } - if err != nil { - err = fmt.Errorf("failed to read: %w", err) - mr.c.close(err) - } - return n, err -} - -func (mr *msgReader) read(p []byte) (int, error) { - for { - if mr.payloadLength == 0 { - if mr.fin { - if mr.flate { - return mr.flateTail.Read(p) - } - return 0, io.EOF - } - - h, err := mr.c.readLoop(mr.ctx) - if err != nil { - return 0, err - } - if h.opcode != opContinuation { - err := errors.New("received new data message without finishing the previous message") - mr.c.writeError(StatusProtocolError, err) - return 0, err - } - mr.setFrame(h) - - continue - } - - if int64(len(p)) > mr.payloadLength { - p = p[:mr.payloadLength] - } - - n, err := mr.c.readFramePayload(mr.ctx, p) - if err != nil { - return n, err - } - - mr.payloadLength -= int64(n) - - if !mr.c.client { - mr.maskKey = mask(mr.maskKey, p) - } - - return n, nil - } -} - -type limitReader struct { - c *Conn - r io.Reader - limit xsync.Int64 - n int64 -} - -func newLimitReader(c *Conn, r io.Reader, limit int64) *limitReader { - lr := &limitReader{ - c: c, - } - lr.limit.Store(limit) - lr.reset(r) - return lr -} - -func (lr *limitReader) reset(r io.Reader) { - lr.n = lr.limit.Load() - lr.r = r -} - -func (lr *limitReader) Read(p []byte) (int, error) { - if lr.n <= 0 { - err := fmt.Errorf("read limited at %v bytes", lr.limit.Load()) - lr.c.writeError(StatusMessageTooBig, err) - return 0, err - } - - if int64(len(p)) > lr.n { - p = p[:lr.n] - } - n, err := lr.r.Read(p) - lr.n -= int64(n) - return n, err -} - -type readerFunc func(p []byte) (int, error) - -func (f readerFunc) Read(p []byte) (int, error) { - return f(p) -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/stringer.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/stringer.go deleted file mode 100644 index 5a66ba29076..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/stringer.go +++ /dev/null @@ -1,91 +0,0 @@ -// Code generated by "stringer -type=opcode,MessageType,StatusCode -output=stringer.go"; DO NOT EDIT. - -package websocket - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[opContinuation-0] - _ = x[opText-1] - _ = x[opBinary-2] - _ = x[opClose-8] - _ = x[opPing-9] - _ = x[opPong-10] -} - -const ( - _opcode_name_0 = "opContinuationopTextopBinary" - _opcode_name_1 = "opCloseopPingopPong" -) - -var ( - _opcode_index_0 = [...]uint8{0, 14, 20, 28} - _opcode_index_1 = [...]uint8{0, 7, 13, 19} -) - -func (i opcode) String() string { - switch { - case 0 <= i && i <= 2: - return _opcode_name_0[_opcode_index_0[i]:_opcode_index_0[i+1]] - case 8 <= i && i <= 10: - i -= 8 - return _opcode_name_1[_opcode_index_1[i]:_opcode_index_1[i+1]] - default: - return "opcode(" + strconv.FormatInt(int64(i), 10) + ")" - } -} -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[MessageText-1] - _ = x[MessageBinary-2] -} - -const _MessageType_name = "MessageTextMessageBinary" - -var _MessageType_index = [...]uint8{0, 11, 24} - -func (i MessageType) String() string { - i -= 1 - if i < 0 || i >= MessageType(len(_MessageType_index)-1) { - return "MessageType(" + strconv.FormatInt(int64(i+1), 10) + ")" - } - return _MessageType_name[_MessageType_index[i]:_MessageType_index[i+1]] -} -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[StatusNormalClosure-1000] - _ = x[StatusGoingAway-1001] - _ = x[StatusProtocolError-1002] - _ = x[StatusUnsupportedData-1003] - _ = x[statusReserved-1004] - _ = x[StatusNoStatusRcvd-1005] - _ = x[StatusAbnormalClosure-1006] - _ = x[StatusInvalidFramePayloadData-1007] - _ = x[StatusPolicyViolation-1008] - _ = x[StatusMessageTooBig-1009] - _ = x[StatusMandatoryExtension-1010] - _ = x[StatusInternalError-1011] - _ = x[StatusServiceRestart-1012] - _ = x[StatusTryAgainLater-1013] - _ = x[StatusBadGateway-1014] - _ = x[StatusTLSHandshake-1015] -} - -const _StatusCode_name = "StatusNormalClosureStatusGoingAwayStatusProtocolErrorStatusUnsupportedDatastatusReservedStatusNoStatusRcvdStatusAbnormalClosureStatusInvalidFramePayloadDataStatusPolicyViolationStatusMessageTooBigStatusMandatoryExtensionStatusInternalErrorStatusServiceRestartStatusTryAgainLaterStatusBadGatewayStatusTLSHandshake" - -var _StatusCode_index = [...]uint16{0, 19, 34, 53, 74, 88, 106, 127, 156, 177, 196, 220, 239, 259, 278, 294, 312} - -func (i StatusCode) String() string { - i -= 1000 - if i < 0 || i >= StatusCode(len(_StatusCode_index)-1) { - return "StatusCode(" + strconv.FormatInt(int64(i+1000), 10) + ")" - } - return _StatusCode_name[_StatusCode_index[i]:_StatusCode_index[i+1]] -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/stub.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/stub.go new file mode 100644 index 00000000000..7bf2a208dac --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/stub.go @@ -0,0 +1,76 @@ +// Code generated by depstubber. DO NOT EDIT. +// This is a simple stub for nhooyr.io/websocket, strictly for use in testing. + +// See the LICENSE file for information about the licensing of the original library. +// Source: nhooyr.io/websocket (exports: ; functions: Dial) + +// Package websocket is a stub of nhooyr.io/websocket, generated by depstubber. +package websocket + +import ( + context "context" + io "io" + http "net/http" +) + +type CompressionMode int + +type Conn struct{} + +func (_ *Conn) Close(_ StatusCode, _ string) error { + return nil +} + +func (_ *Conn) CloseRead(_ context.Context) context.Context { + return nil +} + +func (_ *Conn) Ping(_ context.Context) error { + return nil +} + +func (_ *Conn) Read(_ context.Context) (MessageType, []byte, error) { + return 0, nil, nil +} + +func (_ *Conn) Reader(_ context.Context) (MessageType, io.Reader, error) { + return 0, nil, nil +} + +func (_ *Conn) SetReadLimit(_ int64) {} + +func (_ *Conn) Subprotocol() string { + return "" +} + +func (_ *Conn) Write(_ context.Context, _ MessageType, _ []byte) error { + return nil +} + +func (_ *Conn) Writer(_ context.Context, _ MessageType) (io.WriteCloser, error) { + return nil, nil +} + +func Dial(_ context.Context, _ string, _ *DialOptions) (*Conn, *http.Response, error) { + return nil, nil, nil +} + +type DialOptions struct { + HTTPClient *http.Client + HTTPHeader http.Header + Subprotocols []string + CompressionMode CompressionMode + CompressionThreshold int +} + +type MessageType int + +func (_ MessageType) String() string { + return "" +} + +type StatusCode int + +func (_ StatusCode) String() string { + return "" +} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/write.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/write.go deleted file mode 100644 index 60a4fba0644..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/write.go +++ /dev/null @@ -1,386 +0,0 @@ -// +build !js - -package websocket - -import ( - "bufio" - "context" - "crypto/rand" - "encoding/binary" - "errors" - "fmt" - "io" - "time" - - "github.com/klauspost/compress/flate" - - "nhooyr.io/websocket/internal/errd" -) - -// Writer returns a writer bounded by the context that will write -// a WebSocket message of type dataType to the connection. -// -// You must close the writer once you have written the entire message. -// -// Only one writer can be open at a time, multiple calls will block until the previous writer -// is closed. -func (c *Conn) Writer(ctx context.Context, typ MessageType) (io.WriteCloser, error) { - w, err := c.writer(ctx, typ) - if err != nil { - return nil, fmt.Errorf("failed to get writer: %w", err) - } - return w, nil -} - -// Write writes a message to the connection. -// -// See the Writer method if you want to stream a message. -// -// If compression is disabled or the threshold is not met, then it -// will write the message in a single frame. -func (c *Conn) Write(ctx context.Context, typ MessageType, p []byte) error { - _, err := c.write(ctx, typ, p) - if err != nil { - return fmt.Errorf("failed to write msg: %w", err) - } - return nil -} - -type msgWriter struct { - mw *msgWriterState - closed bool -} - -func (mw *msgWriter) Write(p []byte) (int, error) { - if mw.closed { - return 0, errors.New("cannot use closed writer") - } - return mw.mw.Write(p) -} - -func (mw *msgWriter) Close() error { - if mw.closed { - return errors.New("cannot use closed writer") - } - mw.closed = true - return mw.mw.Close() -} - -type msgWriterState struct { - c *Conn - - mu *mu - writeMu *mu - - ctx context.Context - opcode opcode - flate bool - - trimWriter *trimLastFourBytesWriter - dict slidingWindow -} - -func newMsgWriterState(c *Conn) *msgWriterState { - mw := &msgWriterState{ - c: c, - mu: newMu(c), - writeMu: newMu(c), - } - return mw -} - -func (mw *msgWriterState) ensureFlate() { - if mw.trimWriter == nil { - mw.trimWriter = &trimLastFourBytesWriter{ - w: writerFunc(mw.write), - } - } - - mw.dict.init(8192) - mw.flate = true -} - -func (mw *msgWriterState) flateContextTakeover() bool { - if mw.c.client { - return !mw.c.copts.clientNoContextTakeover - } - return !mw.c.copts.serverNoContextTakeover -} - -func (c *Conn) writer(ctx context.Context, typ MessageType) (io.WriteCloser, error) { - err := c.msgWriterState.reset(ctx, typ) - if err != nil { - return nil, err - } - return &msgWriter{ - mw: c.msgWriterState, - closed: false, - }, nil -} - -func (c *Conn) write(ctx context.Context, typ MessageType, p []byte) (int, error) { - mw, err := c.writer(ctx, typ) - if err != nil { - return 0, err - } - - if !c.flate() { - defer c.msgWriterState.mu.unlock() - return c.writeFrame(ctx, true, false, c.msgWriterState.opcode, p) - } - - n, err := mw.Write(p) - if err != nil { - return n, err - } - - err = mw.Close() - return n, err -} - -func (mw *msgWriterState) reset(ctx context.Context, typ MessageType) error { - err := mw.mu.lock(ctx) - if err != nil { - return err - } - - mw.ctx = ctx - mw.opcode = opcode(typ) - mw.flate = false - - mw.trimWriter.reset() - - return nil -} - -// Write writes the given bytes to the WebSocket connection. -func (mw *msgWriterState) Write(p []byte) (_ int, err error) { - err = mw.writeMu.lock(mw.ctx) - if err != nil { - return 0, fmt.Errorf("failed to write: %w", err) - } - defer mw.writeMu.unlock() - - defer func() { - if err != nil { - err = fmt.Errorf("failed to write: %w", err) - mw.c.close(err) - } - }() - - if mw.c.flate() { - // Only enables flate if the length crosses the - // threshold on the first frame - if mw.opcode != opContinuation && len(p) >= mw.c.flateThreshold { - mw.ensureFlate() - } - } - - if mw.flate { - err = flate.StatelessDeflate(mw.trimWriter, p, false, mw.dict.buf) - if err != nil { - return 0, err - } - mw.dict.write(p) - return len(p), nil - } - - return mw.write(p) -} - -func (mw *msgWriterState) write(p []byte) (int, error) { - n, err := mw.c.writeFrame(mw.ctx, false, mw.flate, mw.opcode, p) - if err != nil { - return n, fmt.Errorf("failed to write data frame: %w", err) - } - mw.opcode = opContinuation - return n, nil -} - -// Close flushes the frame to the connection. -func (mw *msgWriterState) Close() (err error) { - defer errd.Wrap(&err, "failed to close writer") - - err = mw.writeMu.lock(mw.ctx) - if err != nil { - return err - } - defer mw.writeMu.unlock() - - _, err = mw.c.writeFrame(mw.ctx, true, mw.flate, mw.opcode, nil) - if err != nil { - return fmt.Errorf("failed to write fin frame: %w", err) - } - - if mw.flate && !mw.flateContextTakeover() { - mw.dict.close() - } - mw.mu.unlock() - return nil -} - -func (mw *msgWriterState) close() { - if mw.c.client { - mw.c.writeFrameMu.forceLock() - putBufioWriter(mw.c.bw) - } - - mw.writeMu.forceLock() - mw.dict.close() -} - -func (c *Conn) writeControl(ctx context.Context, opcode opcode, p []byte) error { - ctx, cancel := context.WithTimeout(ctx, time.Second*5) - defer cancel() - - _, err := c.writeFrame(ctx, true, false, opcode, p) - if err != nil { - return fmt.Errorf("failed to write control frame %v: %w", opcode, err) - } - return nil -} - -// frame handles all writes to the connection. -func (c *Conn) writeFrame(ctx context.Context, fin bool, flate bool, opcode opcode, p []byte) (_ int, err error) { - err = c.writeFrameMu.lock(ctx) - if err != nil { - return 0, err - } - defer func() { - // We leave it locked when writing the close frame to avoid - // any other goroutine writing any other frame. - if opcode != opClose { - c.writeFrameMu.unlock() - } - }() - - select { - case <-c.closed: - return 0, c.closeErr - case c.writeTimeout <- ctx: - } - - defer func() { - if err != nil { - select { - case <-c.closed: - err = c.closeErr - case <-ctx.Done(): - err = ctx.Err() - } - c.close(err) - err = fmt.Errorf("failed to write frame: %w", err) - } - }() - - c.writeHeader.fin = fin - c.writeHeader.opcode = opcode - c.writeHeader.payloadLength = int64(len(p)) - - if c.client { - c.writeHeader.masked = true - _, err = io.ReadFull(rand.Reader, c.writeHeaderBuf[:4]) - if err != nil { - return 0, fmt.Errorf("failed to generate masking key: %w", err) - } - c.writeHeader.maskKey = binary.LittleEndian.Uint32(c.writeHeaderBuf[:]) - } - - c.writeHeader.rsv1 = false - if flate && (opcode == opText || opcode == opBinary) { - c.writeHeader.rsv1 = true - } - - err = writeFrameHeader(c.writeHeader, c.bw, c.writeHeaderBuf[:]) - if err != nil { - return 0, err - } - - n, err := c.writeFramePayload(p) - if err != nil { - return n, err - } - - if c.writeHeader.fin { - err = c.bw.Flush() - if err != nil { - return n, fmt.Errorf("failed to flush: %w", err) - } - } - - select { - case <-c.closed: - return n, c.closeErr - case c.writeTimeout <- context.Background(): - } - - return n, nil -} - -func (c *Conn) writeFramePayload(p []byte) (n int, err error) { - defer errd.Wrap(&err, "failed to write frame payload") - - if !c.writeHeader.masked { - return c.bw.Write(p) - } - - maskKey := c.writeHeader.maskKey - for len(p) > 0 { - // If the buffer is full, we need to flush. - if c.bw.Available() == 0 { - err = c.bw.Flush() - if err != nil { - return n, err - } - } - - // Start of next write in the buffer. - i := c.bw.Buffered() - - j := len(p) - if j > c.bw.Available() { - j = c.bw.Available() - } - - _, err := c.bw.Write(p[:j]) - if err != nil { - return n, err - } - - maskKey = mask(maskKey, c.writeBuf[i:c.bw.Buffered()]) - - p = p[j:] - n += j - } - - return n, nil -} - -type writerFunc func(p []byte) (int, error) - -func (f writerFunc) Write(p []byte) (int, error) { - return f(p) -} - -// extractBufioWriterBuf grabs the []byte backing a *bufio.Writer -// and returns it. -func extractBufioWriterBuf(bw *bufio.Writer, w io.Writer) []byte { - var writeBuf []byte - bw.Reset(writerFunc(func(p2 []byte) (int, error) { - writeBuf = p2[:cap(p2)] - return len(p2), nil - })) - - bw.WriteByte(0) - bw.Flush() - - bw.Reset(w) - - return writeBuf -} - -func (c *Conn) writeError(code StatusCode, err error) { - c.setCloseErr(err) - c.writeClose(code, err.Error()) - c.close(nil) -} diff --git a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/ws_js.go b/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/ws_js.go deleted file mode 100644 index b87e32cdafb..00000000000 --- a/ql/test/library-tests/semmle/go/frameworks/Websocket/vendor/nhooyr.io/websocket/ws_js.go +++ /dev/null @@ -1,379 +0,0 @@ -package websocket // import "nhooyr.io/websocket" - -import ( - "bytes" - "context" - "errors" - "fmt" - "io" - "net/http" - "reflect" - "runtime" - "strings" - "sync" - "syscall/js" - - "nhooyr.io/websocket/internal/bpool" - "nhooyr.io/websocket/internal/wsjs" - "nhooyr.io/websocket/internal/xsync" -) - -// Conn provides a wrapper around the browser WebSocket API. -type Conn struct { - ws wsjs.WebSocket - - // read limit for a message in bytes. - msgReadLimit xsync.Int64 - - closingMu sync.Mutex - isReadClosed xsync.Int64 - closeOnce sync.Once - closed chan struct{} - closeErrOnce sync.Once - closeErr error - closeWasClean bool - - releaseOnClose func() - releaseOnMessage func() - - readSignal chan struct{} - readBufMu sync.Mutex - readBuf []wsjs.MessageEvent -} - -func (c *Conn) close(err error, wasClean bool) { - c.closeOnce.Do(func() { - runtime.SetFinalizer(c, nil) - - if !wasClean { - err = fmt.Errorf("unclean connection close: %w", err) - } - c.setCloseErr(err) - c.closeWasClean = wasClean - close(c.closed) - }) -} - -func (c *Conn) init() { - c.closed = make(chan struct{}) - c.readSignal = make(chan struct{}, 1) - - c.msgReadLimit.Store(32768) - - c.releaseOnClose = c.ws.OnClose(func(e wsjs.CloseEvent) { - err := CloseError{ - Code: StatusCode(e.Code), - Reason: e.Reason, - } - // We do not know if we sent or received this close as - // its possible the browser triggered it without us - // explicitly sending it. - c.close(err, e.WasClean) - - c.releaseOnClose() - c.releaseOnMessage() - }) - - c.releaseOnMessage = c.ws.OnMessage(func(e wsjs.MessageEvent) { - c.readBufMu.Lock() - defer c.readBufMu.Unlock() - - c.readBuf = append(c.readBuf, e) - - // Lets the read goroutine know there is definitely something in readBuf. - select { - case c.readSignal <- struct{}{}: - default: - } - }) - - runtime.SetFinalizer(c, func(c *Conn) { - c.setCloseErr(errors.New("connection garbage collected")) - c.closeWithInternal() - }) -} - -func (c *Conn) closeWithInternal() { - c.Close(StatusInternalError, "something went wrong") -} - -// Read attempts to read a message from the connection. -// The maximum time spent waiting is bounded by the context. -func (c *Conn) Read(ctx context.Context) (MessageType, []byte, error) { - if c.isReadClosed.Load() == 1 { - return 0, nil, errors.New("WebSocket connection read closed") - } - - typ, p, err := c.read(ctx) - if err != nil { - return 0, nil, fmt.Errorf("failed to read: %w", err) - } - if int64(len(p)) > c.msgReadLimit.Load() { - err := fmt.Errorf("read limited at %v bytes", c.msgReadLimit.Load()) - c.Close(StatusMessageTooBig, err.Error()) - return 0, nil, err - } - return typ, p, nil -} - -func (c *Conn) read(ctx context.Context) (MessageType, []byte, error) { - select { - case <-ctx.Done(): - c.Close(StatusPolicyViolation, "read timed out") - return 0, nil, ctx.Err() - case <-c.readSignal: - case <-c.closed: - return 0, nil, c.closeErr - } - - c.readBufMu.Lock() - defer c.readBufMu.Unlock() - - me := c.readBuf[0] - // We copy the messages forward and decrease the size - // of the slice to avoid reallocating. - copy(c.readBuf, c.readBuf[1:]) - c.readBuf = c.readBuf[:len(c.readBuf)-1] - - if len(c.readBuf) > 0 { - // Next time we read, we'll grab the message. - select { - case c.readSignal <- struct{}{}: - default: - } - } - - switch p := me.Data.(type) { - case string: - return MessageText, []byte(p), nil - case []byte: - return MessageBinary, p, nil - default: - panic("websocket: unexpected data type from wsjs OnMessage: " + reflect.TypeOf(me.Data).String()) - } -} - -// Ping is mocked out for Wasm. -func (c *Conn) Ping(ctx context.Context) error { - return nil -} - -// Write writes a message of the given type to the connection. -// Always non blocking. -func (c *Conn) Write(ctx context.Context, typ MessageType, p []byte) error { - err := c.write(ctx, typ, p) - if err != nil { - // Have to ensure the WebSocket is closed after a write error - // to match the Go API. It can only error if the message type - // is unexpected or the passed bytes contain invalid UTF-8 for - // MessageText. - err := fmt.Errorf("failed to write: %w", err) - c.setCloseErr(err) - c.closeWithInternal() - return err - } - return nil -} - -func (c *Conn) write(ctx context.Context, typ MessageType, p []byte) error { - if c.isClosed() { - return c.closeErr - } - switch typ { - case MessageBinary: - return c.ws.SendBytes(p) - case MessageText: - return c.ws.SendText(string(p)) - default: - return fmt.Errorf("unexpected message type: %v", typ) - } -} - -// Close closes the WebSocket with the given code and reason. -// It will wait until the peer responds with a close frame -// or the connection is closed. -// It thus performs the full WebSocket close handshake. -func (c *Conn) Close(code StatusCode, reason string) error { - err := c.exportedClose(code, reason) - if err != nil { - return fmt.Errorf("failed to close WebSocket: %w", err) - } - return nil -} - -func (c *Conn) exportedClose(code StatusCode, reason string) error { - c.closingMu.Lock() - defer c.closingMu.Unlock() - - ce := fmt.Errorf("sent close: %w", CloseError{ - Code: code, - Reason: reason, - }) - - if c.isClosed() { - return fmt.Errorf("tried to close with %q but connection already closed: %w", ce, c.closeErr) - } - - c.setCloseErr(ce) - err := c.ws.Close(int(code), reason) - if err != nil { - return err - } - - <-c.closed - if !c.closeWasClean { - return c.closeErr - } - return nil -} - -// Subprotocol returns the negotiated subprotocol. -// An empty string means the default protocol. -func (c *Conn) Subprotocol() string { - return c.ws.Subprotocol() -} - -// DialOptions represents the options available to pass to Dial. -type DialOptions struct { - // Subprotocols lists the subprotocols to negotiate with the server. - Subprotocols []string -} - -// Dial creates a new WebSocket connection to the given url with the given options. -// The passed context bounds the maximum time spent waiting for the connection to open. -// The returned *http.Response is always nil or a mock. It's only in the signature -// to match the core API. -func Dial(ctx context.Context, url string, opts *DialOptions) (*Conn, *http.Response, error) { - c, resp, err := dial(ctx, url, opts) - if err != nil { - return nil, nil, fmt.Errorf("failed to WebSocket dial %q: %w", url, err) - } - return c, resp, nil -} - -func dial(ctx context.Context, url string, opts *DialOptions) (*Conn, *http.Response, error) { - if opts == nil { - opts = &DialOptions{} - } - - url = strings.Replace(url, "http://", "ws://", 1) - url = strings.Replace(url, "https://", "wss://", 1) - - ws, err := wsjs.New(url, opts.Subprotocols) - if err != nil { - return nil, nil, err - } - - c := &Conn{ - ws: ws, - } - c.init() - - opench := make(chan struct{}) - releaseOpen := ws.OnOpen(func(e js.Value) { - close(opench) - }) - defer releaseOpen() - - select { - case <-ctx.Done(): - c.Close(StatusPolicyViolation, "dial timed out") - return nil, nil, ctx.Err() - case <-opench: - return c, &http.Response{ - StatusCode: http.StatusSwitchingProtocols, - }, nil - case <-c.closed: - return nil, nil, c.closeErr - } -} - -// Reader attempts to read a message from the connection. -// The maximum time spent waiting is bounded by the context. -func (c *Conn) Reader(ctx context.Context) (MessageType, io.Reader, error) { - typ, p, err := c.Read(ctx) - if err != nil { - return 0, nil, err - } - return typ, bytes.NewReader(p), nil -} - -// Writer returns a writer to write a WebSocket data message to the connection. -// It buffers the entire message in memory and then sends it when the writer -// is closed. -func (c *Conn) Writer(ctx context.Context, typ MessageType) (io.WriteCloser, error) { - return writer{ - c: c, - ctx: ctx, - typ: typ, - b: bpool.Get(), - }, nil -} - -type writer struct { - closed bool - - c *Conn - ctx context.Context - typ MessageType - - b *bytes.Buffer -} - -func (w writer) Write(p []byte) (int, error) { - if w.closed { - return 0, errors.New("cannot write to closed writer") - } - n, err := w.b.Write(p) - if err != nil { - return n, fmt.Errorf("failed to write message: %w", err) - } - return n, nil -} - -func (w writer) Close() error { - if w.closed { - return errors.New("cannot close closed writer") - } - w.closed = true - defer bpool.Put(w.b) - - err := w.c.Write(w.ctx, w.typ, w.b.Bytes()) - if err != nil { - return fmt.Errorf("failed to close writer: %w", err) - } - return nil -} - -// CloseRead implements *Conn.CloseRead for wasm. -func (c *Conn) CloseRead(ctx context.Context) context.Context { - c.isReadClosed.Store(1) - - ctx, cancel := context.WithCancel(ctx) - go func() { - defer cancel() - c.read(ctx) - c.Close(StatusPolicyViolation, "unexpected data message") - }() - return ctx -} - -// SetReadLimit implements *Conn.SetReadLimit for wasm. -func (c *Conn) SetReadLimit(n int64) { - c.msgReadLimit.Store(n) -} - -func (c *Conn) setCloseErr(err error) { - c.closeErrOnce.Do(func() { - c.closeErr = fmt.Errorf("WebSocket closed: %w", err) - }) -} - -func (c *Conn) isClosed() bool { - select { - case <-c.closed: - return true - default: - return false - } -} diff --git a/ql/test/query-tests/Security/CWE-918/RequestForgery.expected b/ql/test/query-tests/Security/CWE-918/RequestForgery.expected index 2707f133c5c..5709a91dcaf 100644 --- a/ql/test/query-tests/Security/CWE-918/RequestForgery.expected +++ b/ql/test/query-tests/Security/CWE-918/RequestForgery.expected @@ -13,15 +13,15 @@ edges | tst.go:36:2:36:2 | implicit dereference : URL | tst.go:36:2:36:2 | implicit dereference : URL | | tst.go:36:2:36:2 | implicit dereference : URL | tst.go:37:11:37:20 | call to String | | tst.go:36:2:36:2 | u [pointer] : URL | tst.go:36:2:36:2 | implicit dereference : URL | -| websocket.go:54:21:54:31 | call to Referer : string | websocket.go:59:27:59:40 | untrustedInput | -| websocket.go:68:21:68:31 | call to Referer : string | websocket.go:72:36:72:49 | untrustedInput | -| websocket.go:82:21:82:31 | call to Referer : string | websocket.go:85:31:85:44 | untrustedInput | -| websocket.go:101:21:101:31 | call to Referer : string | websocket.go:104:15:104:28 | untrustedInput | -| websocket.go:120:21:120:31 | call to Referer : string | websocket.go:123:38:123:51 | untrustedInput | -| websocket.go:148:21:148:31 | call to Referer : string | websocket.go:149:31:149:44 | untrustedInput | -| websocket.go:154:21:154:31 | call to Referer : string | websocket.go:156:31:156:44 | untrustedInput | -| websocket.go:189:21:189:31 | call to Referer : string | websocket.go:191:18:191:31 | untrustedInput | -| websocket.go:196:21:196:31 | call to Referer : string | websocket.go:198:11:198:24 | untrustedInput | +| websocket.go:60:21:60:31 | call to Referer : string | websocket.go:65:27:65:40 | untrustedInput | +| websocket.go:74:21:74:31 | call to Referer : string | websocket.go:78:36:78:49 | untrustedInput | +| websocket.go:88:21:88:31 | call to Referer : string | websocket.go:91:31:91:44 | untrustedInput | +| websocket.go:107:21:107:31 | call to Referer : string | websocket.go:110:15:110:28 | untrustedInput | +| websocket.go:126:21:126:31 | call to Referer : string | websocket.go:129:38:129:51 | untrustedInput | +| websocket.go:154:21:154:31 | call to Referer : string | websocket.go:155:31:155:44 | untrustedInput | +| websocket.go:160:21:160:31 | call to Referer : string | websocket.go:162:31:162:44 | untrustedInput | +| websocket.go:195:21:195:31 | call to Referer : string | websocket.go:197:18:197:31 | untrustedInput | +| websocket.go:202:21:202:31 | call to Referer : string | websocket.go:204:11:204:24 | untrustedInput | nodes | RequestForgery.go:8:12:8:34 | call to FormValue : string | semmle.label | call to FormValue : string | | RequestForgery.go:11:24:11:65 | ...+... | semmle.label | ...+... | @@ -36,24 +36,24 @@ nodes | tst.go:36:2:36:2 | implicit dereference : URL | semmle.label | implicit dereference : URL | | tst.go:36:2:36:2 | u [pointer] : URL | semmle.label | u [pointer] : URL | | tst.go:37:11:37:20 | call to String | semmle.label | call to String | -| websocket.go:54:21:54:31 | call to Referer : string | semmle.label | call to Referer : string | -| websocket.go:59:27:59:40 | untrustedInput | semmle.label | untrustedInput | -| websocket.go:68:21:68:31 | call to Referer : string | semmle.label | call to Referer : string | -| websocket.go:72:36:72:49 | untrustedInput | semmle.label | untrustedInput | -| websocket.go:82:21:82:31 | call to Referer : string | semmle.label | call to Referer : string | -| websocket.go:85:31:85:44 | untrustedInput | semmle.label | untrustedInput | -| websocket.go:101:21:101:31 | call to Referer : string | semmle.label | call to Referer : string | -| websocket.go:104:15:104:28 | untrustedInput | semmle.label | untrustedInput | -| websocket.go:120:21:120:31 | call to Referer : string | semmle.label | call to Referer : string | -| websocket.go:123:38:123:51 | untrustedInput | semmle.label | untrustedInput | -| websocket.go:148:21:148:31 | call to Referer : string | semmle.label | call to Referer : string | -| websocket.go:149:31:149:44 | untrustedInput | semmle.label | untrustedInput | +| websocket.go:60:21:60:31 | call to Referer : string | semmle.label | call to Referer : string | +| websocket.go:65:27:65:40 | untrustedInput | semmle.label | untrustedInput | +| websocket.go:74:21:74:31 | call to Referer : string | semmle.label | call to Referer : string | +| websocket.go:78:36:78:49 | untrustedInput | semmle.label | untrustedInput | +| websocket.go:88:21:88:31 | call to Referer : string | semmle.label | call to Referer : string | +| websocket.go:91:31:91:44 | untrustedInput | semmle.label | untrustedInput | +| websocket.go:107:21:107:31 | call to Referer : string | semmle.label | call to Referer : string | +| websocket.go:110:15:110:28 | untrustedInput | semmle.label | untrustedInput | +| websocket.go:126:21:126:31 | call to Referer : string | semmle.label | call to Referer : string | +| websocket.go:129:38:129:51 | untrustedInput | semmle.label | untrustedInput | | websocket.go:154:21:154:31 | call to Referer : string | semmle.label | call to Referer : string | -| websocket.go:156:31:156:44 | untrustedInput | semmle.label | untrustedInput | -| websocket.go:189:21:189:31 | call to Referer : string | semmle.label | call to Referer : string | -| websocket.go:191:18:191:31 | untrustedInput | semmle.label | untrustedInput | -| websocket.go:196:21:196:31 | call to Referer : string | semmle.label | call to Referer : string | -| websocket.go:198:11:198:24 | untrustedInput | semmle.label | untrustedInput | +| websocket.go:155:31:155:44 | untrustedInput | semmle.label | untrustedInput | +| websocket.go:160:21:160:31 | call to Referer : string | semmle.label | call to Referer : string | +| websocket.go:162:31:162:44 | untrustedInput | semmle.label | untrustedInput | +| websocket.go:195:21:195:31 | call to Referer : string | semmle.label | call to Referer : string | +| websocket.go:197:18:197:31 | untrustedInput | semmle.label | untrustedInput | +| websocket.go:202:21:202:31 | call to Referer : string | semmle.label | call to Referer : string | +| websocket.go:204:11:204:24 | untrustedInput | semmle.label | untrustedInput | #select | RequestForgery.go:11:15:11:66 | call to Get | RequestForgery.go:8:12:8:34 | call to FormValue : string | RequestForgery.go:11:24:11:65 | ...+... | The $@ of this request depends on $@. | RequestForgery.go:11:24:11:65 | ...+... | URL | RequestForgery.go:8:12:8:34 | call to FormValue : string | a user-provided value | | tst.go:14:2:14:18 | call to Get | tst.go:10:13:10:35 | call to FormValue : string | tst.go:14:11:14:17 | tainted | The $@ of this request depends on $@. | tst.go:14:11:14:17 | tainted | URL | tst.go:10:13:10:35 | call to FormValue : string | a user-provided value | @@ -63,12 +63,12 @@ nodes | tst.go:27:2:27:30 | call to Get | tst.go:10:13:10:35 | call to FormValue : string | tst.go:27:11:27:29 | ...+... | The $@ of this request depends on $@. | tst.go:27:11:27:29 | ...+... | URL | tst.go:10:13:10:35 | call to FormValue : string | a user-provided value | | tst.go:29:2:29:41 | call to Get | tst.go:10:13:10:35 | call to FormValue : string | tst.go:29:11:29:40 | ...+... | The $@ of this request depends on $@. | tst.go:29:11:29:40 | ...+... | URL | tst.go:10:13:10:35 | call to FormValue : string | a user-provided value | | tst.go:37:2:37:21 | call to Get | tst.go:10:13:10:35 | call to FormValue : string | tst.go:37:11:37:20 | call to String | The $@ of this request depends on $@. | tst.go:37:11:37:20 | call to String | URL | tst.go:10:13:10:35 | call to FormValue : string | a user-provided value | -| websocket.go:59:12:59:53 | call to Dial | websocket.go:54:21:54:31 | call to Referer : string | websocket.go:59:27:59:40 | untrustedInput | The $@ of this request depends on $@. | websocket.go:59:27:59:40 | untrustedInput | WebSocket URL | websocket.go:54:21:54:31 | call to Referer : string | a user-provided value | -| websocket.go:73:13:73:40 | call to DialConfig | websocket.go:68:21:68:31 | call to Referer : string | websocket.go:72:36:72:49 | untrustedInput | The $@ of this request depends on $@. | websocket.go:72:36:72:49 | untrustedInput | WebSocket URL | websocket.go:68:21:68:31 | call to Referer : string | a user-provided value | -| websocket.go:85:3:85:50 | call to Dial | websocket.go:82:21:82:31 | call to Referer : string | websocket.go:85:31:85:44 | untrustedInput | The $@ of this request depends on $@. | websocket.go:85:31:85:44 | untrustedInput | WebSocket URL | websocket.go:82:21:82:31 | call to Referer : string | a user-provided value | -| websocket.go:104:3:104:39 | call to Dial | websocket.go:101:21:101:31 | call to Referer : string | websocket.go:104:15:104:28 | untrustedInput | The $@ of this request depends on $@. | websocket.go:104:15:104:28 | untrustedInput | WebSocket URL | websocket.go:101:21:101:31 | call to Referer : string | a user-provided value | -| websocket.go:123:3:123:62 | call to DialContext | websocket.go:120:21:120:31 | call to Referer : string | websocket.go:123:38:123:51 | untrustedInput | The $@ of this request depends on $@. | websocket.go:123:38:123:51 | untrustedInput | WebSocket URL | websocket.go:120:21:120:31 | call to Referer : string | a user-provided value | -| websocket.go:149:3:149:45 | call to Dial | websocket.go:148:21:148:31 | call to Referer : string | websocket.go:149:31:149:44 | untrustedInput | The $@ of this request depends on $@. | websocket.go:149:31:149:44 | untrustedInput | WebSocket URL | websocket.go:148:21:148:31 | call to Referer : string | a user-provided value | -| websocket.go:156:3:156:45 | call to Dial | websocket.go:154:21:154:31 | call to Referer : string | websocket.go:156:31:156:44 | untrustedInput | The $@ of this request depends on $@. | websocket.go:156:31:156:44 | untrustedInput | WebSocket URL | websocket.go:154:21:154:31 | call to Referer : string | a user-provided value | -| websocket.go:191:3:191:32 | call to BuildProxy | websocket.go:189:21:189:31 | call to Referer : string | websocket.go:191:18:191:31 | untrustedInput | The $@ of this request depends on $@. | websocket.go:191:18:191:31 | untrustedInput | WebSocket URL | websocket.go:189:21:189:31 | call to Referer : string | a user-provided value | -| websocket.go:198:3:198:25 | call to New | websocket.go:196:21:196:31 | call to Referer : string | websocket.go:198:11:198:24 | untrustedInput | The $@ of this request depends on $@. | websocket.go:198:11:198:24 | untrustedInput | WebSocket URL | websocket.go:196:21:196:31 | call to Referer : string | a user-provided value | +| websocket.go:65:12:65:53 | call to Dial | websocket.go:60:21:60:31 | call to Referer : string | websocket.go:65:27:65:40 | untrustedInput | The $@ of this request depends on $@. | websocket.go:65:27:65:40 | untrustedInput | WebSocket URL | websocket.go:60:21:60:31 | call to Referer : string | a user-provided value | +| websocket.go:79:13:79:40 | call to DialConfig | websocket.go:74:21:74:31 | call to Referer : string | websocket.go:78:36:78:49 | untrustedInput | The $@ of this request depends on $@. | websocket.go:78:36:78:49 | untrustedInput | WebSocket URL | websocket.go:74:21:74:31 | call to Referer : string | a user-provided value | +| websocket.go:91:3:91:50 | call to Dial | websocket.go:88:21:88:31 | call to Referer : string | websocket.go:91:31:91:44 | untrustedInput | The $@ of this request depends on $@. | websocket.go:91:31:91:44 | untrustedInput | WebSocket URL | websocket.go:88:21:88:31 | call to Referer : string | a user-provided value | +| websocket.go:110:3:110:39 | call to Dial | websocket.go:107:21:107:31 | call to Referer : string | websocket.go:110:15:110:28 | untrustedInput | The $@ of this request depends on $@. | websocket.go:110:15:110:28 | untrustedInput | WebSocket URL | websocket.go:107:21:107:31 | call to Referer : string | a user-provided value | +| websocket.go:129:3:129:62 | call to DialContext | websocket.go:126:21:126:31 | call to Referer : string | websocket.go:129:38:129:51 | untrustedInput | The $@ of this request depends on $@. | websocket.go:129:38:129:51 | untrustedInput | WebSocket URL | websocket.go:126:21:126:31 | call to Referer : string | a user-provided value | +| websocket.go:155:3:155:45 | call to Dial | websocket.go:154:21:154:31 | call to Referer : string | websocket.go:155:31:155:44 | untrustedInput | The $@ of this request depends on $@. | websocket.go:155:31:155:44 | untrustedInput | WebSocket URL | websocket.go:154:21:154:31 | call to Referer : string | a user-provided value | +| websocket.go:162:3:162:45 | call to Dial | websocket.go:160:21:160:31 | call to Referer : string | websocket.go:162:31:162:44 | untrustedInput | The $@ of this request depends on $@. | websocket.go:162:31:162:44 | untrustedInput | WebSocket URL | websocket.go:160:21:160:31 | call to Referer : string | a user-provided value | +| websocket.go:197:3:197:32 | call to BuildProxy | websocket.go:195:21:195:31 | call to Referer : string | websocket.go:197:18:197:31 | untrustedInput | The $@ of this request depends on $@. | websocket.go:197:18:197:31 | untrustedInput | WebSocket URL | websocket.go:195:21:195:31 | call to Referer : string | a user-provided value | +| websocket.go:204:3:204:25 | call to New | websocket.go:202:21:202:31 | call to Referer : string | websocket.go:204:11:204:24 | untrustedInput | The $@ of this request depends on $@. | websocket.go:204:11:204:24 | untrustedInput | WebSocket URL | websocket.go:202:21:202:31 | call to Referer : string | a user-provided value | diff --git a/ql/test/query-tests/Security/CWE-918/go.mod b/ql/test/query-tests/Security/CWE-918/go.mod index 5f614a3d1d3..ce6c493a190 100644 --- a/ql/test/query-tests/Security/CWE-918/go.mod +++ b/ql/test/query-tests/Security/CWE-918/go.mod @@ -5,7 +5,6 @@ go 1.14 require ( github.com/gobwas/ws v1.0.3 github.com/gorilla/websocket v1.4.2 - github.com/sacOO7/go-logger v0.0.0-20180719173527-9ac9add5a50d // indirect github.com/sacOO7/gowebsocket v0.0.0-20180719182212-1436bb906a4e golang.org/x/net v0.0.0-20200421231249-e086a090c8fd nhooyr.io/websocket v1.8.5 diff --git a/ql/test/query-tests/Security/CWE-918/main b/ql/test/query-tests/Security/CWE-918/main new file mode 100755 index 0000000000000000000000000000000000000000..e713a460ed5df969e554a8bb572b6599d7475bd1 GIT binary patch literal 6935277 zcmeFad3;pm`8Pa)42%k#0YM_Nj5=s=!9+n5H9Ap{6C7$#)TpRYF`}YIn1NVPC(Hym z4pXD0)vB$jc5%TMeA~=g90v)fSULFz3y{n&V-{9X zZ*x&`-a&lbuzizH`T>PpWdx0bctc>bz)(aj1SCQ*b{5{Tfh^q&_ zb0tmX2awKx_Oqaye7fwX%d5V-xinO#ZrD zM%HtCuA)r;PL;CjQCv(38Q*YB<>vOaNiuHOrZ9UUEa*!Z_!r|@sTPT>z)cy0W4Is17e zUVd=Y4_vS62d-E3E3Nv6;>kKTek<9v4)n7f+VC2z`VCh7SFD0Ie!ISH+sjekV$lXE z&&nGV{(Kv-m5bt8|8`pS?P3i#D*794RP{&N83(EVIqKW8Ws&VSsruV*QuXUC;>bU7 z+w|M|tFh8;G?80X{m8AV{$ShTp&bADwSqQxJSMAnVx=PiOsx>!?wetKmA;atof4&-5Q( z`c1vi4oQoRWqWQyGPdVVkY{U?ZCUc^@~KDq?-0B>>o=}`K=K+_UnI}@qtiv@#h3l* zD#y3fw;Ob)d|OU-a_8^YkwN}5|LWDNSJ8iDc4k_CcKPARcNRG^N7X;Fud09SsO%`A zGyZJ=HKh{O5JTADqG#<#Gi>m&h}Anmp2fI^(~gQ~lP5 zRsGgKtNKe6IR~vD>Qp~=^1}*m$s~E^r)#R0Y;IhxZ;|XwTV&N=WYw?KvnkI0a=ChU z!ryD=6N0GM+{yC%dd`o_|CvtpJKFvr^*TJ)%X2p!gyUal{41^cww2rQrX7cNa=%%; z66|I8&o*q=x8qJb9-YEMj(?ra{P)PS>pF^|Be_97BfnR{V9yX`vb zM{29&^R|iEx!KZi*7!f~|3?De9PTzW(M@ipq*^x^m2Qx6L|zN_Dupye4?Xm1mrC%SF|rFB*6Kw4Yyi^Y|O8#$Pge z>|GO28Fkv&vEy&Ma@_4Fk3HkIE5;QDe;&Nfb;`7xuRnd%DbuE$JniP&!!;+@6rFzZ z>7z!@xMSq0uF}g&FD;#P=_R_c-}D{T!&PRyVYXEr>(b*F=IQZEyn1|wM~|P?B68A^ znL_56c-U2HtTJ~F>fs8GFvl2Ey8Ff$yRN#rbaLs{rPnl9RgKh!#Z;B}xyd!CVt?DX zmY{0P#>5K^-?Y>dlgmyaR06HTmqH7cWSm8y%XKB@X<`roCx z@%<%w?T)RWMmIwKeBGGjFVKykzbI&o@dtu<(_@XHGqe$7{N>t+pubWZG09)8jd#mo2)n12`YTXOyM@hs-i6Jz|omNEX^0xQL9z9Mx_d!6y9 z`8qz#b@-EJ@6AhqZ|f@;x%B7`Zx&8ZVWas1ipB^09@%x9!pG@}A%DSZmB>{$K0wV6 z@NNEvrQCP3RAcCKFf3$0zwcQ}omN3!~v4 zdUTcds%Gu$Up>cLZ|6EA;pne?CO1Y$oi7 zB#OouZFY+)y%wz@!fJZ_9+x=|Ra0-8E<%Xz$kUB|y0N=(PZqJzKNMvS#$dm$F+6|> zs4EM>NkEX-Y_yoY2qQ82i|Yy@+Le0TebtvbkQBjsa*$n#jF5wPu zFn+xG1#*J0hXGTTK+F)qqFm4jH5N9q30Kuqu>YW7|0zD^^&;{Bnh&IP^w9ueE&@P! z106D)BJkwSPkx*_jhz8e-7!Hzd?zNy}(Pzr85@@IIqXWB7d?eh zjwUo<4yIkq3Ey{g6m9}v0*XF(J?f0D`vlE9t|-VTd8A&uibRTArpd#fj)6_&3C@zo zp0Ih{vah2f^}4zEI?w{;jy2YrF_ww8b%gp*o0;}vZmUGb4WeV%q?9*rLgBhbZ9YSH zDQ*r2sEm_xyy@{-FrIT?V$)Bai+Ya6s|^ddl4l{!QNHx@6^Em!)lKQf+jQm>v~Hkn z1tB?aF!74GDajnBvbXGrld{1|wmc_L^^j z>{K7pp+}o@^yvOTXjoZ%Y@V(?wROgh#Ecx4M2`7)5!L=c_#gKBp0e$jLgDqddt{6ytsmiKlqp9S^6pkqZ?zOygaB^LG6ZP-W2=eowz4<}VVVjD>V#ezKmigR!s!ipev`GK86j$ha0`>e{nzs1A<|FJ{FGD|u{e`^sdecYl)noePCKKd+yQF69Q z*P?GASz8+FGbpu=22r8Mm0Xjh@Za;t_>Tuc8ViF*9aQC71Zjy?LhX>R_K~QPfAc}2 zt|1;YGY}Pw2Q{?sv$e9~-QgAn76FN5b>nP5C5rYIgjGI*4l**^pXUl6r7abVKt;6& z^f+Y?vZkiy>+#<61l52Vc_0|pi`Qt;r096Ezi9QCL3ueSb)718u@Hm;%_sm4{l^F9 zhXx&)&E#bCPi94NcUXhF@~aa;INAl;y=N$xGw(YO8N@Ehcqv!SDfOyDuHqIuNIa{8;jK_a}<`I-#aS!Sivmqnygl)C)~Sd zIVuQQ%aEb)XOVR+$b!{&*Xpi?!^l`|l~(sNNmx3mXSdSGK75~p@507p5ydq^G19O5 zNf~h+O}ff0y3oXxcPUWfDpGV^aR6PzNY|AFmqk|#LYYjfy#g$x8{`;%uo-T4v_Ke1 zwVpV;hi+`ujdi-wo?Iyq+?Th}G<)lOz!Cj|Q@`Rt3OB)yqfI`|o1^uO`JYC*=7np+ zJ9{8yt1=Sm$A6n41Vu>47}K0hcE)77Blij=_qK z&6^xBk0i|V4^BtEqT{MHjyeNbMvNd`4f49tY{PRoypqfO5^v@+R`N&ucpQJ~%?na)SF&$=N5`9#fLB|}{)nT+!fmPU zdPlQf+Tqc}<{gbxtBkp3qbp8~{@qT7xYPW*Sag^9@<1>fzs(gbneq&lE3~>P(iVE>JdTA%3wh6~FD^OZ>v!s_Tzx&HzN*z%o%*U*Ut#sNSbg27zFPU!;$Hks(4`Ssi~D)& zHCi(BY2o%p7BSog((RbcTmT7xa}R<`ZO)k}fNsRcT)eu>+f}X?@kD>^rH=+_54ra| zcackbX}b%rJJf3qUO!N;hv0RKdhLbR)#~+dyslKQ{qee7y$;0d)9Up|y#7+X9;H3h zG{5&R_%SC65(?J>*1LJW1xEnyXVPUVsX!(5W77F5saz%HFsVQ#RjZ_3XhP-?l~k{iK48+JDrvDwTFa!p zJ;?2fR+Y4bNuMyuSd%Pc4><61xQl-1J>Ptjwg_SM(w>Cay>JZu;hyu*Aq-Y-VFh&T z(sEjn>p^O-EN20Kfv7bv$B}6HA3Y%Mr)Yd248JqJv`8=27B(Ur%WH<}_NK%AY=1Lz zJbVqJhiPaMa3DScgUK}pbVGH>Md|~z(0h5s`455_GVIC&bYNw*=&Jl?^VH8U2x#c! z&)6Gwg(I#b&coy@!Z1C4nqGXNCvJO+@8Lv1Ru={Ao6wodYxSqfSB zDDOPV8(ju{vP0gM@WG{d1A1pN=LJ~Eh^3>ee9h+iPXP9rGzVGoo_Tw=tfBft)L4lF zlxUlF&p8xfp5CQ&`e~S97ZZz%En!4w#A-!4l zZspJGE~yTDl0wwL4X)rcjHVKiE z9e+e;66%Ex#{a}cu5&>ix^8zK-iP5m^_5*xJvrh4zRBblLlR2W7fiq#CegKkF}?T) zEp{RuL-FP^qcx}no6DkY9&HZ8JiMJdvtOj-E}+cOV$Y*kav=U7-8=IdjQe}wzgDG% z)>LU*n)J~f9WEDUU8AeLdbGt`7B#)8f8q;P(^8P?hc`6E7GKI^m(aCWw(5nA_xBol zX0Kt|!;N|(cPzx;QD)=_6*CXRG?5-bhoap(Y3XDVUw=C zx>nz8>e1~v&idmMz1{!|E`9I2p`QgJKeWw)Nu8eZjE{$UwCS6_)Hikbaen?4M5!Z-xkp3UX9e`9YFfV z4|g1a|HJUV%7;I9_}=(5wDOJbw=_ak9Ub9g-*`Lp4L(<^&%vERP4Aa_<&Cyk$w>gn z=b6^?J9HYBnMF!&cnZc5awm^LV#eC;N3#fGip7`Y%1Op1t90%5#wxAS`d{4$_q*Ra z`}VRH4!_YQ?ZvlGnU!p1%!`V!tD0$7uo^O_h;62gu zLmE8;d_DDa9^k=$`kcLY=kk5@_?4Iohi;Rc74F>G6Ml3*oX6Ls4YRk}oMm_e|G%e= zOjSvLKoTS@z5~z8*etH)pDH$iJNRcN&HX-_dlUX|#{W<8e{YqxZ6*GHhX1SJaawJA z)uX9EE#}bS7aw0ue+bmmOCYu$_^;vrWwicleQ$gp`UoxHKX1Ifjb{H&=lUHTp;eF? zL5Q69duAS`$HDYKl!Vu6!GCzK;*Fty3z~RvXd680FnFYm+CstW3Z0=Rdc6-8>3JM} z2ZBf8&0jj44m>id!s(3I3%^4ElsAV@@Y3+tR>Xt(xqUDge^K&WK+RTXr}ENc`>gW$ zNe)Chm*+I#o$&pbjPz>Jki4~Zn{{jz#$|e9(!h?Y_!(8jUuv-xlGTFAx-HXF$#Yb} z?z7IRieH^$7ydyN<|2hExHCBb1*_t-a;l0y&|+Z+jDIHgp^2fF&zq1PgSbttP+xwgV~YzWcPQd!NM6#yOYnMU_4ax9TD|%fY_3JP=WBwI+mkNf@#;| zXXwQBZ^^Q`nyLzFv(C41p+UHzQ`C|Q8GJjFXR$C4LfgRjr~}aEq%3KmSDaM{!<`@~ zcjIj!tac+T^((y=t`h-MjQhuIVSSJ^X(rLOVY9Ba@uSih_bvg_Mg0spA14=~E{aSp zqRZI|BwweI{2*WzlPi)O#sP_M)(A8LMcYSsv)#_uBn_5-lTFsYQxk1!P;88QyHx9< z2G$A`j(?}v#Y`^Rj>fee4eJ{VWPiKBN;IdkmhQyEmX)fElob9}T;hG~HKJ|3V2U6^ zPlUZydspw$v{)4~L=0G+8@Rhnx!kf5@CRpJr}YXJubr6}%-Nt9@16bylYZ90v{{ep ziF-TroDIPdTgr^Hq&?a34|*g-J_u-&`4EWREV}BkJdXT>^jDM89hJ;+OGh;Tko z3`a*}yu111rvG?ZVi9vACF>p&(N+QcL3$f>Jp;F4$r8~RI+@v~qmxlthl#=zfl%mX zKo>gq0Ryr!ol16me|~m+&tMmGruJAZJvu@g!2W>UZZs!G`$!Ksf_7soMi76t6!gCY zAI`vKUVJe4BmT$m8Elwe?K%kkYquPf{tLR2PaOU}fPo>FkuWa6)LIZd0A%7dKfHq; zrwb8P5yc-UqAdAnbH4*+UEugy^SZRl*J>l1!acP3(7%}d?;4v6*EJ=37H%}&Yf5PyM3u};>%s=exTAKRuG-MGDaXG*@bvB;hI~ehO z4p-8Z{b+NQXFOm|;VUJdDoa4zbtmSH|#vS3)Pe4GDc}ODM~JW>&y< zI*&fptj1YSm24Y_t)mN zqg155Z}@g@URWsGWm02kDdl>+qJWd42Il3o7clMqxGXs8IUiUvoEW^AQxJSmqL@+F zF(ZemE-vB`wO*_TW-Zl?g|alM$1TEYSCQUk;;w50QF^o{;0m9`TI{cMgFZ-Y+mRM% zK9q4aYL&AysDoGiT$WQg2Z*)E<%E6!6?uq2(EuauM{0F9lbkrGumeSO6Tdi%O%tM+ zifuZWz|-Su15|1Vm-eg6qK#-xt94^b&}h_+_qcfgUUDkQu4c=tfHJJP9NeZw#MY&qdz(D4=gl5~g}h>D_@DPVrrv#AF32GB&2(OIH9}Qpr+( zjv$BoUm&KaDCv-0Mq*nw)5$(!cvh`MuL9+%IH(@+HRbL#i-mrf3=R49O(h1*S|VF%Ra<&- z|2-=`SoBE!wQwya5Un(CS`fpJSZW__UJMeBwD%5;iM038>bSS>;I^OI zqZ;NxAs)PH{kK0+HPWvASc|RS`xEsKj{1$Ct_qLQmaD~TX>FLn{xL$%!1DNyN|k1& zybgo%jLCUaFTWSd3ak$+?%IDGoRMk&`6<*iz|*g?OTqG-o%g*j{78pV`IPEV;GMbL zY1m!#@-Pj8MwIBiXt}dP>9dC&O5S>OC@*riz(LpVP#=U8<#4IQx!i&IC&1N~sr;(q z0}4ofTxB1a%lR(SWfjm5EMeuN;WJ_>J~WKNtetU3vOqNm1|BEs?`m%$_Ao5=`O=EA?bgs~{Ho36OhNXTIZ~p}=K?L3O@s1sNTg&8U&2A` z_V^;k?M$!=jJ-TQR^}j#FXrFYb_1y1>ret~;RktQ2&vZD>sPz~5MjxL`>weTm=S;y zn0zs>Ave7|%5J4fq4?XQqSnc%&6TVt_DT$9^_?6dyeb!XNZ5 zdv)VT-MAALs&b=E2r1NS@%(a>56KoGECsL1LlnvV4~W9d_!He+sn5~`WaE#NTo|RO z2C~)U)AoJ(JZT#i7$o~de#in1oQ@zrsSP&3&dS(7hw!lJS7sumugU5gCy(mkkdQ)4 z{Qy2fN5X#(HjsMV0UznpfE@D5kCZ$n@Xuw%09zsi#EB09A+$=vAA_I~nO^hN(|RaJ zgsuy&gK(m&3J{v7D=}~vyw?-&pR?NIOq6!23(Eg!32ompsH3R!LDHv>X@*x_$@RD$ z)ueYS>7A-aOU^qI7Zqr+^(aa^DZmp`gN<5WP{2Pr|5O0-rkER$Wfn(<84_XJ`!G=s zF)PD)lqkn5Z$ZH8B)rzE*9yEYRIiiugeCq;zKM9ui<7~?F0acqW2oMucB7&W z5L<&qhzL}#s)hwwCp%E8fkp6-0<>}gs76UWL!t*1SR{J!YLVCh+{Y6v>8BvYM zg{~ZLmMJA@uLin<;~FWeF092W>M@rH^>zt!EQFh^j0BEu%JGO- z$y%{z=A{Hp@}01Q90GF``P2_??i0)dN`G{=-+x5-S1jMDc$$g7SL(~5aNA#B2~--B=bOcMsS#UC&fO!BT@i~c0}YP zQG9*?A9@S^pi#elzuL^~TOG+m3S6SB6mWFHu{Ou&=0;5Hf^;unAvA&OTwTkut`36$ z&FR1B&g{X+)*ZH#a9@6d!-dGkwJp1$_k_D)t|No%{pM@PsLyHu;1{x*Mvs9%8K!^* z{ta7ri)$NEQ>){a0AyQ-dE#XS^&PcbeRiZxEU4#PiE+Oy%f>H+SmIkzjc_z?Z5v8c z&3SnDV48~W`FPK>-l1N-n#Kk8%Ha$+4RudK$xUdnF_Og+Kn&dw-VMj(hu;*QBes3|SpK5o|iE)09E>2IVr_~&$QZ_XREXPs4 z{jC+AD+?ko=hGszSP4KZ=PSij$=RhI1d1sdnKi82ro~do*5iNUQ8p~9<^~8bUhL7t}GK@!)iT*;RO$Qa50RpU8d(1x8ReW z`+}#tg-?7shvQI7^tG#~iRS3`9~4S^Qf}kD=z`ykZvQ?*jcs^6zz9bI7o`3UQu4&H zu@sKX-MS3B!yz_$IFF#edALiH-{8qOt*pn-D_9*7Ljj7z{!Rg-4|;M1%@cK# zZ)4^)K4kn%99Z9mU3zoEplZ1oWpa) zHfePm@TAl$w53-L#Ky14e(WQA0Eybt@`2Hhheh@c3SYQ_rP%=B`7ZWoODhJ71;LO# zdzyV5nR@33{e7X$_Wg82j51(ez7eQq{zou4mZso#VScb9PZbJzbLhUB4y^aLta_3C zeZv}-3XE3LQIVVhD~;?Q7@n$Vvy&&&c;OuFp{|655^ljA*JG<7cg1?5U%^VH=SEiY zTi9fzeUKL0h?fkjNpCi+gnLP)!^id_Z+%i6$`vh#`p!pXm>%pPbDmV2`z4o3qC3!A zOrs0oAH;+avKFoJKxsQ=?tg)DvRoqk010W?576eq)?JZ(1GTyDLkW?6ST}f5Ua)R( z7+$oc3nkiwE@QtV*m!wBts`u@R|1d#j^yC%7M2X+)o?~N80g&VafSQICg9DpKc%#) zVTLt`fF+LMmULqjCdYT`iCm3|a#S=&TN?AT`M{5$MJ!Z~93}w3kNX>l8uL9qbHB83 zLc+YJbR7~wU|zc@6$f?DOichbRwRs{2Wu*~tO*7II~8ln#$`v!G%H9?;evUY4+t)s zewZq@K)NXt6@lY;XNX=HlPlNL?+Z0_HS^&3)N)3^#)K{^cANC9nQ}xX-Icg)2WGE1 z9B7hFS?HaDT$6f$h>7c{G_C;-Ty=G*o19>E4VcfoNu zt?oB?^2{7nfbUqD)Wu3!^lmK6grMacsQ@%CX{K;oMlUgdbSr~C6gTwXSvnghOI?;- zGN^*e3iQO4XeH>|2rmbRT`hGMU*Wy)SIIY|iYHG&D#y0BK!Jkb?*t2wnc}+ICoe@hVtny%3(d=s=x9b=%8^J5!Np@If*uD zbvcj%_*-JxNeFgwldR*|Bq;v!d8&}?O$OkcclF}(z^sMIFIiFsA^r@ z+LN(a^Ep_ivhAxJ_7=NX>R{x}9zqeIr%AOt2$iSoGiKkZ!3_mJ$#q#wIU3v1 zw#^@J)1cLj7reFvuqu~&-(f6iOz05s-T-Nc!!d8Xnk+)aSW>v6;W(tym_e!e^7}G& z$iJ$yFP`%$qXL`s&H(#60D7_j-a>!}t@p3V8A4j0a1wIrkJkHxquwJ~_4fVi$M8*a z)T_*@xAI5pjdIk>&#HGn>m}TKujnkWiJwTu2M1&nG2@^TS$9=NBCq|(n29Pcx71n9BaJlKo*NwOlPG{va;SvrXKfCB)rtEkdvg_dUz8=uiz; z*8{y*5ZBohufOL^Jw9ry9)FFE0S8R<;$KJbHtP_*c%L@s2x(QXiQ6mwHN)sxZy;kv zWAZ!NC8l~R-#LsinC)l!GC|6L~HcpF?)Q^QqmuB3Xx;(gc$mOSH@lB zigl~kUlvFa6w7JWn^J>t6OhXlaB0ymq+I{^=;32JKd_YFWV&^DLtM9#)5@98rZ2nW zP)K*Z7N-r6D8rt3=~RZ{MZ8m>EHT~_EN;@GoFc&$4IVA_B@m9$mU_yJb;j<}&B;=n z=gifjoGb~#g9eyasy(%K`ZZ$<*N%-L4jhTPIL$u8owze6^*rux2=&xE8gX9e_f!Yt zGkDToGF&k~6^7x65zqVJGSOUxdydEORun`p5lG(1&I`!O*%1N2C^p%OvP3SF1TN4U z_6AN+0@wslf!K5uJD75SEHK{Unzs|4>?6RA1S*N!7pS0&a)i_5FyO>nY76$jV!K2m zH%ugX{yFUxyVNYvBPvsFB0{+0UB0Lw2IY4?ddz9u=fBHF(PgFOj!KKND)nI{V=E3d z23+PuY^tm`5Bm$6$7kqf)Hnr=A&-p#j*fqTK$+8HLJ}mlAC@ZqJUkl>;?-wVgSf@f zAbi;kBG7e%aKrAW_f#(+ac`(~_y*Uv{6P5e>JrSnt7tUkG$AocK%mr=a%Z&rJs zSq1jcWpmmP?B$a^1ef4y^sm&aiN|VE=x1cYNd}jc0X`uY+v#6+c}6Yw-#8pHwR0A2 zq0d>m2t(l*@gImVAP70|6ftVCMv68~$=&IUy5AxL^k;^FST9z+aXtitS@h!4^3bm6 zid`t@3M0U^xmgBxrTSdyyH#n6v#jaZk$1So&_vN7Oxln@AR{jrtUGr@e* zNxAS)E5VF8}3MNt`IavbUf0Eit!6?1|G3zMNz8D$YTPDaHX?4#O9UsMB6 zIQw~uACklA^PhN&u8NSK8p^wd<03jMImTq&U%?$wbMqOkV}lTOay2l&_(NSAx1VF~ zJi)(qN_dqAQY5KL%ecfl|cC1WoD#KyXo@MAaH>Fl{ za~I6a19L>b8T5P2=g~4~r1>y(Ka9)A-V)C4ajP#=SDe^pA#-TS+33*#VH6-0u*Zkp zV~acPjl*&%8o)Yiq){!S?q47d@X&>#0HC8i9SktQDCk^Lph+u@(zzFI!VbV>JG)FY zmU6(fS3N2?&5M;i_vyE~(SSIS4Wh7zOlX09Mi5_rV|Mu&m70}bUnvg!u{4;jRFHxH3d|5W|PovA;PeQWwE;ok6%&g?(7HEW5)+27`AbI)c2 z%3hKMM))P{+2QO`o3sqeNx{BlR!JWL$7dN%@p?F>cR5Jh(*(yeEe zce}JD&JG9{9jV?jHO9>b?*xr?K^&AREB4MRnt;u-#Vc`fS(!GjwSEHJ$B5Rl5gW%R z`X3Q2Zl2jkPt3{*jzC24*6i0ft(D4aGMu83`^!R&wGcF)U=vh zSMtwjvsQ=gv@dMmK1A79Ruc=N)yO(X4&8VT-1u5ZJ#yCok2dd5B7X$<`rePV$ZUSS z)Bq2}!-{fa+|B6%7!NJDieIpRd>K-y!OdNq@>oFQiZ)i#1EyCl5R-ay%tLQO7KD?B zDf)z787-N59p=Zw2nul54+M%v*0;(i&x@8^BpHK|0r`oUp;b^Rl$PD(YM?aSm$k+` zW+j}N(TW=e5|}hqX??7;KeHM_Ecb5*oPa`begB-Ls1Sfw3pWs?3IX6q&7qoCPqT=P zmNZq8Ohg~D6QmR<)+B@CoSA^TWXuLEvZqXL&Z;E)aLyh)xl{zU54Rza?HX^i~b5H{zCft437vPn1DmT4}VM@aN!hH^#zy=$a zIr5*9QS`PW<2YsvKt{cJ?(Z>{c`suuuo*a?0{Y)h0Y4QK5M)91H*)wyI^+ai%(w;0FOYY_c8$b|LL=nR<6Z!d*D401T5_Z+cq$7TlBKsqnZ(*~ zDm4rB&Q|w8%8G3un79l#6JAq3f$?n(3P(#`S2fQhHlqSpwep6W3(8@M=RB+y1ua2A zxUy8F9l=JB2TELKbU%e+^`=GG20)^55g$YyExA!aUQ1e9B!^_Ju3gTD9$g{iYq5v$ z6)h=Z;cyrQZLZK=7NEPlFAyy`N-~cHXBgy@Gbl}Wb+?r!!)D8p;HAsa=y132=dVhe zOQBoESeo$$3`N?nkUsxLi}chJobf=rV5PrVmF8sGT1-ckbz%!Ee>8oSJE@E$a_n3u_OXY%)O0@0FjG{UJIH>o}VW#k@Dry(xQ-s6+@~$8z%{=wtk=7vTQICeg!G~Y z8oSqQeVhW$^Zj6Ay7@XR!5aBjV($9tN-~5&YNo@s z*67(rJj6z(_~F$P5<75w04w*wkX zf|j*wj>DB7NfhJX5+8r~{ppTj`5Sh}@UzvDcj*F0rK4DB04qV}N(@^tXaMY1BMoAB z8pL4$Ap*(uOB>FW2@%zXU*9X>!vP0)_6O$Df3SPm{wTValsY$H&mVM(M}9zQ^bh&$ zAAIR45A@|VJ~#u38gTRy3c#3a662IX>PBJ&3(=BuuV6a}(w!DzYpEzAdRKuf>|--0 zd*z%aprXu4*p9I3r+H@OS8NYp!#Y2q$VM#`;tVcJn(=j%gx!Ce zCy|<2psTC+apr$d585xV$N_>hJ*`+Lbkc(YD#8L`X?phKc!7hS#~=9-dbGJ$(XnvIXoJrT0%B!cPL4pr9AiZ96OQHkmfT0~G z&J+n4)XqJn4uqw3YZ16cYhZ&X;>>U?CtC98Wi*K1j@~KtTimrrD}yE6vkW0(!u-=> zGOf%J!hktqq3tz=7QQd-@66jippji5FkxgIhqjdZ0L#T1bt**}*)as21UDl8+6I)# z=0?PCp6K8vG(B4KpG!&aWwz~RGxHD0%wpzu8DI>Lg z#!!|dqX%UdYoJ@62<@bX=q(YF%709iURPY{L*FQu+WzZ6X9ZnR zacpMb+!`kgAW>;|V^_v=if->OL2uEf_Uk>Q&f_Y_v&bJ|-Guc-2T{*&8Z@pzkTA3X z30MG%ajCd)6L*fl(YoU0gE0hKxRSeqZoxMq|3h%8HMLC>Eak0?FeJ%w;(KqP?(AI%s=;38Hv#?6lzL zwq!wY}orEBku|{ zmBE;Gz#N`5T=Uhpo!C$&c{_X?WBCSD!;oWS2G2%F1MrE5PvQY%*?7QACbHMf+i^Tb z+U<`-_P@E9N~ptt3q|d1H_pf&{aUP>o{-&((UMzK@p&w6%wbTh8(tOmS71xu-^gyX zWQ;1sU+oQA3Je;73cY0x^Z5^v{V-K%2VpoOd)Vo01T=8Y6`aW^pODZ46R_=Q0#`Ke zMB!-3r(!sDr{N=rp?8^a9)iR`0BvPTJQLYNJunN23i=GpME1|@R1Fo~4!asVvcFm) z`?!L<5)^h3*>i(P-KP8Q)#DG64=NJvc^@dcg!RH>9c~mXWkUKeoP(u1*ak-x(KeU% zE2YKGN@OHnu7dXOvDnSe3b>@*e1}W=3jrYN$1DOOG>+OKWtaKT6;8I2S4f{Of@Da) zL@Ku?PepPt5rD`LQ@0?d4jQfI!_1VBe!CgRd(hZmM&Q~LvNEGh=jZ?tj%xX4 z8+#vPZ<&luQuqiOYe4)2qcyn{70j)YzaI;?!3SrZ^c3(4I&ZA@M_E>T13@V(PnKmA0;}c6y*c zNPCa{V*$zriC^0Bb*hTY>?WS3${FXG-@Jp)X_fi?)1ci7-01?7f5L813*teYM&YL9 zO(^D^*3ey{L7djW-Erv8=(dxiPy{7U#zS^@CXdA%#{><)6Kf0?{}dXu&S?=xBrbve zNh`C%_wJ7H-L(T2op3K5<)|d#`(Ek$j(z}rUobm-cl2L!-}gh%Mduim5p`5%{XVA} zB@)D>LEUosf)8d`6rCVmk*90Y5e#?SNnFeMMmy5?G19-3rB$RK=sMD`NJsj&kgH5U zd*Pp{F%?>&u8Q=1og@8#`StU(N{RFXi1bwq^#KyCIonbnJ0rRVK%tq!e|pXLzrlv8 z0XX8{Fb*A8010th$pKOpnD=}Wb13@8PJuNV=a%4xj5-#^HxWw z81b6IqPg}wv@du-B(Y3%mABa(0D!3%v*H(?FV;KjUZNnUm^fW1EP@Nhh5t&?sG((S zL)9H>TCxBLo^-}Xgn!O~;Z~8Y1_3DHmdpGTE-jGryMPKgPxD*DylV(`kt6(4=eZd= zV&|ZXBzfgxdoM)5>lJ@8KNG)+{eMXN&DxKSK$L6J>`NCjGkzr+__om9(USV{%7|Oe z&m%S-k8C+l5J!HF1^yFY@`a7^b0)jAzrHvXElXS2jLny^ZQ)Z}4QgS9eMw&TI8E;eS{r#82b@+TFvQA{M_Ps(ks zdDD%t5_*n{usKV7BLvhJ!okl>d>kz~8>t9dx%-1{sS*?F(d89bdUk2QkVLdwa}@!D zH(hw+3#m1G<76`{O+}@6?+;(Y`aQin`yzJ*tEjfh0bzm$D-95}eXLD*`SJn?)yyj( zEOcekqGSFD3*jSRhM(`QSXcmws1vK@Xjv7Qzg}J`q|TGgQqkp8)z>)4J9#1gn2#C| z|J!WK{0C$6Q8;-NP9B8w+^6pQ1_iW*s{^q;q3zgnH1U0M#rfmJsP1}V zW)ALwG!cwxiC>bw5_ylZH`DpsJBiWTUquC@*J?d6|46Py!Ls&ZgYCPzb`gH&rsG_? z+NSN@^`qOk+KLq}MDM%sn|N{eXa7RYL@tO6z?ZwX;IpuCUN^SLJh1CSoSqBma`~+3 zBOJ%zyvdvUMM9tKy6(r4Ei})pds4Ua|pbzW3)3b=r4sza! zDyjr$qN_@!E49rSOXd-#Lp|_AGtgj0`K=%Y&N0LQ8Oyq?-$~br#Y!mH<@dw6Tpew~ zHiVS1TV1Eky@1xiOA;`ZFP2VDqAy#P^bhqVmNX0AXpx$u zw9X-srE-)2jwp*z0%&UPZugzUv)l=Hj(Ul^cinpu3iaNNhb5UBtCy|Oc_F)f6ia^9 z3%|X9%?1#iY$mV+Hj#L`nIKOZM*(RlVpPqSfP~kVJWB~#p#ka4-_N! z26wMg9_UBc1(!HV@-Vk`_*uwmWizW#iJNsC8Hw><<0UfzxVF<=(@9YG(?)ws-V zSQQZfhWlmg%rT#|zB_|44t0m8*6yXu%)=R5rDNi?(o+W9H19_ zX7u1lf5tG7&{j(l*e0Of@*yk)KcVJt?3PHIl17-1Y#QgZGIn)LgfRv9=HnYWF|v*~ zG(bpd0MAW}48SxpIS@sO@(c#Rn)M?DkT?G8q@Tx0Mb>o zGNl6%S>~Z=AM#Q(8|}-cyN~cfD2ThHv&U^9ESaMq1CCEv`+1P8*@7}(#(@OK=QJ>$ zWapvC?@a&6^cm3|$71 zF15Q~hddK8znnLhp9oyTX|dWJUW(UPqhqAM_`h5`e$A#4I% zUc&BZnem8MK*odp=A^#VGFg*Wi-{uz1NY}pMN82!(*Hg}H~>&Bm4;cBysU(pR;B3A zeQ1Sp*S37A14 z8{*{L&_aJBGZO>W9Y)R;svk*2y;dZHailHqZv6{4gSSW~eP{CFwRq>L?7jpp)xl)d>0m~Yu(i*Du;`c&662sn| zl4Kyqu2NK2yNa5W6Lm1K1^$Sjx29qZgfP&lB2A1B;i1`#Z86v+h9C9ArTMf=Yllzj zQ5IIp<8~FeYSXK93r({_6kP#HgCMaLeKB%z3hNcCEOxbmx6s5i-vAn61u=g?h&MPH z_vf5m+}xI_(UCSuW(oEYouT>~I#1WtoYk6mneRH)MP%PD4SZ)wN0fB zcfe_vks!`h6KHm;k{&>s6nB#)26*#T*?g8Q=q(bF!8W>8^CnB;=-z_t=zhwoVT0fF zqUdF?N&+ksP2PcZXfyvFxV*#hhCT$HMIJo^EQ^1H!^A{b&18^;o}nn!7r#tXFlK)4 zS$YRXpx8*cPmlg^==9di#JSPox<$!x*2Do zPbiq5i(e6>(;m^v4F!9*>P>C(bE7$1Y2pFyaa6rHH+!OM@S;1(Lkn#+pZOzL!A_~) zW}ne)3duLt=7l3zsfi_+$taC=XsJlT3Fdri!Mp$L+s_bBI^&pdgO)0UYAe<0fd z2ri1ddd+=zV~joDV%3^Iu%UPbO6E571L6rzErZ4y(pXIzt1~lxT5LO4xM`L?3tC_(Jpa<2}ko$T8WnZL7IYq70&QR@SL<9YrP5EVoQT#H^TSjr9 z(`VkO)$Z6Xa#^H& z9fFOm_@?!=Go8QD6m6h&HEqXF*beA_Dr3CKyi%~gS6jM7JRN2TwAeK$#5E+k#R)XB zb6G1f;CiWn-`9#yLME z{Apz?d^b*?e#i7P<#PsSbddTw+g|C4DflY~B(U>{8%y!K+TbSo4*nvf>)#ze%Q{?( z#ZW4kxHgA}A$p9N-@iEZ54JFU%=}5X%mZ;D4B4GL)iMSk1>yK98@co%2<7?AY5iyf z^wab_NuX;J<%7LVsuB4=`5PHAL+ zP3UI)y(@GW7Jje@lpKK=Q&~L@|B?_0RK+-?oMQoBj`cvH1d0>rPr*x$C#iP#lr20nccQ})`q;%t7l~#n0TTiz znje11d^;X=%W|=CbFvxcY*U>wArr(M=H4ghu{WAK@m%3S1@lw9)tfKOL<2Z9s{v&E zIqbhx+5h)FiD?HzQ3l&j^9lQxCuA$(0@ur*M>*V}T-$!zq(Lug^NvFNS=+v#+wi-z zd3V6ZYuoqV_vA>7M4-dk_BVQT9In;%#ydvUf9eYp!uia)6k($+H{z)+?W@IJWdgW< zM4p+TO?@L^d(2JaN1sCV7EuYXLFHx44_}uBm)H+#)3NwkAat2M^n%&^%tl<#X4s#vZ6x^6CWC-FfwBAMD%6j(D_$`JE1WN@G~WIo2q zBd|ndu0l!*KlZLzl>+giGvFxRVqYLGTX5uQdEpa0KAZ?_TTX zLc01wGT;{z{uIDh_jB3Oyu2}mLj($+T(Vr-e(ibZRE5id>bO%Bs?l}<%DyfJOdx-# z`7n@>{Gr;?Mjfo1J>CF{9HQt=8+LM$YEe25PY2vS0~FlL>>{|96~E@?Ez8AaD}esB z))!3=f5-U!W+AX353gTqS2hYS@`-%;q?o^N2IBcBXx)rsSqgqi1MEF#V@a-qP1m+} zJa+D{wRtNbrrP$AiNd+zpMj+PCo7UpvkPPO0JlY;0)1|^`P{42p+vG^bjT{;%OgI& z^c@a$rPeA80`{~AbPE%k&sn)RJPCx) zIYObp73_)%%2KQQ5HrRiz>~~fuUG;+DJ?+rq(-2+oTzSaprW)^sdgH^h5A2S!Ty;I z8zxoCJ8%!t>h1*sCHX8V7D^TB$X)?ZhBZ?>eayRIz}E>B0fG#(d^wWdR5hVF5>xqaz6Qm;<0@bae%4 z*R~(u*yGJGeypkYuPwq)w>g&fGzx{#o`#v@fPw94n6AC1X#YF0EJkwj71EJq5v!G? zu(Fxx{rw4wcJx_Fw3Nuduy75^N0~cc5{cj#IS9WVi^}HJ1bOoTAlKW~lMSd_+rDIS z$98Sr7HKK{W-WhPAj>|& zI0-P!xwj)w_y~8tXV1r#)A`GMTmkxega`%f&JiNW4^4am>|Kwy<5d9gwV~KZ*Kb~CB;!ALXHJDa$YW>BZb#4;(*>f9%#@L z72WW2ptE~(c*fyO@*{NN+Po8(SNyIv?+CsaTlEn*(fEPBcbnd{AA{fZ7)W;yWhyN~ zB^!da?ChacwH+h#wYpys*3!vCyG8b&pw+33V_bXU1}3@uaihNXJ-un48cy$G^fDhb zP&XXa$P)Sp^YAP_c1j$iW93fqLDJRFGbHCCOPj|dVlt1*B}Y3?TQ;hDRqYQWMrw7H z0^k*ilhgy}%$7z6tk!7mLQ!G#`rkP}IYsb~K%^BS!cNnQ@Q_V2q>k_+ow* z$d0aUGaQOZAsQEEUwWT<<#E7a=Y)QZmXe0IeIR|SqUnum2 z?6LHk^SY+5nlP{>$9UHqP6F|K|CgY4EB=t$sTQ?2$_6GIxJ@nF8EJGlh2`ZvL|!!%o=|*D(A8s+J$pz6aQ)i~d|Rb%Xei{vCkPss51#=@;|g&8>v$CVHBfX1^`z*=*#SPwAyjTH=R&6H+_ z(TT{dc2y&Cusn1TDAQ^y{U zl$F8wRi0qs2YCHTZ(2R9?By++X0|>5iw#kvd>xG6;0+djj@SKqQ_HZjSAMytWXjzu zH*7=7cft6rc@qlF3EB&*$^aJ6rh1&5-;U)#aN6$EqCclf3U}#+Z9z=x@R+*X{TOY} z)#k{(WxU{M?xD2ZD1Srh73u{wXCAA^M|UT8q$*zGQm^}hargJbFLDJzHs?6r(-WhP z#J-hXdZHJeWo^7;zHqDlvduB7Pdm?(&XI549bgxggq%(Z*c01i z4w0WIw8eu8a6q_kBI#o~bj(dGAju}BpI+FizvLhVw-kVsmmQ=u>!&G9Dhni}7G_|4 z7bghZWY_c&P~hha9k4`^`U(fErsQRmHYpekVO)i6Z>LiB8XCU%PMiU*xK%!Fkl}f#`g4=Ma_CNB*zL}Ag*=LV(_?QfWw{Go7e=(e= zgq71s3>dJ49v#z1L2mH?37%+4q>LOwM{uOW zcQz$&f^WwPJl_ea$jsxOfQc#<7$vpB?1oexQ)iiS^BXL4!_HGr!C@7>M2BVfNQfc5 z=B2ESf)eG%wv*pzO&* zDibZa>FA$k{Cp{s&G;44J31I2#uM)T3dZH>xez0N7W&YupjIiFSghKAZyhXalBNm9!LqV|ZbGt0oX!1_G z#)|>a>kz6d)jOCNm!s$GM*@x|)CUu}TPGv}Ufl74^@>nmT=)@wzpS|06UGnfp<&5} zULPuQLvN?{ehRge)!tFS-m(-Zh%T3)L96=$wc(mZE`!E-0CgQY0G!e3RVKTahESxW zTv>tnxsjC|ZRyzyfk_Q7z8-G2dE z$I!o1`aA@KVpw33H+YGqP&4tP60Q$LZ5(ng^@NXxKJH#>8L24g)khhuxT}yTyMj=l z^pV@L=d#)A@m^<Unv_za3v*h6t3m*z^fQ2q=#+r0ls~9{{zz0>D7Yb0qQ>MvsFs{zn;vtNg{YIja)e9V3bvzK3p`Sor^Og@FkvhiM41-I zufzT;+;4NoAiDN`XzT0psJI9!C0|CvGcV&FgB^s1n=)30dSdU|wRGFym#769=tI*q z&zfx=g^IPcg>~TScwJ6UkPiB zo+@fT%I%HZru{4q68g(|oW?JYR}zYnnc|2`yb8tf^GO)R`dE_pNjg?Z8yV0mC> zP|%6r2E}h4<7JR1f7}(%Skn;?VB$%pBcdfw4Wum(qlTa~gemN-jB#Lsfsru|t!-cG z6v;MgYM>5@JD?rxA;PjCN}Jb7^3O%f`Q|13YB|pb0{B!0lyLv+HajN4HYW3$C_AjF z72tvQ})@U(N&Z5C0*wjJcqvZ|> z<(QkX*Ob0SCU@Kx@bZ#UjkZYriGSG&n(b`y3-(Vv>$W> zqCRdTX2?&RJgkPkK{f2xafpItG7UT5(XfM@-bb%#KD|&C3y`XER`Btyf?`+4FU;Yj zird?>=&>$|%+{Z<2mgucG}U5H826l74#UQfR;RdFhcj}Sw|>be)uLIvOy^40c*tQD z=G==x-gOjOC;HYMXkY(B`qqE(Q}n@dFMHDJ0TUQdk(+`T9?%Q!fAO-_;3CmdZ|V?E zJDA3uFp8E^A4uiX?#cSyWcOsKXD*yghyS~Y;Pc3|adh@K+S~^SqicOsru8wjlRjW9 z-0^l$rR13J?68@J^JuaazzkOIwqtEIjBkD z{+0$y`r2`wr9W8fEd9f(yOjRI8=cZW;%-XcM@G(aO8h{8?E$ zTFg)AzPWPrYw${TV3Z4?cCa-IeCsTd+o;^9X(z8|3%)Lz*kkB``-ykAQ9+} ziW(6$X`>C*DzR9TO6&;++y~Erh+d0BHC~m*YFkPY#Gx8I31s(p+EhEJ*S2=L?QOMc z2Nb6!U;&|3LaZ`aWpLQXV=KZfg9CZLzqR%`IT=v<-h2P={eNCQA9D7v_8Ok`OzU}` z^{k>EV*uKBs4>-5Z)`bU%~iSaO4s`o>F##8Y)4M-xJ_n5Bye$3Sp zV)I|gDrS7nw*|EUe~Q&{=Rb2Ne;%>DJa>222V+$4)|*8XqoYjbzk?c9$Q!^*5^?Z# znZiE1-v&(E@;Y(S2rft3ZQ6e|@^Ii*dsD$6{_tHI8jKTW!GI@ZOR-CIAM??@mnPVM zT)o<6_YY=#kzC@88<{8cov+(O!M~i91?>qM$DM*m20o|D3I5z2{OPtI?EXmB2Z!hb z|0WImkO%{hzAt?_i*L60g$UEq3YlHiKR|Nq+Qa3@4RGre3id7c%wcoOxTZ(M(l0qk zHiW~ukJU^Z#qrH1c1Y=%@R7}WQAViJeBs>S|F z)Agxt;?Q$%e2}P~oSY>iV0nasjVqTa)TsGf6a!G~8`Cr;>CFU$`EXcpqL=#bIL$+i!B8nasc21n-UWx(tK(3A}-F`RlXTg67GeK{>zO)^b=?RxRW8 z_Ff}NpK}>atwuAb|Gl>Vh<%9>tyu>^->t^qW~?UkwG`LXcYb&_^H+`DMBaZA<+OhH z4k%+9;XDztAsi+Ir&#@@mA4#biHgTUtg86<_RTGIZhX$9l`*|y?}|l4Isi3EE$*2r z;1ryqCgL*KG(Vt`XDs)A=Ou`gy9GbH`~@8GgR=&#$P@q3>xF}_oW+2J+XID7|KRL+ zBzmCu#5dH5_+bzIK%@Ii&VXTsh96ew!w&21S~IMRRQIsMTK0Jj3+2u=N?|azG|-&( zzi3!5%Q_a9rl3COt`=`8L7~MnG7+~pQuwfa-?zPQ{s>76G%+_7EHm>na8hVQX3Qbr zpKbg3Th(IvDc7f&PIuDEMVaZWiXTi?osv#}c2;YSN^@3Mj`bIh%d-K$1M}t3u^;AVbxgY>{nxKm$Hu8+0&u!x!S8_nIg2~w z+ZfQtxv`o@zw71{JMFW1=imGJ5u^l3O(0!H$W0vmeO?hYc&3}ES##2?9B=aTk|eRc zXWsZCq&O=VgMbXD`{6W7PERWNCC0s7lY`yDxn&)&cN6t}Zu>f?{Sw{83l7mo>1VGn z0(&^gg3<1(f}J_&u6jhCOI@~%O?}elg(&Fd9tQI#{lxZ#+#|b;E6eTO=9Xb&J?v3l zwDba@HP1)Q)cKX)&doY*Nc7-8fqhZ)56=lrV&+(!cQnwghi|4)Nmi+6`U|5+4_wuFJ$!hTQcv%r8O(8A|+E!tm$j z?7R*}p8V3NMFsEl1#ND!top~tWKFawDE-NQ%vLk+6IpMKY~9ZOasL?m_RUdQZ;gsH z%{KCbbR#Xck(wcmOi&}Av(?Nk&Z@=`!A)vp*{xODCPgjHn!R9LC>bgUCq2b$-eCynbm?B@4wit{5n06 z?be0bd{tJ#a&_gzbXUM#|5DqPt~Gp}dhTWmbzv+R>1p79=GoOiGFRV9L7TsB&>x8-!YiH^O* zA4;E)SM33n*6BNa9Ky4en|CEeUH!2Ut~}Dl!*g+JN%=4FzZICxN=4G`BS!K)^%#o) z62VPjI#(K=2Y1j4%ZCRieVo=#crZslp1q4dSYqy2b=|3}h}Y%D@6-n-E5eUhCdo_M zslLVYoTW{LN?JH^o!h<}En%;#lkBSZI^fxnz z9KUMipsvcJr#7^)t%Kj>RKQ?bGwqNjF;5~&W{ zKEs5z?{?b1N58{+x&%w79qSN-NITx-uFUi(F}C1HK~vhwu0N_%K{2=o#nRuHo8?1~ zFvQs^Xs6&z+9~Nx*{K1v^2m7NSILpxAV;>w6!E$_P(|VB9$u;EIYBo3FdgjcgOx>c ziDY|yJR$AQlJR2AtV`y&@$arP6Tzr|2G1j>Y5L5>O98hV&nIS0=O!}w7wG}fplaJq zEZ$)7Dxki?!ZL^#MpTZ zDaq@gV;gaC8IJBh6a@F!=%~-CCNM;>#vNx{dsMC2kb!PLFXF{a|Gb!e98;li^^S-$ zi=FX%t=qjZc`D$xvrmX`m?f`V-o^d~nOK4b@Tz)mB`;P%7+xB7=`Mac)5USwU2K0+ zBYr?LCoY+jGs5U0W?X_iPw<6OFbgqr%?vll3vJK*~&|~)PF^~O7l6=Q_ zgdejmU)=Ov)au3qzOv}ad$?WUKEYqI#({!~DFj5k$w8ZaIXR&mjyg<`<@N-&2A5GF z;ys=0fs=(F5efRwn$bh&t6XLqow?fI%lr^gKi^dgn`6I)e)D~W}*MN64kt`8!Wpb}}5aE3`YGMOCAz*$6oF7&7;x@}vjjl@k zwbycGh!Dq3MNabwEugd5c$zo5Po$d`w;`J?#b7U~uj|TNN2XJ46O-QKCTle$j=Om2 z@`4F8!cWR3fZafLiE=S98abvjH#;As1=DZXvg6` zZOkb{^eEcRZeq&NEBS@t7;40H4YwFwga1_Nm|o&*8r|Go?!;cSfoqA%S3nrGFO-@b zq@QBhDQT5e;e`V#Og&{kqXmXL@LO2pJUVQo(?WBRsn`F{(*X4k1EW(vxCh%i9OfT* zPwKaKnALFG2rUysZjJm2PV7a^N<6ZhrJi__M;yXWVR;(1St*oauO<+PH4mOV)=#wr ze{q9CWXeFxWaA?!H`F0lQux=DG1W7fRaDYVy_zLT`H=zj+9gkQZI!dQTLX<>&}bs& z^J+_+hc0O7TQS$Wpuu@)mm9y1_V-_l`LWLGeDxhB(kX2kA*kiyxxo2w5lo5yYO5ib zc0Y>}K0*Wj*st5ojfbbVAWmWb8sz)phOCk%C-HXA5<`jU_F)wBONsXIM=vrTJb8E) z37F-~DOZ^nJI7|dK&0jPN9u(%(z$g0aDRsF+ciTf_$nCfa`!gHorz>{L+aS%js~rk_3&bwmQ0&5S?5 zUXOl$2cJkkH$;=Lzp#)j)Ub=|2SKU}Q0{}!t`ldjU4Q)rT5POxEA@g~&KrCk(}($zMWmu~zA z^MuOKv1hN?Fm&r?I?QL|g3m6T)Y%uaw%H3OwT*~9x`QeRNI%2Y9u%uSx87+xgh#7l zdav$f)iIl%-z-oINVrYF*{>)6(_yao>c<3(_X^^cF%N?OmE9x4k@h)$KEc!_R0uh z&m64Pd~qa~JnbYA?VDO^d(2l^NsZ#SYs889eco?%5qmoqTlBIARY-@4)fT^K#Q6cH zD?XJIyvXzKJhrL!u@K)xow^sov3EjF;s;D*B;GJ-R^r47k@&o-X!Spwn8(9eiSh~2 z#1-Ya;XO}&mQS4aYMw@`|I=xk#D(_z0I64DYn94*;2cafvr8h?789MA@PNefE++^G z0q>y-uE`c=uZ0@scyqvck^x@6s_M$9B$NDKVmpr29Qt?RPWxkwS~xjpRjZkAKJQQY z6z??9xv01gEs~! z$QYGDx`T|i$P%PSz#`y(#s0A{4S_HHHTz4fhYI=Z-5J2pX&;SDV-X1I)@Y^HNmoL7Mz69A2Yyn?nJ_D$B=b@^CN;Q ziV4TNX@Yal;q^KWKu9juibaS1QJN#^x45zEi(yzg0v8-ko@Ev^+&>L|6%lDM;r{GZS(H!7P%0)%rylmN73zkK7#YeLY&XiQ_dw5wBrV9ml6M z)b=f(Tj$j`K&6fBv-?XVufBwoImtWt5?|Q2_<@r^b_&Cab+K(^%e%>?D9<{>*16?g zsnIf@ZrPu_N7sw`_EOjhatEI^irsB_Zp|XTcVfGsvq<8w7jAZQrjuZ)7)Era6I*GX z9zAlAn{$@)(1ddpYkd#p+eUQO_H5$}<&D#dHq|;ym#0+~bXTBWx4a?}pCit)z4q}C z<>4%^gk$f*Sw0CeM&gZdmgeKQSO{y`@5GMa>8!*x$FYq260GHqmbE;kFRR~k+Pb)? zdQT}+` z8^7wHROK#SDcl)ED8*xBsySk=B^4MF3oe0m1S$FQT*&4^ZtVlU}KR=A>TS={~hnI0yulgR5l6Bs?WoObI|Lfc=69D~A zU1_NPVy>vkdnZfFGzRGRE-_l(8C$bnIQrsc`(p2HS=!twda;%lo&G<7QZfXxz)k!8 zHO}H|fEfBd8o5I2@Y$eoi1%YiDCG?)rfxA?l2{>i`|O$_gWR5O9h(k&Le>~99b4O$ zv6>6B{PI812zU|&Xa2#uAyi+fN)}4&gmLJ=keDtm4)$lZ+exxEoO|gn&QWGdQHr^n zT(5o}e!HiZ&y=w)K8K^vSPSv5m2$Z+y4`=r8na*Kf~GGptev9A^R)G}J5}H=+HMYB z=M3(_N3k0}7@I4gALi5^q^=H@_&1~Vs=pPwt=Fo|h8q%ozPoZg2O2Qs9V{C|z?%R> zMtN7Zx=l2Fj(-sjBwj2U@?t74IRE$)OvJU&MX&}NFdqwQ2KuJd7bXOL57Q6`;p}YA zTF9XudWGT}`0YxqkHw+#)O}g2yKH@3`^P_A{Uryg|Ne>pE%iUV>j3?q^#S!ei^Ug) z!iaE^y}8Y1Co13~^b6I0+q^HjMvzLYMnk&xA|&gL=ewTp6a~P7@{`$J3H7_H4gmT6 zJF|M8T|80nsUwbu>Zv?YP;qYh0Jkrnt2tj-!JK~zo;hIsr1|&^V}Us2c!l;r{GmSD zcLJ@XI5XKnIMGL`HTA$i{5g;Mz=~^-2h>-LGwQrj)JMAIi`S_BQa9eJm4th_v>UG}OJ*xq$!0W50LeB#K|Kn)f~27hL*D-Cw+pa&w)N z)-5<$I`HS7QXP~jK5U73f5962{fS+DT@YqPKLnlP<;4CGfd;_WC0}Gl(Vi>ldKQ$$ zS;~0gf1NnV%yAM~>unPs6w@~Y_w!Iyp{XjZk*jm;&n(d&Vpa;4X~!NN0v+JHx-y7{ z=54USnA1#2D$+CLfC>v~zFZEM<16#LK?AapTmH|E1Em|7rfmExaTdQTb!!-Vofcuz z-K48Dn2l(c>rR<^+j|^&Cz-f?Ii=DDF%24@xK4UMSl5tiNft_Ft*luf8!Ma)3O3Qt zUF!rPr6B(m$i(Rti&oUjQNZe$3Bli%m|RJ&2J}>1*V2p2o_0MRYr`d?B%cEV4Rsj5 z18{@I8y_k#@JoMAML@%lVn{=&a6J&QI;W)|X%{stz6utVY9jyw3r3{PDv6`N!V?7> z9%_z1Y~G+spkh|psC;x`9nseiB9=l_eWRl%CLij0UoF()XL4XrU>ibRe2JQwMgpfg z@0+H@+;z3^K33UJWLDYJgH^Us(fr2KdZM1B$%5*;U9p2rlcgj%N zuK7q5G^fjsrfjOojh)WI<-6i--o|9E(I*S)(`C+j-qtrqeFj-&XiXel&1<_GJm^%T z?UeVk0n;*YR3?3A@;nRxLGegrWfC~FP^?8>jitFbNn0Z zi@xl@s_}a9ue|8=Z{3rZlY9*Z6i8w4;j7003IiS~m zmT&4)4<>N*9WTn?!!F~*xbYkbvtJ3l$~L*AMg}L8%mJJTqO1&wfW-)v9WKgm#@$#6M)#Fo=`z6xvMzyfRf?69{HpCW?) z=Dlqr-PmWL2XQ;j#T@mLF#zqMi>|TD@zpsM*br;}#>`=5`m=ds&*oCf-jHDK_XL_k zBNGt{PPn_1lAX3ovFj>m;w*it-Vw&^9xCtPX6Ex*OGwn z5+V^f)FCnDtys;M)qKlTi&x&bw*b>@k^DSflkA0ojH3IlDaAHn_BD|oQgd66e#%)= zgxsI_S#*ilf+Qay|7dP)V1DX1Dh&n~gww}-3wgBcDi&M9(15t|Bg=wQU^J*n>Irzq z7IoMA99ydX{8x1lgE+gt$Poc+?-l|zCMSbX{sU*w_N%n;T5GvwTsH-pE)%w}LfZ&v zF;=t0)IzI}L-76chEt(~toFZ1EsP|!or<1FecV=bYEThhht1cATA+KihCmyW9cFTb z8j0&F{Nrs;M4!or^d@nAF(;lmJWig#J=b}<&gc5jUk-fYdYkW1`^h%O~0q zo{Odo@~2I43Lm45c&DMkI}8opp=p*=6pt;~_hyWVlUcI|#yR+yD%E{3yCy(e(mVgh% zEMN?^-rh=h#Hh;sb)J|;F$|>6i>bd;6B9;x7mi`C#|XB1khA=z62my$-tBHr3SHtN z(j5Jk$nESQpZYl5Xb+1wqjK@(v+%T21q}8sanB7~C*cQ%vMsPRmtx z5VA+JoP9tuiSR2pFBxFk+PAE11k+yHqz}exB49wmG?Ra$9?V^1;A!6o;eLNQNXrSY z>dGYl=iH?>*@nP8|9iUc6g#h=ssFevnDPeGlw7KORgt_`XqUaDa+Y{{R_}A# zjBu5cC#shu)$)2O*SmXmYYs{U9cW0%Cj_%w<(t65Gw9A()Z=>cG4hknTqIQ5>_Futs zo_Ynm+}ht{4~~dboa2u|t{2z~{Kt1#Y$;AQOULqhi1kXIsLR3TyQVJ!q+eg31*E2# zJh>aN)e1t%jfU%dGpCe+Rqs>e+P>r;c}9o7X)HoS*=-?g=Rt!LC?A?ZZ*}qs?)_Iz z#;0h^UH>*UZSMM!uFSI~x>^J|_zA8${j-h)la>$VPtM|Mi$7E>+YIs+HY6ZxeIe(b zJs(_q44kEI;qGqoW}D-snFOZl9E?a~B!TOVE+b`^Z9sj!ssqx9l)KK-3luZ%Z8S$% zy1ht?nSgDrTZSNLE)O{m-87q7dL|;LS>6nsVqMLj!t6Suuy%KMq0=T4s9UyzBJYF~ z6RNO8PpJyE_T@T@$MJ@%0w-n?&2{@#Qwo~$VqFCo!j4UD6)#|eSL|($Mff8(&e917 zRc&Y<&*7S{L6a@7NEeqL4%@UwDY2GPXXz#N!WxifG>Ttg{F3vWN4DoQ!5WL)_;jEn zb6VQXVgzdZpuQds0xHgFIZ}qWV>NEWI!et5?J1jl5(0wtXkGyAV$k2YpWxy#YeWGs zi7^M8)}SAPskIe+tT@amTa zuhKkf5PzEfKKQjpa~rEdZR+AGgJ1jf_`e&!gj>Qf;a6oAex0Gl41T>NuB_NGm&-7#0u>p1+u{{7WDnkQ<`JYBHZQR!U{SzpLFVmu! zx`?XU-^JCb*M`Hhy2j1%Ds4%v19AiNK(K$*`erVLbf?) z3E6HL2eN&C0J4E}gYYfK;u{=W8Uy^S%Hp;7*=o(C!8b7@!=AEO7!rT7U9S&hVUX%A zutT5}id@a>3?rJRvbdsK^)@Z*f|HGg!4*aZsBBm$I8zwgmEXZ(%dzX^QZ^wXgz&1a zq>S$2zU6pe5l$nC5NR8UOLoHHGZW>9*HsZF_a<1(p)$GG78w@*Gj4H(wvZqEdgWjw znh?+GAyfe;yRgXA^9_O;3B34Iowu>}aquZ8-1|zn=Wlpnza+=&@A0#~?ksNOh3m1K z8d+E9?5(YBvz4!$rC&9I{H=`kn7FpjEn69M=}UPOdFTeo@;z?e zd^F}&12OvJl}`n^)ILd37VNVRYTf57C|D+MTWqUSYt{j^z1!zbtKQ_qKF9n=+h2Ct zW-=Bn$>&78D~MJ&TXGE7H!-z2_9l1!bsX@D0-Rs26>XsggdNC8_hSFPbJX>^@{bDz z>pQ^2V7PsZoLZ5`g}ayMJ8cT$j%|CVqux}|s_Fw_%qBxPWsuJs%$>*Ddm(G@)v2T! zbZH$XgZdWeh<2G+zDX?c#_~CKGd&vUqNk;S9wrSmfT_a6-Q*bz)xYv&bj{b&^?^r& z>wDIi1X-A8>Z>&MeZth2K1|Zil@0+SK^^cS_STF(xel7~bJWOstKdpilPSQzfqWb) zTTquz6hW#IaT zbGX<~h|!y2Z%;Ile+uaUsW5UXQ2=4iFxnsWc1FCd$x=vFK|y4CGZPJS6SJtNii_&0 zVpBLV`BNB~3+v(+omZRI$3Ct8hs@j?r7S(|;$_XkgN$BQHK6n9A&R3lYKk}&%H$TH z#b8GSy)gS|ge?XYjQW%}|76ewc`yeRt{H|#CS^>1&q<$agzX(F6)ufn$saQ)EC?W` zHQ$8-4r}w%>898x^v)2V+DQEbqBs{T)~*?e$>?bd(C|J@h#a{S8BQZ%5y`bgK1941 zlm9Rg5Y6z=G%4Gu3_(j0cc9Negiv>@k{8R36O3qh+s0P{J2BYWyH?nGq=03(qjzSp zts3?6Q))l`B5^~p|ML?;tS!jyJ73E3qaVho{JTGE48pBLUc~H+$UDbDs?1rU;GEOa zZoVa_N#K8L3~YP~Q3Gk+Qon=v`MZ$qV0)n?jF|Z)=AHD*^SH{e_51Z03Tepj^k!&! z7=})n#(qXVyc)nV#`0v&IiXg<#+`?n#081(AU|fmP}hXZM}I68@iRppTk!Kp4~j_e!Wn}l3uDZ%$P8(GOr&wFz!8%4h8`684!XFaj8dC?nimc6 z3(Z1^Y?e}1cvq$5wD&y)mN@O7(=%&XMIb>T^Uo0_l@jN&gY^nqJE7FD_ZBO2==kPB zTUo9X+YE}Ro-1uVUEBusoVhYTH#Z#HJBp)Gc26mIBetss2p$l`7&41O7 zmHDu8OpSNob~kxs2n9vYA)vJRIC(0(DX=EFea=EEsmcZeC9&&JQbBhE3eB#9s5Vkv zSk?WMhOyGIRK0;sv2EWmx2#H;cEe#zy>HeB^(I@?PmBdJW*WJinBvHw?8Y6VQrso( z1kQvi`;sl@TDB@4fG&ppii^rp#iL^XwS!czO3)r9K$N6o_#0)@YfFsX85|8%e1mdQ z)e4ydYS4OeBa}XW^I$g7ayo3nTWt@A+fZ46% zVi14$wkU0&4VK=^m(YxlfP@;R*Tsl*GC6=pliKoPHP5d!Sp6w|3+9&M&@6Vna}^FY zwWzM+%o)rp#_dAw6x?mg?PZuWxk3S4V|9nqVnshJY0OVQOJ)OWu^c z<}vJSF2n;rxr;a>; z=Z`6E-N(iWmwH5%|GMTpvSq?E zN#v9Jx;my3eSJKt25n^!BKQ-zbrY9DKYLvcQ?=MVPGxS7)r>Y3 zPse!}pQ*J|ZqupZIPvMby45*cM<)HdO}mr$9Cet@znsVng{=Fi5OxQZrZz{sr?ged zAo9cJ`Rdetw#pGrV+|Z*Z{;Q*FytZILI|`U7YGrpW|sH$$TeX|qfrzD0ER*ngJF3H#2y$!rt0s z$|%LgC^4W*n$t{IK*|WS&Zfp^lD{!>?*JpD@1|{2pG5PA7$;ms>#tDqFlq*+!RKU@ zOO^w3XR{rnOxrPVX-DH@%2@?ObpVYPid8z`mVDUYUb2EwM5@mUwH(xXa~Or}N$?^P zKO1u=+f#nT4IMkTsIKaBGl&f`?><*TaQB5p{Fx2?EiY`oPL>1XHwyP|3-_&wmSJ7M z-V6ozcG8W5;0_TFYeqe<6fb#)F zbP!xI#y6G>MaF~hjeFr0!#XNAIg2~fd<1Xg$tc^fUrZ>h5^)#=o{`+O9a?YGEi5i{ z>$KoVp%TklKoSfQ7Z!Ri#i>)1j7F}fU>EycHm7$LLMI9F+l}>*GcsT8f zZ#DvnU;+pY=jN)ZrK)@Gs;NdSFT#v{f71|3QgZ&7Q|i9Ym2p-e*Ei z*W;^?)oihkjg2S>lK|Jo8(pUP1UEk0giJi5Qi{iCdBb#|@^A!-{O#fxKRAY|@I|B; zUki4u4W#N9p3O+r8_eg%n?J{ukCgxyNUbXML;cJ#-uyYL^Zwa2XsuE zxVlbL$kzA`(ZC6=M^;)HMDh))JZt}h=&Tx)6!v%1L6@^aQSE!H87uG}{Ek8i{2!bRV6(qS(TM}e7(63f+5clO`BwM0+mlaFKH%2kdqYGS9zL3hU zu7|(8AvVXOpO&}s1+8C3>rc}91Jn*_eO&A=lzba4fjuvL)g=26CZ^nfM04L&EP<0) zYc-0=Bc;MzJCcQ5eri3}^s$Rt>f$#@TVd-=>`qEX<6i^+Q5w}FH-eiPBcst>Hf0U| zUr|FU`|1*xj;QOHFp?%;LVH0y`By3ocW*CHx2k5w&zmsM*kRl5f*t6#v9@glr=wBsU z+^APPGu}+ieJf{r{OU%ayrDjtyI)Th&W!)gd>H_VhxQ(Sf33GB?DZyp4_$=4{d6+y ztzz4ezh%7EU3(+mp45+J)tnK()l}hnS`8w21*l^Gf+-e>(NvfgA#F(3poi(Eu)RTI zS$LI3Dd|Lra=}qiJ_Xgu~xV=I{$FeN zXNxS!=uEERZJb@fW5edGdy)D7^buI?0Pqm zkGCqs3p+z1>j4k}5@`zSheR3(%nBWmely3M!K{8^BRJQsjn|HeqzwhGR?MmxR%^*q zM7f(osoJ!4D&3uU6Pn$tBbpXeu5Vl4d{JO^nwgkaKr?ma$4Mt1)V*|%K!yI9G2Kzj zj#KUBSm10~R+iAK$ zIXjSa-|Zpv0bH?ho(_Lwt&zN(CJo!bDRR8gfWq;~<+6t!D^}XjNmnkfk0icaNP$-k z?_kHAETi~vYYTrdqGhyMZp!-7azeDawzL@_-fNSz1V^K1P(U~{mw)Mn?QGiRgc z!W6qY!|a16tQc0zcoMaH&6s?T&1>oIr$Lm4r?4lKlD?Ej@2?iqd&M%npBj!B@I9Lp zg&_=LefQ9Xq@zLftx0-lED_RNz<_f6-$~m^6kPSwEFot0$DGc=DV_e69M+NCv2S4f zIPtB^`4;)b2u@@K{71+FhjU6v$$(emf>L+U@?1EXL>K`zn_TBCqBlrmn;L~a7x8LK zBk|hOaP_+8V;Ij&jc0XdBrhx(QDl@scpY&kVnbNBDXo~CBfT-&(K=7VE3 zx0p9ap{E#QkR~a%Wlx9VwCPst$wDa+g$Vr%2`Z2=`MMHrqPkh;FJ@y~vP`0{U*2iI z$GpzSzLqy46MVJ2`(1*(Pr;a91;JghwSkVK%8X)1$6ztEMVGW{F`c+LJH2>F zZI;p|`P_cOc{+ph7cV%T_E4;lm1+-AscMkX|BG3i>QU^;;uZc}ef*?4tRj>%f=vfX z2KOP`{EFZnl@RSTD3sAlDgJ@)2f%~;@Q5+`SgJmjsE>?X+(7ns6T4&l?I%(yV}C!D zo7ROzD6zK){P9q6YL4-AcjrslZaP)sqWZ{|6lPkEIL=+LO)!MDhR?yS&Ys@DIZJCG8AwFhYF+tdS6@NQIx^GdZ_%{hEegyq|jb-m}U#5Kl9DmAe!Dx(R z7!b>Z()YfB02S##fb3W%?CY~}Fcvm{JQKx~uPCN*RjqI5E*RVTc7X!FRwvH|x8XXe zU4-qVo~5JDb`9-lqTtG+6X-t7NGqH&z~@gnUgSS_7xZx%@@*h}IE%maKJybY@8loR zOl9V$jvG5ax2EUk^V#$BnSWw_@P*nWqaS*b?q=*8So4`l(&u2vfI0sEdZuO$o~ch9 zsJDrNrP(PB%QRhya!uDm99NZ`t?3#(UnfYt9kPGa#^dco5M*ZQPuvLSApskO2j7t$U#vC#!OV(yJc=&^{S>@v_!r%%SqQp!nLQuv8|(~cI1!7 z#e**?jxVXO6FsfoJKgOY2{{`sxWx)pSq;Ua9_P!Oj~ciWPlIiaqdW4C8=dE`!ndrRm|b0T zC;2OVzze3s<^SL)_-V`RYdppOai2u~;Tno-ED@$UuP1qrv6ShlVxnUoL6R%Rzok1% zg)u(jg+wv);^HAMF10Tz{(79{dWnLXBhxp+9u5-pHo~=AHPTcF1KYi}coj#Nc3tvgQm&S(L$*ktV9)r9;{3z(4#~k&Pk4 zhb|DNu5j}(+K`a#m%KpL!jhFAHa^I2@Sra4)N$b2oR(M6v&Ik$gw>7h+s)t<*i|9( z9|&{-7$$FEyW}gk#5r7d4vOnuFmsfVk=9wb$MA6w8o?n=#9uX8<+Te56suU7e<+*o z-p14VkSWOYOOy@rrKa7jSL&NdsT#JAIuD(Xs{9fXm(YjVd)@dUk?Q3wuNsdlVJe1y zOr~ovk7{^F3$ZFI6mIUVVL59IYq5{=x^`uLF)U?$%gHE_*5UdyJ4?97gQ(*+8R%nM z-|1jW6r@!JX@yW2XMofjSV*QiS&NL%4YloV`J;>a>e6{DQ;Cwz3_C{w_4(r8SjEz7 zEdP;D2^c^%!+1~yfwZi}B}pwBaa*I?$ay+S3dL9yiiOZvSMqE_RqKKyn$wKd^-%jn z@tUh*|9S(|fY|Gkdkj_d524`7CkE3)<1tyz(6xj;!U(N1^a1!ug-faW9?=gc8tR9WX~ex_m*#p9oS93b7apNXw+gIbkS^L zFJ6k~&B2(34cU3#RejmLjTi|r=a1nWR9VbFsb>kXqsaXa>K-IXW1Y7d-1X zkw{w!<|{o_wcb;T#KKg>;EYuw8EnBDhha{`qE!9kOq`CveXz|LKs~F`)$9`g;IgF!?_LrF`Wl%(gPEZ7&3%G{STUv z0oq{A%*2Faq6q3RXXs+dU|$_|baKG)CF~HKTLDLT6YjwBAT-#35w2bs7%=Y85QA*0 z8K@|FuGr5(g~}K(kTI(;VBm%uV!&8^k|r^ou+|bydJ@bCQk`U5{R~|;R@)cSh`!Jw zy0v6jT(^0VlSirBeNQF-9o{2m1>WWOxy6QAExkR9zZsK7hY{Vsc@^>>JAhdYpntPJ zzYWAb(E75ff>~g?tT2=573LODcE}17 zW#*qEfX4XUJ z>vl6I!`lOl^9$x-@&fru-Z`yXIub%1am#>Dt6pVeK_2z#<#hF=pTA~Cz4rSqS{cu__L{qAQ zL)V+fnkqhEz4=41VZeIx^E~*USa0qkmx*{f1NtY|o7xmPbiMgD!2U4n&CA|@y}8z` zHx*zBbPurNbpNRp=UsT`MM5b1Lsp#HIAm9xrd4z+16G^|8#JpJg^l|AG=dX&=E6%qL5+%L!5|p$wBen+7)AaYDr?I@t(9>)G zb$Y5AmYyQsGuieV89WBi(}KbD6mh0KlWo6|au|t^G~paG*<8XV?S&atIo$I)z74`s z#{D>2y>7v!8FPaFlNU47cR+gTHv=W+WEpVIpi3wlQ)jbw-C!*^gry#0pH3fS!7(8! zwY}TeC$g@oRTi9u0YzP%a0}Yha4O6k+82LrUqfh5 z|Jwlwt$hHY{o-9fBGb-Y_YbD0?>mN`77cmPW?w|tW(aNe$TXpKj1r;U_5y_V{S2W6 zddDDo`@hM)Q`m3ciNu}Af8D<02EpJ%>^rZ0R8#-|JNr&)(Qx*iO=Xr2(7*%6#Io)G zpna$P-oZrCF(%8tlN!M)DQ(|*Q8$T#*+V}07e49qZ{7$={9j|=>DfSUFa8kroeSlF z{$Tr#mZ-Atz_4w+(gV5~CSGYXobUbOm5z`gen0!pz+ffpJ2+Yu8iax8Nmqst8FlebDJ+xR35JWm!9o@5O?m+=C7z<}5!1zBU@35ipqH&>YG6g6ZTk%8wr z3_Po_*eDOS3_RCk;F;2I;Mu3v`VBlc%D{usv~3i{iRKtLr?zcW#Cr+7PH(m=2nCZ7O&Bf02WfwbBBZc2T zP-dW=DFC1KVcqf9EIX6brvn7aG???7EXW2!%Zy>zK$$Dbu`?NhyVr!wSepB(+0>i7 z9eqHtF-P;8F*MzQN(R@AF3MuG#?W-EQ6$38!iU-js*wsYNPqZ*SWoPYM)`*tSPN>`;`;Sn+z`An05v3+_j(Zm_U6+M4B;C zHuXaW@>K@%2L8t_>C4{HM8QXf9g!NXaJyg2 zXVWaZ(zI!oXq4ZTw^EI3C^e(Rex6Q|kf0=|`N94n(lu?qU9Be}28-H$fWZcxV!sF} zJuG_|Dc+)%h);Lgl=*F1ym(sm!A|?f;1+CmK9X%J??w~(CG1vycUnAWn$DyhB~GGI z!Oxyg?lTmv(`M4n_jKn4QCX=6M2;*R-ZzMI)@H$(CwChI8juBty~ZYT#Az#|k3sav zjKsK6knMyjycN#k9A20N5=H^+-)q{ze)r_>1k65sVgU}-toINEi(^yALb>B1>o;rUGH0l=&=PZDAwx3tF;AEV~D*#E&> z!YSrYaaV+jD#9DR)YUQxOlIS4>Q3WDOpF6#;A-82JOX(O?z ze;B@kQ-j&)=PReD`O0_tiEenl5>!j9Rl3>?e+doZFSos!#a}|g1;!};^1Tn_FF#}S zL-

IPq&1s0SY5Kf!1ILCPe{Xa1vq$k}|Rei%M8bnpZCjSdCCkdj4Mq(sZ&H;29t zzu6-Wli@eX|D*h-@<9BiIL&XQUS^pw4ZnFz>?NDu+^q*6j^CX2q4>>Ea37HG9M2Jt zAHa9M^?`iHoW__am~rR(<5-V96$SpY%1qNhK|GlM3^NGwXWsF?O(Y7wlzl!y8G!Zc z*tyi{e|atZ=(_jeM<%v6_C|yBn>o^N;J?aJZ1N#xYc)TXvID|5W<**uYLL+o2Ff!u z2Y3atuRru9$Z@mFurKWmmp+imZ*VP-+lYo1`Ov!D!oVK5GEA!(s zK{VH`+(+Vv+vGNv1j%i#;i2n2qb+J$36b39<#5j%Y%IM3YvjGr>TL_Ib<@@_|Hw7a z4x?l!MnoGA@jCIEMk|PkBs+j5vX9CKSR!?Jp%JX)D$qMjj5-PG-MrE*SiFyv;XR+67R)@@Q zMB1cHl@i1VnHvf>=@f@_rh86zkB*wWv*qJmjDGGI8 z{0j>rv{9g91Thn&arGt7Q-=+#lgHZ27XzXA+-lsYdRC5Ot?lU$>f41JzwqU1jRT3||@bywD6<}gwG?6*x8@lOwVQEgw0Seh}V z9`V-6ARDVpzhQ>^kM&uqIdHWu@>7(9JA3HH{!8*+_p^Ku8^XF9wCwamEX? zalnweCSD&Xq;8&@6;h|T+5V6^%PtNaQrFlYQkOOC`xJO?Lh8JIWOxvIiG!G zt6?H$k68o&g(6UttOtc!9TfZRuk6QI0mmt+W!t!Di%?3r5QmqY%|!cwL){bOAO8QLMZwz5hQ0q9AP+Cck(H7FUqA^h*qTPDU`^t zLiOYZGueSqqXd+gY%*k>W})br-QOKdjZf}|8q*0&KK?fh5NR9kc-Dtx8@XR@868EzX#5PvQkgJDdskP%%aD{C!Ng9^^KR3HMKGZ5R`- zGTdcMxC8CC#=?nkipHm4=4?V!IIh+3uW#^8l&FCNSZeQ4Q;>l4x1pBWVn`$(vioqs zdxPzH!&qt`Mw%Kk?OuQJ7EtL*(d01J*nK|?q@;)sLLEMsufTBM{| z2+a&{k3G@|GR6JL9{Xzz43q2~Fdb|=@3VLDeN3_it3RAc_Rk}Q0{>-`Y?_P$t85qS zOjg;mq|2nk|3>(R4?c8t7V9)tS??|J!QVasO6Y9!Z0^GTvmqP$LelkIQh7LS)`TVd zW$b#kbzXv*&2n>NaFSwsA7}Hl)*SUUDO)DBQw3V^B$Fxt-d<=*OPm;?Em}a+BuHEP zsc>V6h9l*r{ud4bn%!>vl&sp7EAg3+SON;V1iDrw7aFX-2Eng}2HKZD#CcTe1L~#% z#qHkbYY5bdv7ybs?QvAWLFZ9@@cC9*^*w0tJX7D)q4hb74~8iX1bJ)C3pa?Fw7n*9 znBHj*EvpQ3AJMvEU*UW*vYdwjhm*VQ$-++C5A;5^ZB%Ec4k|%#ha!pm&nSn7W zMRk*5qpSG}o8Rqx+ZBRknv9tfHipZD8kt*zoSNWbX$Gu@>;&uWu*I$#6JS~D_omj= zukFvz?aw^}2!_dHjBKmd;=W!b=4Dd1R-=L~cb!@GG=8 z`O_UMQrzSOO)rNJs~PEm6>Ip z859RBCYr9TyjA1lrXrn$R5z3SjYgX_Y^LA0WLxk*xeQEKg5@+)flokHI0`XCGB2h*o%#8i;!0L>btDE1Fd_afbbd0yxz2}JK7 zMt{}jN;T3i(Qsa^D;Vrq*Gb}X$nQa_2a5{NqQb=piudDfsy z#;dRZ#NkmP*LiIBA3_3|Q@1BIRk#CW07Z9_%}TWIf3=@eVQg?7dn#T08Q~R`$alw~ zejL-oJxpeQh*?X_2*Gl@-0F?ZAEXO`|@QuaiX(jBf{3fA6Yu(s2Em`>qA5r&CB<*vhEH{Pwu z$qA7s+T)eZv6;i^S(~)S?8M5an7%cFY9~kV)(f=7*kQB<#%vDl-GVur5x`wm%#AI) zB&Yc>OdnU8e1@Cd-q&@qm)Dber2iq?aOUEkCEsD6ea|sY7enA{XosAq`h>HSdQwX` zDl8i1?A1Isp1(rE;~0Ae<5-sy8g&M2ylq`hPANFC$%HPT6i#K%EusZ~2jLsrz9hdx zqM<6$P?i5hjF|qF{9zG#bxRfi4+a+gt%bxMfszcIGy*5#AorK4ERWo;yO(#c3SzS% zIe)-S|5#hgLD`P=ajIoHwfKwD-{G^GCpd!Q%K8SK`>$Z0rv3P(S?wF;Z%oiW)J^-p z9%;e@pT97x7}77te}#^zPm@fsCAQdOLyA2?G2>cvmV!}K_&1J|_xEBO^0%u8)WG>g zSeaL=(t6ve^B&D=?HIkdHfU{*spCl7TF;cMVnBoMgJKP)*iQCxF~sfJ#h4B9@lnjb z!nV~^msJV6chDtZ1ihL>t00?y8m9oID*OlDGeCR&&a7{aRE^KmBmWR;Ox_C8g9802 zL07g;q;DhWNZI79+yH0jv(i^ZEHi!!vHTGkU@!<|0j8pUkfowiou~>9A!?;}xg0+H zI;Q{=%`Wn}lDf^g+)i6HmtQ~Uat!y)H?_V!qInKEOq-+|lu3E6r#E`Cf(sD`CnnC!wVbeN zt{We-T)uUTr)Z^2Qb>~o@ax>fB6GAe*9f?@q*a%zR3xypgg(?OdzkYPoAT2~t`6=W zOC~y2q0^}O1uI@8paPs5;pX<@9LY15e73nqs#h#%4C{RCi2zeaP#=aycw!>|m_!JB z;nDeKn96WxIDHe-I0l~jRP!grOo5rsXHD*wL+zy|VT)d!-nnq=K!#Pfu5MqZB?F68$-e(^_0 z2(bx#BEoCS2&o$l9BD~1p4EEQpg$$PUC*KG@w$TAP80+oX4FF7&jXj6CEORPMLr4i zK_;{cNgrC_*WM2!hzt@aylNHxEEGTB({J0u6Vky4-g9mdGxeBN(~I6tulCx{P}D-r zgJ04@qD>(TompHYkv~3L2(Q987I2Y2!yzpfVYfNgZuJEv&XW7=6@>f~uHbL|ryaZT z+mMNzS00HM6i=U-qn+bcw#Q^949CZGG3!p7jCR_wKH#Ww@F?8v=Y>f&oP`T`KX*Ir za%NZVPLXqFWuaTW---Q0Qzu(8^nU0x=O@dXCeKWa`$!~ymwNv*uvI*DhwDu!uVbzX`EMuO z56N6&CbO=*ypCBb)r^)1Q|4*?12tN}%dH_Rk z#b;148!=!MUCbllNXv|g6c>OD+dhKu(^8JYQ^v1@E&&0ml; zD;`pOp>1fnX{d*WG@x`tTK1ZTe(?bfnMCPX4W-8?M|bKjjXqf+5XTSu`c&i;JZc=` zWPS57mgrDnw+Di1lLS?SM6aVkZv<7o!SZx{mW}T2WywVzgV(Y&oeH|@e~AE@0sIxb zgqK~zq`{xEXD;AOH-frZZ0TnVv$baYRfa8T^Y8(g$%ESpQ(h!9A&jX7ZN%UQ@N<0 zgg%g|r1oHT&f+DK6|fiKJS?GEoCTQ4ELWBMmw;$OqL~akannSzgF_uf5F(mTP{GCG zO6ghxUZScLTq#7IgFtCm(N8TtYD)ieJNtWk%;PJ02rk;IJL*6VX~TBxVHDz)Jeo^fvD(j(h?o6j=hShHH%abEcm1Q+DG z?R_m@jKn*|7%`oNz475yHqV_Kzr#F)FS?$+tiHqW#iE{V#6H{r+|uxFC7YUrcZJ46 z$Rw2y>awP-G_^947*`z$Dvra34+(om34;#USj+9{HYR+yHjpb@YX-5^ zD4o#|dt-y)eNBc@MWDuNa=CvSaIru>Vt04QX@3vUwbm@Y($J(*oHC1Jf<~`7*7lIqh)x)-IrgOKxkzHn zX#j^k4tEOb(Rh)O+oLUcd3pwEBB9J>q}tO=wER$pj8ftM1g!|F(y-dmYUiUt^8wn+ z@sR18@TgP-Fv0jpYkPc~sTfFE`=VeLTzSamrc*(Bih~9c+tgSnJPP@bylGZ_-yK2? zTld=LLoVOzQ={t@`cLUO%yUi_^W@~89RC4c_$gc6;p?*Amh0^y8~98;Nlvysp?$5y z=m~u?t9P>+Iz%w2@IPkj>3cb=9z&!v4$!SrY`3nTp7jBC-yHwQ;DZX&`q}?5yrqcb9O8wEHR-ChXp?($Y% zru7I^6D7?{Rn)G`B_aCq&TwCMxO(UO9mWk3p16;UPujTB#X^A0t7H>FcU^qHYG4Lj z*9)pcBVZB=K}%FcJWqOC;&*anw7~2o91)MQD4|XN-~VE!W@onjZoFP3ctQTVAF~qCQ948Hr^X~Y#Qsi84C$*f z+AV+>YREMrSpp5*xRgM*$ihj!)b`%=EI zpfVt6uwSY~_1^jSi*T)Zyz(gxKiw9M-dNt4nybmELO#Uyl}B!h>r(>k+O)dvFhJ)WJnNAz{H5=?32)}t5_yJ_n!uwC(Lw~jRIj~+L&*=_i zs88gZz^zKLNYM zW~c4FLW&wPEpQjTYE2X`Djiz)n|ZQ)xQkX;Yelz6cLy~_m8UoMb}<>N_?F~BBWk@T z!;b^bzP_7zotp}Gr^ZLCUvS!vp#VB}RSA64fi6*!et*#;+<2cmIv$@_W_JlKogKIm&OEWbk?|1vvs{XR4n4g&4XwhZ8zC z1k(idj*ocz$O<1W+blw=j}&c$?U66ZtUT{FAd0{z)f;7)ZqRq|9lHXJR=+v_S7C1_ z+>41n@zb{PFVnb57S6$esZW}$>@@0nZ|PLavcIbC`f$--IWV4$L+OxL+mzfM3;sN< zjRR&}fP&7p=h14Kc9w2NefN4R*U#Ov+gZAfeQVDHTn2-QZZ&vR`v>WG;ojH6WqZOL zZW%87N9Fp;-JJQsI>%{STOgorgxtqV;SgfYdzc1*u!Mmn*`FGSMysDCz>xAxAP{{$ zFRBWv1$NSM)hpd5lNMf($@5<|LdX9$1nJhh->2kejM~E!}jM9v<8Fr=sUW9h@Zb zZHrjdYn-;9ON_=3yLocfQjkMVjSd)01BSh9TMYe>gaXrF1=E)sOveWU{>S!@aN6^! z&~Vb&RvrI+#Iz!@&^mllwJ{Fsi9N~t*vb(o1OV8rWSbR6D#8^@UGH~6KKsXP#&B;+xoiaY zn09Z3gLV5<9k^4ev)KRCpCvYpk6TSl?1n$I*$>i2wZs$zberWFJX7mZARguy^r@ra zkn07F#P;Pou_GaLd~(1?yDJbhv8{gsI!H+hMEsqi3GxH~yXD?=usm0oGs513yW$p&=nr~!>= zZfqmLhjdvVrn{WnWUMof86ZQxU6s2r+1zFxX7D$8y6$!MD8~=Hlsw4XJqIl%pTSmP z2&DVXe5q{cQr+*838nT?k)m!=<A2jItQ^IFaHt z$6fTy4tIY2XSn-~e7E|!=Fcm~ZWEc3z$LP_JjMA%;i4xYr1 zws7oac*37lLo{)AVYIquek?5Ow?b_>!J&)ObJ7ha|AOU={_UkABCx0{^|;J4QCfh- zbva8>>unR;+_H7FG9!^+Ew!NOXjmlHZ+sZr!bQ(^h7;%00>KIEOlXrSMzn1N=I@*C zeiU{|{Sog?m~ph|jhTrt)oMBHy~nA)#Qn;-ONlpANn+~Jbp;GUfu}M3u|9B_d}0C1 z%i{oz5#iWc?Q}1!jcxtyw4#mEItmdVUE-A2j(r3JrNi_74um0I+p5?+BSba&Afn{t9CxLM)S!eE{ znO-Av5HraUJPODDI7;#`nrP|kL=c4$)Zy+|^P&^?AQ)#Q&O3~GnN3aROK+$04*!ie zNVABC+;}dzVxJn)YaRnZQv!)f2?*e4ybZ_0h2i*-qFPkMfF9EdzwCgZdmyHv)e7nE zlfsFq`J(SC|C?|{y_dk39PHFDQ9l6|>d_Vf>1>Tg2YGQ4r)AH{XE76nW7UN%ACL8w z3O^3__C0zig?qP`tti^mK|bGse8Utway`g0KDM3niHc!FBfWjK%SfM!>bteJth;tk z&$O~`D(I~%THA5V;2OXxI)TF1RoTbz52pu1iX;lYeqYvNqKvxz3!cgaU&fUCla9A5 zlVXj2p_px9nv46*Tg-~1aY5GCtnG9BeseoaQeXddHE$Q*%bzCxSo2l&AMgSByS{^J`|E#XskTPJ9Hft5FTp*?glYK@>MSmQ z)|fRa!nAa#gLKqR;tHoNrP-C{cn7GBn6F&#?%5@`+$2h--Evh*Q0iI_8F2-_D{tjp zAZul>oVZI>EWU%fNR2m%5D)DfzS-WMvdHaQ`vmRhqz=c%?K+R7Ms-{~c~Y2jAJGUR zY*JeEjw+l#8nvoo{${)Df=eu$RH3qN;u2NLlQpK&36omk@2Mknu&VQj&u*u>36qfg z5+h81c+uW;h3{0%-;~5-0f6-RSGlr<*+rO`2jT2U9U-iB9{KyIP)G9wy5*}DYIYax zA5cq0rWOS>n!;|PiGHc4Z!rK(c*V-P36%!K_n0T(LLzNc5mq#+kPQVDYw@=V>={zh zl3PJr&{V5F&s}ZSbFr>GqYHqHje2GWLikYt;`?sBNeL8R7V-=N#ma?_b)Tw z8LuD)2U7#vehzAV`$sK@QnEq)X%s?*%wik(T+^NfhND!+(J0P{a=(SO#3MWi`TxdM zr+@0V0L%_yUDn|+);>_ImeAsmJ#gtI>O`z-uT+Kk)7X-n+cGxP@hKFbzst3m+Aa!> zy^5;yv=kLyiSWC9w4*I(FRS&CBXgxO@d0a#)Po3)+)lY>V_R;HB+kjjcDr?ybISz` zI=rWwg)L0+XKEJx<*-UZE}*KOh?FZf10|b;-0DV1D;v66stAF^IM#M6+&vpyj@oi_ zH>8|UN2U55bW|a**S=xIryD=99Ds4&%z*Fj$b6rt?@L{8*MM=Uws)xwbF{J^zo-f~ zr|y#r2<>=uG;wixF3Vn23XC>Q=WAUYR?hxzmd25y7dwZ7?oXWcKA;Ie_aZBLKxY<% z7IYV7f$lEg!zwaoL4{J>(FA%U^>2w3tt4Y_er^=2lrb&>t~JROOs~-rds44w06P;! zHgJ55ieiE>5r0pqw@k?kw0txDjh3yA7Hv>%%+1TA=C7CHLLw7pYgB|qIE&Bdk(>Fb zjE`PHPraFQD@k0(w%lmh3(=xiF?;gmE2HNB83k+y21yJG|H=Fc2rOo}V)Mhfuy{0r zU8zGkO}LQSJ{l={6*zSja{OeZx@*4AA7?Q}_?*bZE)bALIY&}3CEg}nwv&3P%?BX# zh^t<%9@bjlT?UfqUvBD{x{jmJw^QKW%Do^gBB8J;6`qK2>j``R8LnPAA07E!nE^nw zh_^NBE!Q~}Wjmrph@r`R*O%M;RH~G{ssrXlwfc%4c$ZqE;9hKhe$%GZ&!X+S7r3O^ zHZ@W)@s#jnpq5#stLKUNMv^g@>!NdyjN44lS#pz z2{r6z@4{ z5N{#HR%_Z_l(~n2EhZ0!yN*~JOdji57Mbq$B)5t?NNwe)PM{7Zp|&PFc$z(TM=*E! znmeslg89o2=I`aCQi6sxcbfLCv=vR%qf@`mx_@(IVlSyj!+W}f(N3FI!El68;e@-_ z-Lugm=F3DMxV@=J*>*GO+ui?%xHkc>vbg^EZ-9$Ix!#~eqk;yFH3-(ApotO<8tNNK z6t^1G+E^6P(iSm6vvrC3!);p<^TDf zd2jM2Xn*}b&;NP;;o-j9nVBB&as1&>BIttCKIO=8sTwLuu~euvAy=d;f2>&wOoq#cEtf1{@WW`8P!H zPx%8~Zjb&|ht1N(ly*(wGP;dkwr@>Dwt%|J3IzUG`q{o-)B*?;^G5H+n)vAC^VPS? zx$?tz$VPpu9*c1w(?2Pk3fGmF92hc}=n|a;C&u>o)A);I^x6vfqpK`I^Or93kGPud zPXhH!4}5QS_?8G?7b2<7K99FqgS!C44mw>nmC(U}w9!bR?!XTF=IZ%<2suVL>EH91 z(M;#B{5=68$5X~ZS=?!%J4EMzdVnRlvF@TtUM~9r1n3% zQo7|IpBv22P}3=3NEv1=6gF{Mt;lSZb5Rdee|O{gQpt2EyHPZ2gf_@BRn6lJg0 z=cfjrI{2hW`qJKIm(<3aMU#0GFuOMPgy;?0DhAU(XBr8{QC%h6Y7oe@){z=FtvKaDy%oyrG}P!i>e|6pZt z`(KO;Drl(A20l_~{=`_RNBh3D1AeLKUHecP%v_whuC;F@Qns|dEM5BzivUKee1C89 z35uh+{>_f!sp#}I;F{;lwJVab;jyGPl@RNbY1_Rw>?{Ucx zl*Mj8=AaN4O8@XB1`FF?;OA|Z>qXxW!CPecE{|$pFlsIoh=6&I`hSXIqVTCiVe?B-8hs;XCNcn)q$%Q`w5 z%kM6zmVJ9J8Khz-?|o8)W*w9{RQa*wN~3)SE|K(@Z_18GE*{YRB^{gN_g`9D5x;S{ zJVM2sa)Z~veJQ)NwthMOLaV;M=K2>irg5dFnb8)9sO`i)x&AiG>>+i@lFN5<4y z7ER|E4`&!bNxBb zWckWYpwe;^BIDN5Q?ho11`0HKDS}=hL0?Mzv=O@B{;DK(ZvV4?)r-A@`|JEuo(=9Z zMPk`*L>sjwOPC#rw(8UDH#OsLX-1I{iuNhOrIMTDZ(D>-?dX_!kj{}|(`j71)LDgy zwKZ$~&}@_bs7I4pYyK6nqn*{7&&L-<=j~A)VHL_gv_o^FB$7VP-#;kWaT7fd6_Wx- zEmn&fsJ$$!oq43g(erk!&6l0*0sj88rS443eT-n4&*TcH!y8YbWH0s?b^Se_5$R~+ zj4eVE7ec>66-%?g^Tv6b8LHZu zV@kF7EL*o<9?{Xk`$2{dB+kn$SAb!1ObH>1qre~P-wE~o<5u^MWNy*7bo8SOLu#Oa zy7_$`MspvpyR+_=<}R9pLih+XCfvDl-$Os>I4kr6HJl<6=m*RySSVD7iT4%xrDB)w zLC1DVPO7$6(`Xxc*Rg7zSF1_y_#;#6F@Ybm_O;0nsO)-pFXIRxW*`$PA-FsYGb15!kmpFkwy!~-%ml(Z=w3PW#^^GLuhPKQ?&1V;OOttT&R{xM;mwVGJ6Bj7@RS`Y$;J7-H;16 zDWKBb*LP+aYSQ3aUz*#_)uxme!!GbaYJmc}5k7o1B_sqEjni?znr7%Mnx;NznjZW< z&9z6V_#G#heozAy+M6=DZq0l2h-_`D9`P6frelNeQIFU^XMT0jfmm{XU&G@geU6)i z9{3*5Gj|gO0wT?4l>R z-jJ8$kBryyo0sw8Xo=mH_#@{~M*QB_yxy$#OV&*H${;J5OS9q!ZTeNcIbmv7UI^!)Doxv7etYJ*N*|m7Uv{pE*M>ZLCEAVf8)d{1u ztEbjJ~G~SQws0?xlf>tp5d;=zxgVf{93E3I8!k8uYMTl9B2E;!Vi^@;)6&!l$MH{Oy+y9}$O8n23TdJL|3Z)t> zpg~G?W++vPRKlpl?VJGdFtHRtfiQMe%Rm1NGUPp+Cs!x*bolk)&#xSRR)p=fXrv7J z6(^zNtt=?WxxpMc(fn$>>1JNG5Qisc;gFRst}WdsUfs-;%T(iH+mse6e&T(;!5f0A zZmo}dIn10t9dFuC5aiwblE?Mv%=H4Cq*i%=C**{1zyIe!}7bShks*cO32Ma&F0M7ehxAGm&)wa*ljj$JtI zgvdNpMx`??yU3=os$l#B$*g^OD!&{^mY!bcx`61rL@rsMEI^AH{fe3GperT7FGJsK z>|<)y%D6mh_|GWG4n^_ zVqtY9zSgUbkaKeJvq6)2pJ&8TZC~KOV2*J6vEESlYvA?4AS$sfI_=(!rYY&4er_0? zmFp!3Pqf>?Qw#;Y$v@BD)*%%ezKnhHiNjH zO(#8)>-5sqI}aR)$~}AMGUkWv2fkX zYE#WHaOLX4<lc^)KZoD< zWtd|cTE(X0vO)@Ptn=S%0HFpdV(s4@pW5#DB+83bOhY-NMQkPR@gJ!z?;jAqv5l<= zP31TRknQQy(VVHn97_H#s(VG+|BbWgMZca>+pphYd=f?b(;AIZK{KR+W@rJI#GMXS zy=glCYKrxe3@AqoHG%qKDm7ja{fLYHkgbM`sfAl-lPF(JYeyPRL|j$@u{?Ts30%-Z z10DPep+ygtjvZ-PqG2XUGv*DH=oP4DetK=T8;9R&-Q-=md=@$R({7{&_X?{za{H8Q zt(}ghox~xGm*754O(3wHkH*N_U*QuAMQT-y!zn;@JdHmaInj=l zjGcxf4ZqdkNh^M~Fl*Mz+7CF9DZ2Qa_rQ>Rwv^P!HZpex-=Guan$OIA#VdZwo?{Yk z?#HIJ1LMtFLBPtuEu~|cdL_#5fklw533{1C9%rzM>zpkJ-3{);A@-p*w<>XY1#q`P zljYHmzAr(d_!@KS(bOo=80fmEa0oVX95wDg}V z{TWv3HoclE)ye$y1@>xn`{JtPlhw&r{4;p2PHxORX&4bzw#Glsr7}x_rr0Ci{3>-) z148a1!w7V9Gq+}wtn}kSk|eJzFf!XEFzm?7@f%0GY84olbw`?MuZ&LA5Pwb|~vK2WJi%C)sx9l;|#!S7eFTXP`JHjiQ-AFEMDP1;uzHW-RY0191MK`@PqHeqSLfC5Q1uwv^9wqzMW9*Z@C6cy$kXUL4EbN)wBqh6N19B)<}RD997 z1Gg>%UN(lo#~(TOFvhe*Rn~Aa9c5D?f zMO8yuPh_7}Tb(hO1ho9G@uI3XK`l>T$sP`@*7GCVgSCuJ z?&#+M?!2Zr*OkIB9XT(&`H`PdT8}nfEKO*`6v9wWK(B8^uW#Ffb^DFm(C#OQ&l0mL z;Npj*N3tBR_-|w%*~V$%ZyJm(K`@FrhO+$N+EUTajVhwSlDm(Y&Ajo*!$0I39H|K+ zJtGZOHu;Xnij$SHd7Opm^^m3KV3m@1v!g?goc9Ume6w=yBm$Lw`s-{7@f%y)7rOec zM!lHy1+k)-SEa5cZc+MBODqhY?Y)Tj*iUyPViw^{fz(zH3Rfmu{Ye;io@|V(zLMh@ zZ7b?cmG*;#S|v)A=c_0I)pi2e_fE?ve`s2Ij&4W>Mc)2`M|IB7E7RHZ9-3cB=U49I z0E-1!va4k*>w!Wm{IanQhw&=j^OBk~(lwdC@rzc&gYy3?L3io|0!fG$IE~Wz zucZD*BtO|}M$7YU=skWn=#>kl9uq8Z=&k@~3U17Y%V`xwg$yS)Zf)#8nk4i&oCI=%Ff$5aN%N0tD3Ek5Pg> z+=mbT75XqzAHKfTQrv9(6QmIP_;2e2dH9cQ{|>Z&c9$~CqFqcPRk#!F4Fkhy+k|Gt zcc4APAu;cf5Ox;b_+vh__{odt$t$7&-_Z_&)fDFQ?*RSJU#6+CNc_H zr%eejG~h;InVr^b=M5cCNw z+sK*ck2@}FD*#%-JWt_@F~t$V5$USgDF1Tj-mZKxL_TZWg-rDO>)qEDSZ%YS|-*8$NBYB5?;(Ua;<&;aVn zi74AGUi{!zU}9AUb8egN)7(#re}Col5quur%BX4_Dg7Uko&T}g(mDm@&ZoMBtjg?Q zb4&c3HkXL7>SNoVl;xb*nB%R@c>UUf@+hOWwf$=UhZj<-5gL>BsL!8VeTqXqv2^tI zEkh|T;C>7c;^E(N{-8XyPXW&2-VL!yvrB(5siAMXMa9&T44OH`9W^At!&pD#qZy#ZVLk}QmW!z8M3jH=M>uSb0}aoXK~ zg#5qKtEj6!m^TssUE-`I7^XD~(1&6$?8_gXI}Avvse$FaE2*8?bYN(ixVF*U8s%#!EC9Y8M(Kslr@0KLh9e$^hz)g)_l0LtD80qDgJ^wa(! zg=^j4fB@7a#XtTbEBvS79HsaC_n5V@3gx*9y>~BK{6PKWL4(XfbTyw3Oii|ye=$C< zFK>*UXtK<39{e+Z0w*7bZTieJspxXT#31{+Q%{OCw=P*YHzyLWCNL#`Z)Rg4`!e1u z?q-2ptAQF_Mgg&<6aZVUOthY_*QU(RMa8X+&z%b>z2B9S0{EqZKQVw8>$b^G&Gm*c z$@rzuK<#n;c=75DTAJD1Y93rKeo|I#w+el@{ONd}ICCWxKe2)v@*Qv-OvJ!hFz1R*s2yr8gp3M=ayzt*k%Py)BFHDT(Bw^+FFxwrO1VrPT2%axX8^_l!0!oH)t zZ`3d~@nmC{Kaulduf$UrZ~m)3rK0POGV(T^!o?~VUoed?Su|yaEGV}ZRz)Q1T&lgw zI>FvRkwvM};t5!w=&OJfkV!&_F5?#?Jib7a7hUo^;B*F@$NsJlO$6^x<(I_}%G*n! zomr$aUu`suz#=lfW~#`aIwdd2e6=?*{}F|#5uy}ixrVf+fex6YW=8|jq`$Cxy4`r* z;KcZoRMz=I=$yB>8`Y1m@w_ic_)=v&j|Mqs8CM!_!cwlNr*k#}7Tt1z@zIlH3SUv9 zyhQm>G+-ot&FzTLmP);&0t48xOb>X3c)(l6FMcAuGIJ_A1Pr9zQ5N}M)3Hc#pil;H zw|i{`C>mZ!p7Ar^7CTY=fb(S}!vWaR{&+3bNk>a<021_JW=~%x8wu5bS%3z)3t0o~ zxv*s7&tU&kz^Dg_R-2v=Azzjd}41o8!IjJ|_3n?wD$UFxaz4m-H4V*)QTD3A3Ce0U^St{#y zuB?qaWKo$dOU(per7P->Sb_Gd%o7sG96(5%Cvh0X+w}&;kDIvk+iE0bZ5`9Pa=x1JHi}Zt;Kjmyj|J zTrJpWGq3>~Q8UZEwLU@TIbOfbT|8I&b|!)D1;zZAesX9e^MJ)?tt7r4W7YTit?UxH z+7~h-?CVm?=uI+0!I`2!j%u|%PG&1UO!-BX9RG2ULkI?k>0b`)b+^f+*_j8uf^$5t8ET#W zlsz%>;@9lP1F3_pE4AapRx9RISBnk);;1)%Iaw*-KZRt_7PD*{dVAc(RO}QFrN5_VlHbDRx8Rmwj+N z+VKcxNHS#eizoJq;O@d_wX4{(016DuoJil%Wv(-c&vyQu*8Bf)hlBs^gq+lWKMTss zJKt&J_n`j}XKxm&|G}!|CsF=BK|T2A-luj#r=*D%THJ_1#>*$|<@{S@o)Mfe*ad?% z-{D>_)a%6MdGub_*_+rQ4b+`3s`)aWQ?bADSQcBzZ#;1>Z>*zkVjykdO^k(#Nv@VZ zNXb{QjYUU?BJxft^*T5S;Dz{t-h8l0y`~rHFYs10&KF+%v00r^lpNqdYWykLN?_QB0+gdgZK+; zVWXvH@AcrHUyHzr_aWvKjgu9mqI|5dAPE#H~He=i3Mnjm$u zf6wvO%Q9TLjki*<&vwI-#j5(TWFwWovvxwB$l`4x-`2K!i+6eXj;ZB4zkCO4x4h5a zB7}`a$Xf)TZ#`4oLW|Tfgdnd|Y8X&Zq zZ?uOG-Xp{My@d~sntHPLe|3TI)d)6WW3<>JWtGZ5mX8=zCAwhCVk6GoGD^m_fdSl`(Pds> z+ytss$|~~&_lzz6_DnaaFsZ7OXp0NI0=BTt)0d4(no7!|E z+WBKu88@PxV)t%DyGD@(8qxYM{oYKJr_CoCs4zQ@;A`v))z?{yhyKaHKKLeNpxDsy zr2wqNXqM~1PS_d(+l99F?+w759s34zqL8{OFQhcA(D?yaq2;#3f&IK!2+RsS4>0Ir z19;hO=dr$x{9f7~D%O^ilm_{^f$hcQ=Qk|mr_R;-$o)e(+n9YGgU}ZLewJiq`eXid zN&k-i7OK_V{%EfbsioLWzYvM%F9fUwkKtS%6`OHQ%`jd==ydF-20<5Nu^D@YVlzH= z2Ih$dK>dbr$UX5@JhIq5QGVU7GHb@RsplwLIXy|X`(;6I&JB0|{-#r@34U5?(nJ4V zWV6EWPnQ0zlm4v>Vegf+bj;3`V5dBK@vbjr%wC>?^rf!TSFP>6_BbBB#G}?D#hXX+ z)RI1{Bl+t9pkYAc;`<>2i&wlA6?q%j@I-7iBfDDzCd<_Jz8%r~&r@jE4=fNfmMDKJ zW~PJ|Q|NHoc=JKQUBinaoJ(xq~y|Q`C4)Q=#k7(7(nISgV z)O1&3Td(+y(MQQ86+ISJY3r5WM-7{oS9*+qoY+2X;t?r>@Y`is+BI=uc!tTBGZy z5X19$Ixsb;3bGm9SFp+Gv0NI|@&reqc&u8)MUr)vjiYPCeKV>8H%CbVUt(4K6Ltk&@1TcNfC^cTUANaJ8B97x`)*=f`%9 z69bM3#~PFDtIuKWmKD)|{B)d_fOV{hE)DMdza0R@R-T=0p>(WKIb##J`dtHN0UryCA?og5-KZm9ES#%p%D-ykqLiEMBNd}I_-t2GsH~Ez%9*HL>FB99X z@dDC3QA3E-Q}IQyaUh(j1XXPYc4J%Sd)zK(R?q(trnwc;X=8cHRJnW5JpxcaJs_`; z65R0I%C_W{1!(D}P=NjcNtVl;j?Qnf#Fk4cddQo?nPgR(?^(f zd1G88%e2txeg&eogXrhy{uFclM{fi5Vv z9cMDm!kwxtVZe>9pXCR*_s3bwt?H`dvuZBHRqZV9*L_a_DV+_9AmT_M9L4Ys~ zMnJ+~?pmBi{XaElmK*Ux7Zad9+?&{2Tu|Z1er0{&K4GVXb-g3$@YFgL;&6YG>-mO< zT^#0;hyeyvv39@(?ie>O`&hUqx4!osOiJK}8&m;M{sF({XIEGJfI&Tb)KRn4qyD&> ze&`CKP`Y~59{rK6RqVdMEDK{U4Dn&7n!o+e1Y738rXN=Z;&|VQeK0OB-%0&q^ElLa zDtZ-3%cAr6jW_F*YP8jBlgLdPs=y%5G>95OunR(due{<>TFjEyJj5XCc(lLT#z7v^~ctHnq+N-iy z=5OOuWBI`wOe=rr3jAPfP~eMI1RGWs;n8&6934~izP+4!yOFG|8DJrri%X?h>TOn)a1nvSB?xJnFsc5Azuq|r~5jsNll#N36@ZW)xyBZ}| z^${go7Q=#kh%L9rRP=GKW`sP3G#U=`qaVU#V#Zs$UcJmKIC-Jg(Ilg@saK1?uDMT` z;jrECb-|D<{pd2{v>n@gaA|_b#s*@?ptTjKb|>Ew<(G-AzQmFQWYic*sacz#D3mlVPOP^ zi*o(_!KAVLvDZx8`r>D`SqY&XmXM#q^3dW1Ji8$&NtEy2+urYM>7qX$VlDBJmei!8 z5%-kg33jJuWa>En@sD7ki)s-c|9~c8ER})3-al}b#+5wT4il;T-%W&93G2WxXHIIJ zmoqq_H_1`;x?I#6S^b-%wVhcy_N6vs!0(C?MEsr*;2f=aC9G2ZSRvb~!6zz3demD6 zH)uH@UeSm2;I+j99!TF9eOw=VNB6TbqPD-o#OOOe5f1rVbQzZamM-yo*QgmQ$aWXZ zQLp#ludu(kMD>&!^^(DkTH#<>4li?ngQJLO>^*pb-X;g1s!M9r;j)!kXFGA!vpJ-V z-}|xGd(`)M2|H+VBs*At&iOzFL=P6$E2610XfXa7%OhkIsb|p8-|7<`V)@f+ZQG6< zMz)b0Bs-O&$GywR1Dgq-v-snG%oa=r5CaxnkF;}Raj6~Ue z{=T@oQqgTT_79>q5h1*k@`)=-$V)#|RAHhy63$~g0%eeAP6Pk`eVuQkSizcis$|j@ zO8gd*!hhfzBh~QdL&Iw;^i_5G$ex7RD4TneL7x3=2vTzA-y1+GKNCq(SwZkgu78~~ z9yaWdYz7}pkQS4Pyeh3$%pY7a{|dt!LLTsbLg=QV!|R|f4d9bhe}S^u%q>Re9{NfJ z^_9nX@ECl}4Ia1g6lRp}{qpHhqtQ$e{|m_MkFxwVbfPY`na>a~{|_$3uig%&*hMK;Dn)Olfbez7 zguj6BlX;Y2%n%EJVTG7YFtpWu>ehG^43GEgv3K0|MvMSzctRLe z(-ZRoXhR?i{eXksYX|5F0rV|GHw)e5pi|F;Fp;t24-24M!q7i-(7FE!LECuf>+2of z^92n@`NNr*0_WK)Ly(5^Iw1XBsefbng=f<-HC*90CV90BQsQsb-N*dM4n5-t`IB}q zn;&58qwTq}QyR`v`yU5{fr&Z$$;Gh9GQTfHQBoglV3lNYVC`^-u$;_Sx7#h_||85sTV~nzpja7 ze#E^w)><>iatqu)jt&h62a}usJ!T+U{P7%8n0f5ePFq?gb(cMD@w0b`?mgDiMi-6~ z%V{1y60I?#qGznP$1 z17aab9e&<6LI+nwui}ILyp$CgDD(mrZ8LUZs#zPBHRH<5RFJ3#{w>&?;E$4;f-Q%C zb#fPgjn`7AFd~~HrL!wVB+9@1vIc55e+f@Px%b~!1I|$g#M8!0zGoQvkL)I~mGU&B zTb)VRW_`rv@kiy+HL?>CybynNdUsnq4NsH3xJnfzSw@wPE~s_X@b~!yB47uN63wL7 z%p}kHs|%dJTIBJ^-~q5Knz+oj*;JHjg(9+=cLkTOnx`hk)DUm;r5O2gNA>H(25J+mXZL^p|Va&Wgl*6D6P z-rVi}^&fUSnz%>vyJj^Ak$66274WZ1%-0@nH(di7Xz4VfR=ikeq zV>apim-zH(Kpniq;zgVOR)d!Mdo`J|^N#ANWhw%rrBsaTPjemP6Jc}3d|7(|2Ite` z16A#Mumw9neS#hb%6YuL2b4d8St5UsEByKJ0tE|SKYj`;{;(-<(GB;fCk(}Pu@H)w zh{W%>T#K#jHBM{i?NIh*;j;ecxuKMP&1UxoKj+ef*s_^B1Q`;<^|-_wV`^P$Cm zg|$VQ({MNLsBhQqps(=nZkJGA`#j>6DBtJPng~sLt>7RByb>L9I*go(&N)pQLlP$E znr2Z_u`hU67Te5ke9mi@{^@O&*$l~QqP&JLNCcid<*;(B%K_$&J!JO?D0+Q=FKPiJ zYM=gBxq>S^ojnW&085Nn|Ce3|^GmWTr2nPcIRpD_EAJX?A3h=F_w4SJRIMo~%ND2e z?=9*?;WP6WO41dBQlIpnU@@`EsP!fy4Gg5>i&_@*eLg4u`M2w1I{K%7hx%AEe^-fx zNafh>%lQU&&l@2yW4qe{)22v!&ZkF*d+yL7T-U{2xn z^5|s2_@~4~*XVCf5tl?C{2odt6utAYDCF;B_jJAZO!l;UJFRWh?sjk6hLy+d{z}ZN8qk2LHoV)jjCz_uOhsP> zZT6UFV4IeOz;HoC{F(r)#K2~uCCKgXJAi#J0CRe$)`8viS|~Sb(+(9wp^mAf@5t=| z^9S~EMx`Mk9e@=W*gvG`R?sB=12e7o z_3s}*6H`3)5Me43i(G%}x%Ta!_k~Nm6*54oBhbW(u#%2s!$^g81BLr5C#G z_n9a!{m3}-7JW)bf4ZXD%JXmE^bOPRqgU3jvstfX^l)xgL=WLte`|e(Hm3VD;*lG} zyHsUcq150}%49`!P5_2tJNju@G?hQxF44idB=e83OYBH4iSlhuB0eNrczJi;nL!i1 zh)h7}wdDaq_xo;TOR)_Yu`Z)eWIt_v_Zt^AG9Y?@OZCU>r(cpvGwtJ!V}AIm&PCDcy&&wNi8_z zz4NWDM>K>!3?(OjEgxF^FZ(h;QEZHJ(D!KXV%Oe?#}p0s?I+s$ff|A8JVEFVNERGR z^-{6DxX}ABAvtKx^28!x>#aykB?r5;)1%oaI2~=wrr!@1;kopwpoM-{55lt ziVe4W`PI_-c?QR#(M^!iL(Tx;3uUrnjV+<=^9kKlG}32?;pd1(&+EVRW0|Rp$FjYk zOGz(y6*I4c=h5aU)6~ed!6s_c?rlE+HaxqUR^X31p6`6r&+eF0Zp^s_E}B zo{96f{gX?${4JFG4&%S$Tzk=FDd;rF$X+)6(v5=7WJiY+D z1mMi^lActrjy0KoBMSbz-{;*QBos6lidAbCA*OK+VsHwu>XnE{Bx;h|Lhb!g+TNF4 zNOZ76qGRW2Rb4wMRk7aX^G(`(kMn%5uUh*?_0Z?Nvga-(Tzf@H#r)BSd+8r^a5exF zi)AY>{n7HueLKF-M*QEj-^XOQ4lR4>ss{vrG-slf%g%@OfmQtq!ZZD&`O(ASTsc&>8-K>RLNnKWnkP$?f|naE}^4*0q6@qBgNr#%O$V z{-v)=YQYbmJvX(^amZbr?(&=@BmISbBMqRs77MOKh?J^|Qw2A}OWs)2C~T-=1x>28 zY03>R?OcnJCE@txkrJ1Jk?jns2DG;4kq2~#q~DFvcTXaaNyL9u12D=CPa9xNgQl(R zUr^KtR2Q1C+#_d5UCbU1lWC|L7HHRX?drj_E26t|(I5J!vY0n=S}H6b5k;=UF;j<1 z>3XRL&F?ns!A2!Y|GuLGA8cDYTZIgM60y9B(+~zfCShMij#~~2a(u)}_^upp(br)Q zn)|O?j#p%Jyu@-$MNet1>DI4b#4}xdo0qOAOhuv!7HISP(M5YC0D((3NzF%(<7q{7 z8^WkR-Ve~{-lkKy?Czchx=X$;W=}j%0y~#Ia{{uf1KKn1L(3lg{DtFZ_(rZL__-t% zy^fTr*tPt!U&x#~LEt%hH|W#aH<+5T6%1w3KLIuKd+5-SrNTKjN*9vZx&_qE(#9p$ z(KW2mu4>UgXLA|5(J33}?h+>yx1{EXh%hkm@K+mI;p4*iqTeV7HV@t1pH**N^;Zvt zY&^-7|L3dtV3LqTlhx{peY748ftfWsD*!9>1a|)~4eZb-LSVVdP3g&OU=XyDyu#oX zg$Fif&XxeD5!db-aV?vUP5E>EOmJ8(Au7+xnee(P`cDe-F_8p3dWsuKK5$nMpCqrITJlaG@XTu*;Y3r6sLPpPGhJMsFx*NSmdRDKTEj-TS zu`=D~u(9b1_hP2K=+BEP_o6`w1|F6^wHNal5=K0`({jsRiO+eMF?-pv_`G|0S+*^n z_zPDUYDy6drJ1E`?D-Vrx*y7eE>KgD5N$l?2~X1U*$UY0V=uL&5y0xy9Fz3a^=5Um z6HC=ljx@xyS30_>KsWMGK$sOD3jJy3G>{XNlTrihq_)OOv6j$@u^YlmSKcH=MWiPu zVYAKas?1b`t87Jl-rba1$?-Lb+YQgyLk9$SC+*qct;i~hMB0S+df{z@w}BjN^njQj zyp8cw*WW3zV;haCp&SPD?RaluHtCM@;Y;gBm8+sdU9FR3($ znNF!bOIuR&MH&uBZ8(dCKX-C(3zK5o&Gw(K7lDViRv1kd066cj{YOBvR@JN1{8^(u z@G#j++rDqe*t10lz)<13y?6Z|+8^nvU;m=Yp{;_>^*uNv(+40V>HPhMkq0SnP|A-G zokT0!b@O5l5vrLD8vAdPd6ka-=fjY|+jd^FY9(}c9Z1R>@jgoEddOQ!DDJS|I91Te zZ@Y;T@qe#zTa^YjHk`?prr6rdF{a@jnJ?H~?3eY)Vtb08fcsS})b>VyF^XsB*4gO5 z#{V+=J6rO7=2OJtE_45D)v^|b$ts8*`0nZYkFY(Ijz&h)m?Fs&IA-CpZAa@_1+Iwt z-0KheylSrjD}4#oG!wU5$U>z_1HtrbwILfQ&Uum$0hV)P50wC!S?uCz{k>S$QUqM8jFv@~rItrCwna*5Ql;j&1)qc=470|aZyCRru||JJ2F~1_ zs;{~JJA+g)!KF`e4Gf3o<|=hM|HQpcAQRK$g!$_(#K6PwSO;j4JTn>I)uY4txtATz zMk=F{Mkl427ip!`%v!coYwAsc%Jgx)$IuBiZRLIYUQa+R+?7%QNJbsXfATW_v{L-> zC|CbI=Ny0bfsnMDwK1T`)2D z%r3B~%e9<`y|6HT<@>=Ad-~e*ON>NlSu$>T{j}@n|nOE5DKx+o$X=Xev zUTM0%umEi4K^C`U3#->WCK#-Py=43~Z=G4Av&qvhkZ+JF`x8uv9vx)5hE;Y}rp{b< zcgZc_aG{TLrgFd@aRV76T2E{kW%S2kLrqRZvRaE zK`=(D5Ld%o#@e{?pV}9-=_ogUzTgwv@ti$w^3ePnywpR=+MjqaF72w=3C?FB1G&)9%VWn+SKYi%H!dx+GR|Z4;Rkg zFO$2BXjI_u zMXo{J0e)0K8TO{`$nH<;P;2==a9dXkZfm@ppvg95#*&42VcLPL3I7`QmGHQ{y6*g2 zA-s9a10@;eZ~UqIJNpxL(KX)2cG59hkE+(h(ErCAEuVrmlhfHYN<|-ewTAsaa2~Cg z-RWWjfeJSiMsiDA{Et|U?4|k?xn1jU`q5G@8VB$x~gDv(aAMHg7EA%H|gZ`91<%%SA(gpwCK2C98VEIEK&B9 zOc9E5U9QkHz={KjX_dtEd&`Mos}$vUuea4xu|P??TWqbJ&VP*|8B^Ofar`*fy9wKCFOAvc{?cx>sr;J-lfQu9cw#PZEFYUVuE+0n_j<_P@DneY6si5c;n=gf z+nj%@(dx<@RZ<4}(6wIg`L=mZ(p_e6pN}atb58_vz?)8-aiTQ}M1Nh~r+JKUQu#-X z#-nyK!`B%wyCIYLId{BpbI1N(0AzN7+aTc}$W`Q@iI*N(d}wn>q2`mjKl2x%@zwoK z?S8yG1Qioht%GtCxGA9gn!wzNtn+}17c4fy^_TDNx>dKD46T;O@%HfpFdI9!7&a}y->|#FRU8bMY z!#$Udjyy83%?_}AtfIqtHcb%S-@eFB#5&G3Ebo2J>JrJOxps{+gYpoff@S{3y=j?i z!q&|W_U!%=%kF#fv(Dg%0EgS2(-cVTB}r<$>1C({`q_A;*slea%DT6nO9?fJ(m0l%dCt4y7aInA!!NVd4+BX{H zA?@FVlp6;YQorJ5Qs<)v4kIl#S33H|C}jg_Y+>at2TPG^$w$P$g;BrKGJiY;<56i1 zsp#`0aiIat3PJlf?*$9D!NT3!FFyCjj(#Q5f5qzGvCGRZBP;rlVts>G zw0X7qW>X5E(q$1TEF+dkxNMn6u$BQ`%v%e0ZO0}ttG`P%O6jQMp*}W;67g@J?{rQ9 zEed z&bOWKU?PYkG+It{fMz+s(D z&FpTC!fvdvvo%F9acJbd@JB*FXd{f)m%PM3Y?Tk3yirB*xCZj@xHfoP=^mHrF%>AH z*-uJ8F`UjaYfyE~iAVe`Wz<uKH$KWdVwY^GLl& zM}K!m2-3DqJli1UBoyPPCmPtD;lO9JyObVrIVYGSxZo!kX;XElCa({F{Sy_xYhrFkjTIYNXog-0ceSt#f1(Wpy$2@P6avMfohs*Cc{CuW^Yu9nrjj3r>jU z6jw2i4c(mV?eT9(h)fVv5#F$B#-T7TuCwga0;gvb;;S!c?ucLeF4*nTk#=txg?R>NR&<*@v5o>YNo`*%igp3!Llk%9o`b8kN!P zCsjc#Q}Z64gCC2!InfcWXmvUH^8BMpRjPnM6AZI^)ssSYRF)ndH9&_<O0kRM7OL()v2iA(=&@O;P3~rg>@|?T3?U~62x`iA$MzXbh0MeZ$r8q2>T;)@RZVLrkA zfln~SHg&1%TdfWRwz8cFB)t-*_&K*dpNuYry}R%D9xJc2 zDWI6hrLo2(7GWN5ew^~hm>a4(o!^ISH;;|C?Od4}{MA9@B4hE%ByJVj$w5Vx@Kvr~ z#qo`5@(K+>CTLHV`uXBB7{(a*6kN|Q%-oMC|7+K}LBs9>uZu5vGiTav-ik2=WJgnq zVhJrAPm#hgpZ~Kh%A0J6l~MQ$r#}~2S?#}8)m(*e`Wp!$UsZCmmwc{Ag+2+0Qes45 z0QcwbF-GESW!_h(cCq7#Zsop)9ZPHEh+zU5Z>%YtxYA1VY_mEeabiIKDGeE@BMpa5 zF?;(O1R%ZuPb->h@SSU1HFptSRP(KzX){#`S{yh0ii)7VXd7?n=V*>u@M=K5eMW5M zfZ~S!UiuL=bY@Qz(v_L}H4;Kc6icoP15&`%4h4Iq98{jzsJQ)6mu2!B^Q{|}lwl5` zBEbz)+en$){%8#wWz-}mHSdsB!wM z?*5m?^7mJmK6nkz>Y)#`r>qnK-u6H@An2wSO567_dWz{wB+r~Gw-h->gmHCritapB zE_HlCRnF$BvTaxW(&_C)`NPbH!|+E_WOb@{jg0hS?rWHI7WX&j@L&V}c+*{EL7O(5 zk&5+(Hyckk?Km8SL;X zbyH5pibQuB$&8fNY2j(kaGspvXN~)=eluIJxbN0%;`ZfL1b|f~38ybN<~w{`s&Zvs zh7eHsI*FG-04Z%8jrXl(+yR7Rni+&a!Zb&PH_VmH`yFLsnxPmYnHPgT1P=T@}8IijPz zpVzU1jR_OWa|!gzji*0RimJ!(=B7=fjxsFez7MwDs2skf1K zb{DJ{SR|#VxrQ~3P$)Et#UT^b`!*_bve{E8mU?CLnQO9hq2}l6X8#`OqasGC@A0G} zDr^rvk7kfo%XOyO)5FOy$he(AJ?VSRsENg-VLU0|yuiG%I6G-SkS+GL8&_x2xonY| z!Cwj^ii(=u@$Zcyu2=Ie5LPZ-^iOx%qim=oXVbUaqxoOlN-%D(7B3ZeSkzr&g_0!Q zXJ6KfJ6@-a!rMM%VdJ|*Ue3`W$W_VhUfV}8 zZ}ui0Nd1p5B9TH@+?kUtqZP_%Hm{j#pL;D2)nz9a#GADMhZC00{K=TDOW7@_#)@N8 zYc*^g|3}icB_iGAs`PbAT%9$KcJgK~buWHAxw`j{3#!XryL5U@YVR8CwTo*~6Vb+B zNgx_d7_o{eDHh_;OH?NZ(r6lU|8gv@Hu4u+RH%U_)4T|^%2vZw2PS1_c`fn8R#;

{ONhC2YA}s}K_m zLm;XqU+{A5lK7@~oT)c9He*waqpOlnCqEvO{A%4tRf#Wi>vzT`=o3#+)5w_k9nW04 zcwBlk{qwPOzxDT2CBL$e*O#aLK_r?XqD|$0DS3~sP8Jn$aA)>xzG36PRTvJZuBC{; zXwd=gCYR)MBEZz11dt&%J~K)xGAZT`40?(){vIFZ?~wT}0u=lIfv4JUtjakxuO{a# z*cFvq=7`#4~12J1UlY4!p5S3S*+~{=V>BCG%&Rp7a zyt{s6PUKMukUs_x;{S7y*&k|Z#s0eF)%0Z$zkyQF)FS#47Bs6ys&W;>wDdT3>TioD zG~I3T(`G!ws40Wy9J#Zst=+xPm*IY62)Rff6U$25S9namvvV5Td+t>6!iN=Gm*?QK zgf~j1=g`a}VV)zz+`m1cIe ze%G7K?ki7wIY=tzs-Y|P6&xy_ep9-XvTf9_i3+M!>?ee8C+%E*ZkyAm+wY!~m~n2T zzJLSiE@<4Yv*EpU?cR`2z$r6MU2Et2_@Wt;2x_UQ*{juo#2@i=YW&kw2BBToUOj{n z@T+zbLeJ918^er7ufVhF408O(zqcb&iWVcc%+Ga2w^yLs39e=v!*HOc1$bUdBeeLB z5@q~d@f)+n(mmFr%V0@{PERbW{#J>{KAA%6C0H&FQ+912?xlXahFn>%5z55%SLuYC zf;OT{oN*gR+8^=v6ox;6km3Hw`1=ZtGrG^;(TpYD=SvxIz_1m3rz=von7R}h)_^Pd zyx68Hxy?&#+KCxlw51!)jal~wZrRa&8_VB&)J)J@#Hou$mQ*%97jIf--PNdlZl-(d z+v1^l`D>*3be}!L-P&~qH*&cJGM#8#{<7_QJo`=cU~GQuCBLB)Lv}Xx#u%MkmDrXW zZ~lhdFh|DjwTfF)HZhyPRz;60OsQ)le^F9F>st&M!IWpgXcN?%8e5dXYZ%WGKD4j+Y){HQu)(~D(eP^J{+JAr}Lr3pUGi_nTy!mxO2cj&f)ReMWBp+hV8TQqX=SCQ6pJ+vlyXubmf@5fp7OKuL8V*BL$Yn($1 zIEuK8A|Sut5(4W--Tc1?V4i`EcVOGYvkWnT%?rRBUp(qrZb$t-l$(ieT>$2|?0N@w zY_cHR!!S8zGyAMDMy`uBE#MMqq)Sd9SXzwE5}%Yk6#-q zP`)7lBM`PF`|(AsR)c+AnX?*0kjAo4iO7*`nb3Cf)fE#*Gt2gv#9c0w2XsTb*r+j0 zJOH$3>8G13Sc(z4I-X#T$Hs27|Fl6Yb7*8m!=?E8?t@9ddCRn&lwG9#IWzXPKlWGp zkZtXBf7X1kK#4~6KdrDj-5kbL65;QoMu0Fq8LGEyoS)7LRZWHY?^U@3#YTZaC}fVrl=07Chjg#$$uXQ%dAH&9>fPvEuxHnj4eH-La9@OGg(X9A<`JYau> ztAZb{f)!OuQT`2lZGX`3?|^2_389V66Y&oh(9f*^^2`ue+|jh&#d6lszY`(6_E@V* zRBra=?3MADevE>e7=Oa z{C9!KyrBt#b6la1%njiyQ_W8Z_;JfA8^cU+)!!D#nc$`RbD9aWAoSQV??5;7U(gnb z6h<=t!n=s`^Eod5M;zFdxgzXt)cQ{vPQ5IHpTfrSy!$X38gM9QRs6VPT%;?#GJ0im zuEHa`IvkEkF=Lhb$$gVE|4t?lbzi~#eRi+BEu<PEw4nH-|OAhRWQK>fasmN|YVx~CYeu90g zlp3Toz$0~u9nL6YhHdwrtXt+!{RHywL&x1!-H`vt?DbKI6!jgi`nvg_<0S0z8i z{e(a2U1zwzRMqx=@2bSxz3~Xyo8(BQc+M}%t%TtHg}R$o5)}(=Hp2fKCa&W(2nOk> zQRWaRG~$J^Bi4@{@ivRY9tB?^+ZwoqMHo%<$j5Hu{0aMLoWJ`Pi2HY>FhpE#d+^h@ z(Rc9QV0p-poZCg;2D|_Nh`zbW|KI4F{{Mi!+X-%L@gLm$ztDHS<6nek3LXRG6}Lgm z-w0tf2X=hE&Z9ZaH4&NEl3v{4T2MdqOO_e`h^#Mr-Ak6g-9)D8=mm*jYlrjAcbo;z z9`~}!i!aF>>lU#P&8V|pbllnMpdK8sQ@bj2sLJ`yui9GEORn=09JYp6zTdilV4O|J zp^%)nrokQ-L(PU?L7m052F#Te54JO(Y1{JgwKhgKU#`;NOvn{(_TY2cw zZRN2p`{BethJ%Pv$7{1+7P8gG^5~;VLQdCboU-?ae!$9tfBMrtR~{^6 zoT*KS!%BhHic2cs5^tHmfXdpeYoLaD)VGqHs4tel6nO#p0l;;qiSjtig-^!j{F2d& zg-AMjw&6pA9L9bP%k5DyvrT=AT{}It)Gdk1(u@KVHSQ9J-cb&Ter?9G2clMZ9c7fz^a#k(>yB}=| zME<9i)dZao%eEI}$T7yX%Q7*^C}(VbA==Owf4WVLp-1DN=ZwgrZR~CX`8M*6z=Bip zlyZ%gqIhoekh3;w0m=OME^=zmAZ{;u&RYjF-?uZq>*FQg>GHD$@S$F8lATxtu`;)D z*S)*z*54IOp9HT#<|$AeUMt2}Kp)GF&N0R7fl^*=guu}X^qi0P_{|X%Ri1R1Qq?}`K z+a>>5yA0l-3tNt8#;cdHv5Ng^+xecX74LHdYK_38I1rJ=9*D|Zn^Rn zYqe!|)+c|#Q3m>ODg?R<%;g^*fEILup65W%wP9Y6tBosj15kQ3ay-g`{W@GY%0J@2 z!IZu~2-HNnQl`50^{+XcS9=}7Paod<9XyI^g;1>+dr*(*=+DDrB^wt1N;$p2SJdX+ z9r)_}Q5l+hA)L^SzSA#R2LV!tHNQ!!@UH0*`DU!#@SSbf+BC`+$n|Rl9 ztX?;RwP>jutZHtg*S2vdlV{YATdt=(Fs^ou&GGIpfOIHmvSfm<`r3+*pvnD-qeNB4$jGELDHO*V& z%}Wq^V*+COqSeXv_9Qb^9eAX8UzMs{KcgwqQZ@S>@jzAEJ3Ce9_-Ywb03Co-GujAO z_?XpK;Mli6C&LoiUwK*9@7Alr*+{!+bCBH&Hm{y4Xg->4pg1 zQfdoZ1gipeVDoHTXk%-Z-Ou|C?EX|$NC57=MYaab)(x?0bVhCFT(AqZ%(!&_?|Z0A zwMef2L-<`7ploSzj9X7bmmGAq@SN1=@ZCzDqf^cX_3~-EV4I_jjRvqq|S_+9d#-sF!+<5#?G9A zU)<9mzL3uIMwvdGGrYjAYuw9OJos1e)8dbOgrKL}x*Zi|9Zy$(WBwBbnsm1}%o8IQ znIwQ?xYW~>tH^lbDFLS{m!eb@Q-eyTZC+Ggc?$*a}SjZ4<>8zHu$v-8h-_aT97F?1L?dah|?^QcV!iSzlK zj;>rn4;g?2Up_;@c4g+MbqcDr#oy%(`epVH4Ep6B^wF#&^dXliC<|-`)0S9q+xo=k znRCcCeYxJq$gu;pE#8tdfQla_jusM1`VE z_k8j$V;H+Fx8V@)@maxNS5BR8LOEp!!2#E8dGY3JRME$2GW*w+tn*Dc*is=k`yu~1_WyKK^Le~;p|onJcYpTJJ6K)GkFTRnzY)K3(fv3tRdA;-1_ zS^RZ`%ubU|Y^;BOAJcc!!Lon`vv4&P9R8*p*ZZP1p zxKX?oZ#8YLU)pM=kRaX@Hv!glHC}4Hw*Gq6)>f@n0dEPR1koxNi-=YMTYc8G8nqSB zujKds%z1XR3F^21@Bhc^MfSPObIzPOGjrz5nKQ?IFzULz4@QEjzk^7Bf0BE<*Dl4K z-LJTmin~q41@#wwlviB2iu*0awfip;8I^vZKW#mvcis8#sce`LBu=-ee-M4mv1{l z*Cl0_P~uFwRB;vYb@m{(oC3x!_l99s)43Xi)%zv>6Q58DUt?KxdfV1`<{yU1SZ-Pq zy5>lI-06oO59@5SSD!PpghpS>lGOgbnO?1V|JL=oI zLT%@Y=_w@&_mZX#s)jLE`%tx@XT?9s#rSh!N@1o*%G9)(&|{UFzY6b~YreWv2DJaA z#wazv-6?F>auQ)_XjOj7|F4Z_nOu#ZcAOetRHdwz;7cGs5lF{HY~p(idO- za-tU*Of=j(OEY=Inx8NpwCpT^=<`qas*hO3{k#|h^hjJeQ+8*QF%Hewyz*^c_3M{R zP<&W9D}tPw{=Qa{t6%d%$93|5L%Z5IN8GYNavL!Z7J%%Q;m=lODSahivOQsDk3!{S#kC3ndUa)9s(3e-vmxaL#Yzs&qs3&7wqT z(Q?tV`sNbdEVMLisfWvS^C+?GGLx}!9!7sc8=D_~T}xyC<+WU0s^#J)d_j+g^_Hho z$Z)J{{qwqyFSXy~{$AodOo*?0$>ZsLeKhZQc&Qt);{hG$TnPTSFkdC7pic}(D$6YM zhX)UB)+umPE|U!=^ZTVL&7V)uCRD#K|7@Rq_2SdvBGbVeA=6e<)&unO1mWFJKL?Xr zOa`a)Qg?_HQl>EH9gYej9uFpG7t?fHP3jKnLou)5OC!*mUi|9Pf~Ilg_!C7~PHUpk z%ZyUVtBo8Gtb-V246CVdYnC>lxLFy=x|hs&o2B$gw}>_JINfMKM1}dO6+Z9pS+45! zT!>3amJw$kc{c3InMn$cY)@wX;>a8-kj41& z2B`T+F!T+eC*ezG-`d(=roV@)sI5gKWR713V5kF;VSuC#&0L_n5-at z1Gbl-b8~U>ioxN!Iz>{rmkx`^KU|JE*_Ip``?;XX<$+t^av2gEn*#B-7={$TIGkuIO4g;&i$4jsrn zfVBJH|10Fyt|*i70rd7%cE9xjAxn%fCfoalx{b`v88O?2XbsGr{;`@ytlchUK3RWC z{hv$S@^P5ijRsUT7P;I(FIbnM`y+yE(74jMrC5a_5|dcAn;({Dz%_q)Ay&rMo0_!J zG7*-R-KUMFhLa6ZtbpK0u?i<I`pzt+ol13m59%e}S6jqQ zoKb2-Cw!tjIjVZiJgl*3Y39A;nMH-0825Brmf0-ol-ZfI#zI|L1>LXz=1-*WN@W{D zME)qR{)b!f+uv&4>hkKZK3SCtB+jy;fA)Ho#g=A^8)$D5IVgUpRGDFw8K%PQdeQ4Q z;@%CljS>v!zEcql_yheU5d1-lv_zp>ta8nnc*y%tHf7g-9-8RZen$NzVA<5j!|Y>- zV~bxS^45MD(X5#-^%jSLXs4K0pLHMk&#oCv{!n$Gog47C%qYEnGW+^|UXyvO&|kkl z4lj78py_qq|9MM*r>HitvLX-U3OG$@9JsHBU07bl6z`HoqGp+>~wn8wX?p{{7GTs zm+F#{S!mG4+v-v$4W3rr*?2=b#_QC1JF92S3bnlqbJV4dM|L|C8++0XIftrKy%(s_~c+oB5Up%x^4h;D>k|Xb=2niD!Va(Nb&Gg3q?mlK_y^^0o z5r0g9f1NBW*caD`Kic?OBQ9OOTYlKr?gIT*4ixc@Xl*w8$s+ej&+qcAF5889Snvrd z6NzbXU`Jn+2R2+K4+V^_XAT9S035oXp>R)A9-yrhy>3YnjGDk<09%m_Dsr7H^iJ&P z3ETzDSMw0Si^lOhtp%HDiM6$zZx4$m&)HZqBRO_`>)=|Vw&|xC$)aaxbQe8K;|kLE z$;M7jt?IQccT%{s#Q@S#v(QluU8wwu#phIvtD_6U{xa+*=->QQUgP%>m9~_-XvlHd zXvorW26=a59;A`!F(4rjw1Ajz?{851Uzi7FRKL+dG2{TX0x16lD4VVSMmr=Om8OB# zSY-?9+*14bM{Se(FMJ+>ADi3x<5cVbdAE^ppneSk&^U@OzD!(Q(6mQFtQI$MvR`s)uvr|7BT>W9=w^Fq`Q)l+}gdRG}Nm|oU8afzH$7ag> zyF*24c^Mo!*1k=2GCGb;PMt;QV^MWa)89n)u&obziO~U*98Z0D&-)G77UC2LgPbpV{T*_*nZaM?sfSyF3_@2%R3uYOX7Za;&96S_S1gx$FtOUJV%W^ zLv17ZJh|WD-y-X+;_8x*RBWas3qo6bMa417Q5$NjWe!${2CS=|j#fHccW_f(bIpwN zPS7A08=@v&6^^AwevguRqM^=ek0b}7N3Z&Jgkp}2B~N74Ehba=rUp|r&iNfn-P%lb zvE)znlNnZ@*c45yk0st_|6!uo}S+M2-|evacO zUbA~r21o1la)KqN&y)dn55=r>Yf6P$M}3fc{o}o-_e;3ueFs1Geiaw`$5d-Kuea5m zgkh13ui(jt&!XV0CacBi$aeMt7~1`cn%90E-zB^j^?K0^sT^hb#t$}4XT3+ zLG2-^d<-(zt=+QtI>RQ@Vwd*|bo$jnEMF~6V_(#o->K@bvUzyI*o-1mC^9~3fAg+MJe z(5R(mJ8Fg6rtmWTjK-V<+Xs)t_afvhs^iGS>NRQYmtsk!-~t%1?GIdNF=sOctUT`g zLKA?{W0yD7Cbp07z5x9{i&(HUUdzNP^i($%-EpD# zUjU0HpXj(3*$6%MidXnaG;x=^1B)ZQnuUBx<`ZGkxtY!OBQHCT;UiVV>^2Z$E!g@% zk(I4foi)cxijHI$#9J`Rzh=5?Q5g%mUs_C(H$Xj9&>H==tdIig;?tw}GLn~ieB|=8 ztsbI!s3+S?aCeDcP^_l$N#;SyygFWUG*QI`SDoi|Pn|<)*!jt+>KSUp_0w_d&b;RTGfG6$JPm z0MoX1q<_Ru=&{q(0eI3a{t0o|%=dIwBrWSF%dPBG*7>0En#&hTCfmM??<_q`1`P`H zHes2Z9(Jp07!l{~&K#Yh^det8O+BWs+=11rZt}Mgs<`wxUHy|Q24^*Wj^7b7OJ!8P zx6ig#y@g36LLQT~eD>PQAZL7MpiT3nj3;_%j#}@(H^#uWU7iP4s%mcq45)}fJp+{g zBC|aIX@|gHKh1+bSnzLdQ-5H%T~Nng{Bp-3C`_FFk?xD8d}G;am=qwgz^b^wA#(qj zc?C<3{E-3J?9gK!206t+KJnu`$T5O^gQEmOkEwFCY>Wf@!7c?p5r84)uE5M_8upQv zbhhkn)L4|Ct1YaeOK6?{i%s;|^q?n>3_w$PSXfV-tK#!};yQ|l;X1yR2Wi&j;Xr!1 zp7^cCC@p6#UpUB$V6@pyrxUXPDvSyh1@>R#oOK zwW(5?qe}KA8WIl}-x3Esic-As8#q@YbiJ{8!TZRGX6=m^GfDgS8@%Q_wi>N!wDdm| zBlitfO5$ZJV$24E+3%=_1$x99-4QcgNGx(`@oL?*y>f*|2q>$ZUtuYQ`iY=iu3*fK z-guUlz{PxPIAxhh75{`!$p3yi4RJef0>AM$cEcy~p3+?~ZT8l_%K~sv=mw%O*JXa? zj~PB#6iE-VF;KLMuLyVfyDx{l_n{xMVU?P~Ch5^qu9_QAMXG?ltWSNJ!~ci(ue1;7(7W|Kh% zp;h{Rwzmj&QM=g{^dMrEKE0{o8Tb2%7g4BI7Jt zf=g%wt6&g(Rr*-I_bWQ+>0|SIdf@!V;z8~aDL*6Lft1GQnng~S=66+37-Uro=~j|^ zB%@)@(2-j-&4h2&yo%OAOA2Hofgkc97b}KF#2!H~7tz3iDnTUH(Hk>=RXGBEQG`#?%z*3+~_7B)@jrw`_z(BGfvKR-kq0mZAtwwi9sa%ZFYJ8-L!^Tu?-AK#zre6;X;2o)(Zg%(863J2$Ce-axZ0C&>a)k zr7ts1gYkcDCW9%)DxOnrkZNhDBmjqdiQ~A`DfARj zWd)e#VcJUqogE^0<0GL(#DU-~yiv;zOwyv;Hbtw~#X={oW2t;_wDXf=>&u@dq;P+n ziDl919Ziu~;TffXgcdzd0kQGx>c_9qk_=1jh+CAC73<5_kaDsL^-UMnioFk) zgNx{BTPEOTOv`bx1SU3bOZ0Wjg!LWvJ7~Zi7a(us;G4c?DBD;#t;q^TCS9JsB-iDW z;n9dvZ#>!(borqTuFIKKe4zM+EO|v4i+>htyU$`8m)82f`^R9W)vH`CfS+>H?w344 zcOLF^!+`#LPCe4k-y^)?9p!rnwO(hhFK3yLLrcZcF!nxP0v3<+u#r}sTI$*2-f;n| z&6^9~tw+5|DS%s;CMkV9Yx;g^R$39x0|dc9WC|PJo)qwaJ%ZY0nO{h!Oa=jXqpuv8 zH*Fyp4$Jg6bF6#H-__Q!kJDCV`3vNFKzpBc?FBz+1o)RW2?g8;EO^w~!RA2}6n*Re z)QolkbPEwMVI#5*Kj-K!y}zpOeMI)509g2Yrg5~+gV->mKu*itp{l%O&wzXR;?>!# zY`Oe}Ssi61w`NP0gkpAPp{%T{ zCmPyku&3U1*&=4&PEqX}p z|0Y?maFAf?+{Z?Gz%32zGzxq2UDtEO^X!+M~9bDk9TDfZX4_iv} zhvhYYzeb*)4#$6MYbW- zGqP{qw+0kXwR?R}J9Mb$_$%vg=f|m^ z#qX+Pnp^-P5}lYD*}Fz)W!sVXFX5IIIe*ii;Q4#ARs4tLx7py7E&nI|${*jq{L8+e z{4>Fye$@O0-OQijm=#3}j+@;_!R+XvmhBeQj7m3qMxVu*`wY1C2dml}`^#@=;oah^ ze&e5inHA_%90Q?_Yh&}l+XNJB^45N==rJ;?lK!8Oir*l!>I_u}zDfjw36>iBG7(x_ z_cP?zFdC~9T(`5A)4C)pZGB^0kSn$2Z&Gn5JVK}A>Iyo&Uw?!a#vT5Yq5gwr{3)LO zLcnz)(JWpwl>36FS~kTF(v?18MjilhInyr1(oY>^?+y;$`9Cza&9a7y?#W}#N=ouC zM>O00U$Ji{jjhsuKUQerGF8@(z7(?R`2fF*;f#2V|3h3=jpKOnK=#E)AWrbkWXP2x zOT6YMye?>bNjlEd5D;Z*O38Ijii^I}*`%}&h1F*dWAfQY+uNSuhuuhE>u|!g^vBb@S z4Yh7Er8uR+>wJ@mZ==k!;=>GI`qDrDDB%lf?c_NxF@d(U9csfvZaB)YRhbXtN1Wp zbFBlmLqbNi%;7nOH}lio($3$Y@Y{mRc+FW3{z+cJdKX#YE%)$xWy`(%HPj#ELjI0; z%^?o@e4r_I3D5ai#Si4w-h!M5p>Gp zX5nluTv@G!bAoGou^{h7bM`tlwa_j5T=9sP!YPA#HeCdnzHaGTBJc4Y`qy*OGRTo zf5d&>;qHFzK7Ts+e1QX1uYufsJoQ_HQjT=5#0Qk}Ls!ZIch?ZW$V3CRS?=>w^!c>l z)gA6trTbul`@G8Cl?O1#I+#-T`CxrMBzX0yY?IVd6Qxvf`>)v(pLy2kAhE(3=)cNs z`YyoyJ?`hKhO3+`>tcZYP~+wob2NUSVXOT@?YHwVuflB*g^sm{g-V}-#0Zs|o z0I<1L?Y#>v&Pm5FFh`ixTyyQ$@m`18o)Cv7ADT?(OPPCKa%q)aUqQ0tWJ@L2=3G&R z+-Ay$!-mu+w$vqjMJ6oVm(OF#8{0vF69ncTSzo;x|4x1A__g(kSL?^GuTA`!)VDpc z&_lNirj{5kvLU`wpLni*{8|DK>O<4EWFDwpCYK~ooz@t6h}a4ot^PO^f0#P8P(2wZ z%vG|5-EhJ{$B0PaaSYQfEX`V}B1B!9BhwA?Xd}WUleEiKZkRk0u^dN3t%b~ZqKW5f zr3UyAlBV|;`x1o3Hw)wzxJHOG8C#~RW(o!WJT{FQu-CsNm*V&g6|m@bbqlAgp4eP7 zt_D&!Rkzb4E(9`ptvZ8fo5UTui0>$D8kIfGl|w!vrLWoc4fS$-#hfm`mn_=WhRowu z|JCQIemS~+?svVfcfrDSUL(_AmINT7K^ech4>tQXEbG{;kH0X%HoJJ5|I#?n^3FXX zMdE(944DdkS$({h=dFX1cWlNCfE2_5Jz{J4Wb3vN2CXlz0YXo6?rNEq!y5b0`eZoRhBG(?P7jX?0ilW)~xX`1c_u96u{3V^#wQr<# zL*wrhlQNmbk^Q~Y$%sL=ZhB4KKoagNXnNv(HZ!qX$az%RO|rK3X(}U1=B-*b6s$NY zHRWH?!WW_~y#-;!A^v45JSq9a4vqHHlIP8;OP#uNTJ`!+n^bfin>p$dYlw4v=)765 z^73gogK;%t|HWWPgcH7sCXWw0TMaT;i^Va2IoHjKfGG-sqrUQrTNj6qZOtGLx|ifP zYEe6tUR$D`4m(a`-y&^`;1lvf)3~C?X*iURfmPY1)D`6noci&&Q@2~TttWu7eN1VD@O@5Vfn>4d9cu<7!L5T& zOpbtHkSGGdh-`ykBc82oEtJ@@kso`hKJg*~JUEKS0?$!sk+1Snzb!z?)hFJKc7BTc z_U)5Whm5LE{l1`}ydb*mwUbh#xw}beSnCtr(N2Fb3^0G9=t}rh(1wKC0B1H+p4_;W zu$1tD9@?=M>!nb{O#GMu0sUew%((V( zj4R@CN)LvlHX1W2dFx%tmWvXy2N#?rXrMB`iY2z2`R?EJf*iR$u|%hTiCwY@m{$9n z>}C}kUL)k&bT{y$|7|Yue`2AfFX_|zee!7QKOI7+-+qvs^{5M356(JcQlMiFs~G}HXaCz4H(bLY<;Lo zV;M6e{h{v3!bBGlA?E_Q8IyS6S)=^3q@B1m>6$4NDnWrHE^99(iObKNTFd=~c(g4y z*_H@tGpO-!>tJS@^7TJ0GRmpO{OqW{=|d>q%3~d=!`3t}Ikqb|H_}dyh@8u;Q(>+ILT=Ez8{LEjKHuv-RmuIBLj?%0sI{vv>;>|je zOtgJ8ze!|WCe_e7G%rB}q2XmDh#(E0DT;YbGm=wYXdN0$T3yk^COZwHcQC0rYC|`5 zSxUY)N3yH9c37A82o@9+&EI2*ek{{ExCX0YJ*KqaWE`Jag2DWCBQ$w|gOHAr!}-p? z_ODVBf&BdwbF1C|&Cg*-@=n2!`SM1pmv=;ue*O;tvgQ*uQ}QNL5Q^(@Yc0zv_u!Kz zXo?>e;vOX?Efs&t|C(B?NtT4de|WNnVNHS28vvNwwsmzCpJQFKPi1@L3ifAQqw*rc zB6)`{*;U!=)im>9o=3FUCVQ4JC@C*%d>H;`%_gX`*j0%*M{-q~m_sH9xm3mZ>sE^t zcg-g+!8Rj>$;<$H98hBPSRfIaBN?3oK#)F@LP5!cD0aj+Dm}cNnLTS zO)KlpsYe;M9m7rNQFl0r_6eY7>49Lg5XzpF3!Bdl>hq3IMR(n0!z1g!;S0K_HV{WR z_1p5F&xTY?#-=VH+=G74-|YLOd(h%CPB+mSWzDSEH%t33A- zQ)h$6WCR@?zgqyd=jiGJU44`H0gn7eP`U6Nr}IH@f9^iKgx1D@5!Qlc63*{l{bs)b zujtp-ie_pc(4t*--lCIdwVQ83nq=leJHQMFJZFV9NaFx)!>T%#DkznD{L%%yN)<0% zpb2}wH;?KKfDt!t1hK)4!|EOobmP2kY=|oJkH8RCe4#8M#SglVgZN!3fH}y(0%RbE z_F|#EHm#I}sSyeOukupt@o>^8c7p`ebc+qgFbezXVk1gPLyHXHI+ zf8uPNZiaQFU?T!}OtrWrriU zm*`I1$-P8(9xRMgBX4+bIx%h|F7*;KW}CPwnUN(@B{f+z0XL*ZT&?{0YqxOpUCaK* z6B7RD*x}O_pZQ&4!_T>F&;`>HXP$$R85>?$yEu9Qk?FC^iY};4L|J)Xoo>-YxO-|P z%@P|AKJ)q&c{a*x`fHnUVBz zBuc^}*+^`Qta+EQD%7?wPt|&i3FKSiK3gKK0(1}sYnKmmyoR`@%CyY6#D7p|kV$-bxE z$CrRuzemZdNorR!-vHudmBiNi^O*plhd!q;R4qIcg&CRMFP2|L@=>opZ-ei8?j}lL8 zS1}f-m!m|7%{ZMT;yEu-pEOu+Gx;;-H|1Y`q)3pj{M+1_Cc&2wI$sl%`1jB+w%4fX z;C?tPP}k-kES{$iuy)nloY^G{-7vi=eJ(M%13zZIb+SH(DzmcfkSc+%c0W;kl}|Y=hx?{GY)x^Oir5TS zmNn}*hSC#edWlnW#hk+*{MRa)s+KPRZ3rE0i;9Z>E589&5|=-h@u#n7Ff|N2&qSOfB3 zGjX7~;5Wx>>9l~emMsNhna(X(*<+TSE@8PXBJWe-vn|iAjtmTF)aNqZ|GeoENiEuz0_@s$}G0_G8m(O{ZBgWY$-> zM#!N*63rSe@EwI%9$0`z%5EsLK~P#n;MK}-u|`z{hxSzeo*0V1sCy&EdR&zFe?LQg zlF#g|@6rZAp|e;sQi7G_!)l$!HmZ4+RVl7pmJncCl;)V`A4ztDLDK)@96l$%sy%e0 zDfPWa zZgx~1y*rme$8sjBweX(iPC8&Jfg)GUdQ$4A%T#?38tMftV*txMz&QKMIcftYg8#KG zhX0%Shb?R9@Xvf(-)Ex=l5ZKO;!S z_M!jtTbTsZBZ#@VqAvRJ@BDA{p9`4XsCH(j-q8P*If#ih9+a&E5YfN{vUN?Uf@J^w z7Qm?7S>XObRGztcKz+|Af@OWQYHQ0N~dJgC`T`(GlDc+Bobm@eF#R{U>RvMu+Q>m?fuUBksHxV7IjIfDh3w&%+C73J}cS9 zK6}~xfa~Ad_EJwIj2Vujge^C1uR#FaoT-~%aYMqQ)O1wvj4+XPm@-h!v6(e z>yx6_OvbzKOkB5cR39HDqgA}hPLUcX;HkIKq2=RdioJ4NC@wdfmuOvUbHUygdkeK) zn4tOwA-b_d%L`w<(M|5$UGhdP$$5!V)_`=CAxhq?tK(Uv5}#ye7bSk%g(3+(VYGHB zyB+L-yTI;!Q9sy^P|eMsaMZ`CkoAK2Wev=+CS-dp{j3ysVvQRNt|oACsrk9uxDq`S zsXb$sX}M&xx>ur7=_rW9-aqtj)Rij!<#l;tI~H>Ir@bj8%zq_&OLwW_KaI-+D;C(H z0a#ca;=k~B18ba|2R1@r`aZZp{ts6vVhq?Q2UfFh9vJN| z@RtN&PB`A)%A&HLa$eK7RT_M$Fd)s5GScURbpLA$*8D=*sp-WyR- zcQ9c0si;1_GXLNY)e-%2B#USf)IzCK3)O3zW_Z_ zU<8Xo(Wkc<*dF0L0u2$^1p!#Zz{+%&D*i`)ZyVUL0ho!O|Gw*=@rUP?wwp?`@2S)= z#cBt3^)98^_kc~dN`C>Ee;DlO@9i41Wkz1PB9I^HQm1^solapJgzJ<6{lQM3&+ZQh zCDOG$(=>&EMzTm8VR4O3?3y<(&M1j-auoBA#xcy307uiS6LWn+@Mb3MdQQF)<&TH< zrT*J58?|n`FAv>vp=as~)T2!B$kFs}J=z#Na-F90g8ebDwqLNx zYFZM_tH}s+@NyC6!$sr)oAVsqd zBvIjKQfSpi!~4$s9sdW3Lhp$ma}@eN-1)DnjX4TkuSd@Wj~s0<-H$@5i(aNx&os`E$d+Vq8W6O)~?TH}b=A z$W(!pwGy`UB@}4yy~eE{N2|opmGV`GN5!^ypc`7oSt{B`@`( z1u_r$jQs>(u66cH*o*tkT4%tagC5B+Rp01hog4QFJ;vsO>JOSqCZ8~z4PH7Os%bOV z^U+9n2rfW5v9;VwAURx^?L{LloJvv{P!4>QKvpt#(iSotCT_P?){j4Hl@;r7mRb1O zQ8!!QzW+Z8gp+c^c&d2W;ykX{&-m{tamC)(!4;7B`^4sUu(_7Hk$w|@Qc zYUF>{AFA5eXjUE#bG^Lqe_JYs`z$EmzhlPSmDe$0b<7!0s$-h3rDF(O&KrLF&ksTi zy+I~Vvt+Mh``Mr3f@w0pV8&y=4h>Vq4Ryi&1L16sAs-%YunqPGgZ@tewb@`Z9EatC z(s)fLk!YA&Yt^rif41p5mO&%Bo5LMj`tNoy%>fME=Y{1nX{HfeR|>SjO9az1|2tNa5%t-o9e4Q+vP~u+~cO;0Ya9gA)5w5A?e_uVFPfQu+W>551n70M~h87ZJ z=haS4yGnJajTp(^Abuj$daxW`K@3HDAKj#iFE}pfiC=M4b34<~e^2GXSBsz0PonrO z{UnQ5*^kU_4ZNZvUmF%~}=+%H?K++HaVG^tevhSPAVG_=E4o0#02{7qnJ1 zs|_Fgh6jm_Y2sJ0m^%eE+y9$AT$MhMhkhxkR?~O(pOFsG2kn%E{zmU=Dha>Q-GQb; zgOwEK}#fp-tgufg^lx@cQ7&PQ6p_XESP{Bd?T07C}fM;KZuCNw07drj`q*! z!B>lKvggH*>nB-!m;G3~#B(X#vaifw`1Z%5RG%$q=Dp6(o<;x9fybm4Y~_iH%`9}v zm;pEJ?-*gc|NU%P_fIHR9r@pJZ*!{bTa64#skb|iS%UN|1k`Fft( zG&^wI5|K6923bERALGQq#=jt|ff4?ljH9aZR^rQXPI+Y6J=XFG%M1UIR4W_UQj=c8 z%i7b+yfX9?vIxJfUA%Jow<-~@1=x}(3vn?9fl_1m)kLNrNKiap~VJe3NLZ=L9{@k|2PcAxk{ zb=u}EY?T4kHAWp^>l*2An;#@c?rVr+&80?`>XL2H?9aL-XibW~lN^L4Av5!bMtOx3 z8{{p?uV;P{5o>oUiFwe>_?4hsBF^$+q8Y<)uO8 zm0wUf*>ZCHYfGTBO?nrv0%_#XFg z-dWi)d6}NaD_iMHe?vg2;)`qZ1Y{H#_&Xm_N3U6`68&%eP6I-4b6Wn*@!U9=8m`*? zZ7oRDAI%TYZ#-b3Xh3+2aR&M#yT6BSG=Iy5FnfGOS(kr5MP-)tDZGB=g%%o}`sIM6 z9Sd#>xbNa4OqLewp5f&Xq~d(Lex|87(?DCyYtXiiX-h)$k>YRKm&M2GCt2*dyQsVS zn!7ukA0#d{@&Mf%x0l!(TJbZYcg5o+;LZtliQrlOJ$Ct1woBj1n9p`U{i{l0M~|D*mtFTYskr zqD%+!Y^911K1-@pX3n2T>>xR{NGkFxxM6rg_PZ}na$;PTxtY(-%lCebqeg$jAEihO z)XaUqaD2K*(lo$dJo4UKFs0%<#)KA841{M6)LO`S>R&g5QkI@jV+3tkWq99skA7sX z8Sc@U4gfKy559T;cS}IRjt8*9_;7)~K-=@LS<=(e%!7E%NL8W8Arse@4naYBw}x96XK9Hu_MdY$l-|H&QK;NlY2Z}rN_ zNXE?N%ryX=|15t_q6mLAJV7}Zt3}F zsZ)M%65Y6V#8nAWX%Y>KrLLJQAyJz73FhLt_cM@KU!qhG2b*s!<{8j;@n}`l;P| ze_5_tPTvBNnRdjp8BE=sVi)0%B99LE3e7~jeTKG=m=ij4I;iw0biL&*cXr8Jgs$_XhP9Lt; zCeS5DuI&1)PHLgxQmv_!NxujQq@e+AHk(-jL`nY>Mw&l-DMTtrKgTr#=AShjRX-oP z1|LbUJ3WuZR<*;QKp)%`(12yD)@!f zHtKoj8?3cHVsYAD;fJu&(>(2qfy_qMaBKr?;&E%1{L?fPJ;3*cpLhuuV`UauW-m^V z3bh_uq$*t~6)D|XD>hT+G%cZALjNg*0AVbs=lF2N@<-~EGl}DM0pXeISP&W>O%$zG zNSqF7lCp{=e;LG)aa6% zEGU^oEjlBoR2}BuJwb)RXt`N4-4fAOziX6*H~kfgVb6DPs8_m%j4?~N-FQb(t?TgOf!Xnb6<3A!aneggp=gwml49_;aSoufM)aXfG0=@5Y8zJei zs}46S^H=QS2oqLI;q_ar3uy6bNX2R0Al{%l;ySC#OOAb?{%>TBxaj>Q#>{vN2z;ok zm|$#8j_p_i6wnDBSDZ&ovCT|pL9rs3VE-iiraqz}}Lzp?JiIaF;6}QS_|% zRGd!G&m7LKZpcR8lhY)$$Z`aTzX`xy^dZzzi2ZoZh~|vm?H)NzqD*k2P6jNZwEzP@wPk-5(>oNK+doTOYvPx@$lD5*guHL zC-uqD8CmxKX`oQ8Ns={bCD){B_GSMj-D40=^s>U7{u_2Fdw?37H33x~7ne_RFoEr^ zG{o2u*3m>_uBy^81T5P(tOz!+wmRE((~h&M$8y$HUPpbZy5R^^?&o#T8iwgWnB^BB zmvoJWR@V_HAg(&X@Cm2Ms$U4je{Mwx(5<9%k_x7>_)pTGZ@$u-b+4%=Jaw+@=dGz+*gzv?lL@mj6(I0>?lY z3V_J^OO3^wm5&f@3?nD=_HOrVc+QS_*PKoFq<@U?v`Y#a^7TNIiBvx7ZbNhD7El*` zQe&azK-6jaOs|)TSB|t#;yzR1pGVqUtNSQ>R+an2IwEXwO*RY5#`vm3vd0RVF??MR zOH8*o)2Yzki_kJv8+H*5trhpEKd_}1U~D&|;h!*-qMZl%944q4$yhfX_MdT6?{c{+ z;6%7WYpc&!d~tJWZQ`|3U2RmA9Ih{3YqV!sN$FS!Dqbg<)F~Z9;-%#H`?1J`DKK2d)A_y zrkd(0(YW&^@MAmJMh1qa;%WGx$Y_0+Wrx)`+YCO@?g2mT}XGVQ9@0R9h}!^w7UaJWb}m$-++1u?xiPZ0R<+9)6kpLG z#r@9oO&zgso8X=>D?WEZC^*$7p{%2 zPuG|4z+C6pH<38##QN$_LTw*1MT@cVm*=_36@no~(Z)vgT#QMVm_vedFZUi;*KnA^lakCG&VdM_nQWVp-4JCosBt zy+aQ|b<0gMmS`fCWd%92FSQ3bSB6Pi+Xh7I1^8zx0u%uNpF|jp<&@(?c9 zL-s5CM?6NUWD7bp&&e{1YW;JlJXf8L*ovj|BB`kId_`8;shA*ICY1kjEy%;(N^ zkXLNagQRB8FE_|wQPV$?^<4_Q^WS-3R^ZAUqXF0~1M>;s^FM?k z{MR1k&zbz8@Iww6*tTZ-Dv&Cb|9~t1%H8uIcN4Z}1d!5CRz(|CP-fGoc?b^`H%eco{TB3zKZ!3L#w8I;~M4Rkg4Y&~T|D92x$QnG?FPm-_;psfb9i6{lzSd~F@ zIV7Z5(!bYpESd;Hp?`T^X%O%vD$M-D`fXWJ$&bzaZxdu{zZb7G9>hwx#aTDzJ2r=s zb)Yjlv~#(zC+ktAy26cWoNDw^ML1VKryg2s|0LnzoMjogTrj z_9Q7!QPy;iuYjc_9z8&M$+|9cSM{0bsiG3~u*z~OK^`k}ivsVj+Rr}1D5t_OE|${NSqC{XUw@b;m}`)l)C%mEZqOLEOMxc@U^EA? zD;?O@cL&y65r8pq0qhJ1_Si09pTg|^WSZzd{D8G{O1=i%gHH1|0n*246gG^){Lw5W zx&1+@;zj%C(WX@2eEBy1v=H6s<~57Bf`;eq0=M%g(h?i}GXNm}t^Wu6UF|RAx7{!O zE_0vVKFsrGrmTl>`0nSNcv)Wcfw0E~W7hd%>w-vB! zXkoWlNh;-7gd#ICmWs=HKsI4XYD0bXs=0*Y&cI1H72hVTr*lQ>lSLiT(6Y@KHkw33 zW&|9QG5#hEm#&xAEAdbJ0O3jEK9vk=Cvy|NCz%_ZN6vy+zXdd`h89B>37$2rcL8%R|ID~UZ=68c^XLlCXGcF)6|H)(jTgaI(^2A z&60i0`}CC>Rlb0B{!90Z3dO%I%j44!^!0a|VPcDuFm@G5g#g=Glm}+!m$P58#^Nx* z{LzSu->Y(I36u@YDHhlL@44C@Ix?>qGf3Kl+A1|470YQshMO zqB85VU!oiJ9Y+LrNW@_QEoyS!Ca3x_U}lH%xsRqT5*JXIyU!6nMq-mKewTG9adU}N z0Afz6Fl2k_WL1jzYw$OQG#y~}BhAS!Eq;Vf>l5C7WW)5659|v`lschM*|Cu7Qa?$Z znQPnK3TodvNs3}nDlCl*agN`-HQPyFcire5#e1UiO6HwG@8Vw`u`(8VST@E=TO`dc zbw18al+~I?_;Dk~>4ZMIs}s12DP2bx#{YW$%|yY7O8&uIX$Pvo?88mF|Kc~{_z>mg zJmKyFW~T!$L@zT~m~yVvvhTu(>ksvLX)tds=8+i-W|itB-Be0LfJ1RO`pC=)m3Z{@`;JoE$=KA3nlKaXx48k z_)QicJ$E{fL6kFCj^tWtj6AOOT-UQ$@hXyU$hm%ctQ7O>pSFU=?RV|o1l`zry^5W| z8S5`Qzv8++zajfrr882aKhzQjy9zmlUFKei8#NEGGI98thSG~N|G3*fwE;b>l-8AE z42lm;v$UXB2OB|2#Gy^4_O(QkyE%5pAU#=hK92_WB){!_x#3fk!~CmK7pm7lTL3wRxirPWb}= z=hrJd<+-!@hLc>fa?r0og8Xi;$%y*A{BFSn@ji`Mp|&Fhijj{^Sm13VtV0jWc^FV& z4uM<4swIs!)yd{A!#gDJa&zVLNKAex#~cv7l}z){69GE2Kb`3A^@ zWX(+8a4$A0X6F@iuyLZ}NelZv#wGxv>7DXGx9$!nXvD+vGUM(Bi&Vi=u7}JIrM+u5 zyHJ(fhyk!@clzt@Ib@RsiPh}dm|hC2gyM$_5ddLYtz&g=E}D^SEaA-6BFfcLn^n*# z@&&z`a$VTFMy&~JM1+b8?GZQ^#{Lc|eO=}sI9_eFU_^qF9Swl%!(@n>*N+&n)XZKv zW#hN2H^6MRaBN@&yXb^u-SCnVl7x|}KAKKdW_*7ZdVT#nJBwa}q%-)2ugm<_%Krg9 zZP1Y%GSfkLR@}o+mw!Fcl$ysZwD zpcr~(%+`TCGT*&9T#zRPkS2WzAm6=@r-@(kr_q)E{6l%AAEs~ayjE)9&)+}|D9>J> z{G0uk0fZs3QbS@`L!$LWRS>rs9FSw(heg-4KqG-myztbpQ0o#;P9-(V257hUHza ze1jK%vyh?3)^uP6;S<;90vc;QnCSxjbv*L0v+uu zb1qBIvhT`LajwLI)>q8H}8cS4kd&$c% z2Y>OxyjF_F49z#;KcqtOUO0#+8yHZNiolxiEtRMXor8|@IgimsQNGlqVW#W-oTI{8 zD+k161$0%VhoT2*6v$gJEO>ZH;?_r0MU%I=`PheE^~>{4_VVUp(S)0iCI`iYL9X@) zwc8v4B-XuzrvFBV_lm_9Ithjql%b zm78_c|u97)mwP8W)pmwZX zf?D#Xe^d6+tj6Z=y!35y6N;}?)yWav-nO+Em249@C4zsVpkO=IlQ|yxqhV1U!I+vI zqCvDYB1F%4)gd~^7)E_BaK|wMaD7(j@4vypVY*`Yl~AX`SQ6J7A5hBzwYJK`o7>D+ zx}n}|f-w<0u1M2<&L=)M=Tl(7Es%Xi+4fJo;J%@)c|IS`?u62H(z>{NgzBu%2+f(o z(uYMEPwDHD0is>%k7d;v;fZ_2tRuo2{l zhYrXQPGLHL>xe*S(G|o`pTZ4&pk7VS)u0X47pQsG;w+`I4RsUB4VQ|i*Em*xh8y?z zX+2IA|72L+AZtVTk)WBAf!l%dZ{bh7f8tC8VTb%K*?$A)pG5SC`K_Zm`}B}G6KO-0 z^Q7Q$qT)%rd8zpf8H(uU2!oZ4|K-JZqO|Y^LBp}jqum|oieBcS(P0}A{N*?fIF-7) z$bvNFMX2tX+vCOGI@U{_#Pn$g@f00=_(9(w-R-50@AZZ;;EpAYaBiYV+^M(sM_zKu z@+dkm@p7$chUoe&gk5^6Z(@crjJ@FvV{~V+DED2vu<}B`!9aP}`=kfrQ* zxw3hqNKt~q8Ht+fE?TAbp!LDEU!UiZphC;IV!LBVb7%|yzlRzSpuKaYrCxg<-(FjxI1-=bH4db(D8Aw6L^ zj;3fm#&j)CFxIAaVb5>sWoiKs#qcHBtv9SbXnGNiIuOjBm9ClMS@w9wOnH5JeI~T;Y4|NRhqjBbA_h3I&)4e zHH*NJimv*^KcZ{jsV{%7zWgush41LL^PNHUlF&@?n25dZo{|@S)fHtXGZ%ZS>Y=6oOq&3NZ{ZSs8<30tbSmKUPSTx85hrG#>+5mY9Y{b?@;k)#c;> zFr@EHQ9--@LUz5C(m1;>XTopcCpy068m zS4VNvalqu^q%+48_db~tFaP23M5;~N60QD-Cm*$wXtjy4sH-G%EAd6={&9N2^w6Uf z2S;&EY{zkwX%5uWmAlI@o3d&eaRu|FwTLLksAwwf?|x(3THs2{`PuNgZRqpC;dT2E z-pQ<^vHTlgKdqD&8nB;DQy^BA8n4hyE5F460Zk|C~?vGK2MtKQ$vBV>4S}iC-mTxh+-w)MX1L*}D9%MHw6SgHo=c!Cwb2 zdmLO!$S#4(mH+r842p2id0;d4lf_A&PboDPbH_2Mf_f(N1aM*>gPocF-=0tBh(=ozU=q(7VA z;ca_OH8OVjmO7Fa5pg$Pwk7#4!A%R9!J=aNwm(MdWy zvV(ZroFQxPYKdjr%S3WUb4moRV<<_(I|uE3v2opq^7_Qu^eCuM&p{(NcB4!3Sab~s zT>!k_J3n;5`=lcvp*|Ihu1=G`f?a(*^EjCn#VN*+E=Gp3I7p_!tKTzQ2cxI`BQFXT z#dI^Co1EDv=_=6-YTFuP5xI<)MAQv%WGUWWj_;2DRQKjWVZGRbeuB9G2|lsca6-vV zy}fCs`;wrb?E4SQP1mE123A4SPy@-_>v5Dz`AYBUED3N6YMKHGiqjXFtQ8H(Tx0$% zjF6A}0ltL92(Tjn9F)0E4VNlsGaD95zOzvaP^j{nn*l}@9g{ssA{amV>F@d9Mm*7! z@?hnBc?{DD4O2|VRSP2|VLoDjQvbXlXoJyEJmLm3pn`D}D2=0+5|N^Q3cO<9pUTeV z#o0lufBi>Of2rzcGll+0^||`}J*^a}!k{kyd^=kZQ)xos`+r8;*ulPa1fh~=v6|k7*Td44n*X_$11gBM}$-osp9ygyy@`1RO27qD4+Amwdl$z zaCVk9`t8@A`6mrjpTd~)eG8lRWm`TCELw%$u^ynIInhWJcjbr3j#ixy&r_X$i$JtH z^D69L->lE7Psvl_I|gwoV0_2m|Ec05cd7VjtN46XeA9sTg%*ZoI1N1i_oZWI;C*Oq zwkeW1o7gR??G%}D3@cP0{ZcTVd{lrb2oU_i|?Z%zAXXYtZ7I8oh8xQ! zuH)dN7Zu>w&NFq`On7-#7gN}iVV{q~p+#HJSmHmA9li7`%t>`9EW}SMI%QIO;oPbc zyjSU``9!(K%=C(gG2zE7*$h9UgS@4a)0e|j%3!(& z$Be|M6#Qle_$kapRV-llI%i|z&QoS9Eksto9BRAKn&m`v*B@<4ZF@zFEP=CfgB z#9A*=!o!|wdzdJ~Cl$k}(0N`JJP!kG2{97IW9%~6rN`JiCcf zgRd8Hndxv6nqYOp*04Cr-f6RPEEYA-OGhC?zjfEXnph~`zI_aup?I!VFCln|U(ylm zZ;#i+{+k7trZ16d<3Lp#ui2L$mVE0lfij1nhDUJkAABy%zxDAj)baP_v@mxyimRpK zEB}%U%x|_RKT#xZc;c@vme5vm6h^wsdC9ClL@r`!RyC0vH}H~|U`1m&aYSa{qdT@mQi=Iz=lf@&s?d@3l zyWjryw~SyCyQ5Phm_qJ7epRBlXM3z*W${1xD|#KB{c_j`iVRShrnk?U0x>>kJdnQY zU;n=-&FVjp`kQOoRd^!~1XlRtw+r$NM9oujkg{=ZYt){p0MYcT>7 zD`m`p%VVXLoP}!_Ra}(n$z(2M*p!AT8b4lLX=V08b3%LK7R#szIr2(ymdJu^5~D)O zFr*}rScul8zrwRVh2Gbnsn&{8fggi5TKEfzZOc1zOuO7)F>@O22Ep$KvW>oy~ zlLVG}$&0|F$ijC$VpBZheGQd{wJyrS;OejD6bca}EPx0@Xzez28Kj!?u6jn}WPAsz zZL}(-M1J@H$FdM}GE;O|MZ>d|h5l-`>#BUTVXH;0Cr2*&h#rbnOfkk- zy*=mcc=>;A{GnS>u;b zduE}N0fe^jUy!5inXAVvfx0^VW(bVLLB{%9h!02OY4zHx&IHx52f;jW*V$Fchr>W8 z9~XDlCVD#G991`QWo=^n#BH7L4xPBOF40}v>6g|{?3tP>B9wE3ce}T3N8)jPRF{bB zD>ANze%6^-l}TZ!Y|lz$A3aj76;(NTT&xdT-f?_!zp=ICQGCM}LDI++S?c-=<_F&j z1k)WO)j|7cY2z^V?uXj`sXLg_m`+4PY9pT~wWI%(C$)6#$mEBC)GmA5N$q4Owd;dY zO=YOmK4Up39)-QD)Q45aDnkGp6SnY>Fg@QdT|Xl!-qmXmMqF7~SB6ZvXQnbgPbldrx&j*VkVrZ?-Vf zU*3`n4hwhSpBpo`AnfVKolY)6BPz zs}c_zQ<2&4md@5^@}qHRm2EBaR|32e)esKOB%4*)0;Z&dm7uYyRa z;*~GwZNu122;WVj0DUpr*yAMKrHUs#nFnTqK0g4PV_;=CO8^_W3z&Uxlu0<95jOVs zk8*eq(>+*I4_UeI>Picr|}s<0_~+Qnj*KbXChH^aLI7JRKl) z$h>StgYmnc%(8Jlwv4KDvn}10WG_l73*-<@|FPe2(&J*k=L#!5vN4Yg)(c+}LBZDb z!ZU3K_J_ywz^oT~^a3!~3pceISbP^SeeW01vh=T!DgXO4Io+0Z2@c>ti~a7OUprM? z^2Nkh4t*rY3T0x2N3)^p`*NanLb#k&D5x}b$v0kym$(&djPGidsOJVPN6@d5N*As* zDB7>Rld`z2|A%XD8SM>s`4vzrJr3UPQ)PBFpuP9H_CjGfLojCHm_QYg;AYj_?>fDW zSwq&IP4nw`Hm{hgOJ?a7kd4}(U~!qUNuf8s5Ar|?ZX{FQ`6b#`m*~o1F|N%JShOnh zR-hCjdC)dEsFKY8fi;dEEV)?U~P#RsP&WZK>+Zwiqdu zjLW1h&;YA}S#B)p-N_RCQvVMnc|NQv(iF#Q?ts7rO-vD`wGyPBr;Tnp;iWD$=AG*S^p~)2{vblL{)mg!FgT1L-dU2UTp@A*TjiID`84AW@dOrUnNewZ;Zn$R23X zlckr8R))QsI5w#ldTvR-t)1>%iI@j^*`s<-JlSuaU& zBfzobU|JVS9SC43PBJ^zz6gTZTvVSNjdP2gZS~dbg9EiWxRbuOJijZsh-%B-5A;Q< zmhhA3nWGZ~d<8R7ZPcr`nl~3k6IT>a^W}ZDJs(L~GiP0C zb}J{?l~O%Z+EdGn^>U)GNwmL&483AMq&X(uWUcjNdRS9Aj$~iN!AMpi9whEc?M}Nr zs(UymRE!K-bO&OLA}sYkW`~6EgMB4(`*_K@6edNK;*2-=c+sDwbjI(Ht1%oM-w~_s zgey2QdAm1$8$MbH+6z~7D+eNeNm|scjKB#P3*Lugyz=ehe!L>x-v8z7T;SxK&Obhz z?8GLrW|0sCD_v{|-4JBS)`o;PEEXw|s-~huiw3(%kgzek$&SgeZgnZeAFa9+Es;dE zxsYt)(j-(PQ55A&r|wGPw*T+%Iq&Sgvm1KJhn@F*&+R$S?L6l>&pD_1^G4fkENL(_ zXua|-$x~`DkTFB-Vw6c;kTq0P5Y6u_ba!%USDqKi%TmnCy+-^s;GcK?zi95nDa8yoz)qh;W%0d&y?=tO?=!n<+A3}J(pj8oJQ(-w_iBTd4GKIkXEoP{-X)%ZAt)z<2mUF^5uB1A zYutF?$X(tY9|WBJvt0PduSbWerIm zBDY;SzU#^LJzi9Keop|H?c-(SVPk=3!XP}n`Lm35X;V?@K>w+n-cVWVjZ*(br5(S= zfLhU{w=m&$pYX0v(3}1-3meMLnb-6+Jy>V*wBKVHiD2P%MYFvsrw@`jeCC=0=PWep zju4?h!Mc6{!A8hcI(i!&Tg+`$t1pPUPeeEO*;J~}#D@D_xFOJ;=c#jVj}26k4{-wVMjGoojvSue_Z^kPIoFU};JJO2XyoJzgV_?hD{}W20Krc0)ilo{Zl-m@_UdG7pr5V^1&gge{oAbSb`<~I_b7G)1@%HfAQS`w zVuG5x(V9#9=7#DZr``b(9TZ5+eO-eb9jHZW1&;nT)eLx57;57OhsYS=r>w%{H{ zfS~uKQ-YL#ENnEp2L=7;ZwVYamt18X)ULQx^DEX%om%+5L7M$Uqb+xL8|JQ6&P?l# zY9fWZEl*W*?P!0X9Bs<#etU+RQGin1C=TPeKiDWNDkV9ifnj5)$6|V($1OFwn}_&v zI3eq?R8)b7bJfhXk*Y2%s0zd_vQ}pvEiPW?M)2#uOysG}ef$Ymul_Obb?6eHC_k|- zGGE;*h!@msifNRaj9CUSCBV`j0+uB|Ti>vq%rMw!6s!PQ^K1TYd*v;zAZxJ(I^ymQ zCuapY%gH&|9dw4(RUwod?Vro_yldon|1b}glvByz+_hlV0$=zY1qnO4HM-4iXor3H z-qpEo@=`W!NBV}%I1IWCt8lO}Y|TsZ$&zJmEo<+&)dl#lco4L}Iapc9R!KTu{c>H5 zLDmKpzkY|ls{Cu{Ke+0JFFTSo1IQC=*oK5eK4H5TzwF38?Gi*Dm=hj#^WKKK*xaJr zOKzgt-TeArVvfaN7SMxgH|{AL1bn?0?kS^7aGiu66)P-@HC++Vh<~s)T3gjsJmdYe zsGMkd$a+q|MAxTg`(%nO;9P*(K@{kyEob}>*Wzktkb`ecP5N2Uq$>4~$94V*WLlsh z=U46iXWupoLi$ob0Ah*TXCMV8cbY+_f=EDX<(Y^6{rtqp(7XqAb6+~eGV$XlL=yH? z!aK)nVAy_FNWavaKLzwl%=xDP>=BPy+caYkL&2j;?13A6e|+`0QHV!T<7vE_U{{bt zf3Z3AkREvLz$0R*0Tp~GM&h*u2cOhcV3%u%F4E#eCVtc&o?5~}t;fPys)im{!FeOK z8~dQik&dy^mGeUA7zs0`L=yH=!sqpt@cQAAgl{R~brLxLa~DwYsiDH;pa37!jsO=C zem25{@kP(C>EsrT)ka8m$LfYoIPJU7d+$@YX8p^Z;n};?fT}1FIvZ;JDi#NJR!Lzo zv~RkgahopwkzVAVPU@cC_@#ig|;H3XGUz+77K;c+ylzb;Jd)MZ00|d zqqJ$p4h*;pnVH9O^Drx0`I>XxQmQ3=Va;<=6u|8O83Y&b6_56vk!unyTl2;4gzSXq%J1hh5pmX1&r7l<{uiU?FX-ckuhJlKc)8qcAynYMlb>!*yAPJ*Ku1mB`;30d5 zvPtZ3Ae&CHnK&N-0oKEO77Ik$em3ti2%XcJE}9<6b+H)iQe zqIm)@*@@9FBlYDV{)oc^H$u*`v__jS_>sds=vKJbmQ$_>2VwpZsuB1d6A6VWJ@B3E zdSb3P336c=dgX=mw@>>a+6$!Xy&Z~uUviik(D|pp9!SjjlOG>3(`1dH-x<3xQ@WHp zP3J{;kTsLf)FtO%nko+E zyj*f#8ze76Temz3UW4R9(`k(jDh_DqrpH%#(6k}g>!$Kf-Q?}7yxN()dUI-L0}$rc z=JR}ivw0pk133NH$J@qN$s>#FIZfNI{^-*eo{NZWCTMohp8(Bob`LMC9}0W>uLJtCra zqqj|T3tT3G-3HoQg<#&`g+kI5xwCB43aK(kM3J2_xgd9*hDDC?FC;WMAZaRir!7eJgGvnv5*RC5!*9e;oRjyns6cMR>`juVhU;0SdblPOEl`5EozIWk zWm~$s15cg&-QB;=&8qeCp{Vay0p)8z>4Ls{PrRc66~fwp}mU(e*A5!x#TSzzB~0 zSln8{hQWqEn-QV=ZpILwg(i#F_17?ie$e=%?fhlEcG5632m>nS-a1e9sOfTDCzagT zYx*qh=}TNUCOVgDx(K_xzwag3z9;u|^79K2lH^4)uMH=;w*+xHlBGc+hIvhn(x!`K zUN1lxW4Wim{Svx;`WuB;|B{*?>WEhu0N+e8R}1sMRpH% zGdGmV(I!V!5a5GqIg~ejtuhvqp?0M<0EWiuX?k2yI|E+FfDh&}+;tPvm?I3^Cj4cZ zWe$?valC@q{pfF+)Dt;z<)=bMs7w>h_vmfKY~{1+7YB1^+cyLU^hC_C)1obui~s!i zaNtw_sS^HTRW~I}zwnoz8&$&VHk)TZ<+&@5ycXTNo7*o`1pFw@M+(W03U?dAHJsTD z+uKF{IO$CM^y&zwn&SNBXfQyaS9E8}w****gf{osR&Z)BI{zJ=%`@ov{gzwBsp)wG_Q8w$vO z)c%TN|6ThrxBu6+zp^#o{%stv*ya|N{*0`t}-2eCssgNCDoEr5@g8i$$L_rk!jGU>qw{<(|X0}p6Cly8g#yfU*$q8 zlt1R{sE>4f%jMoFu2#OKR!V?P!4)yL;BeoXM(zR0jbAi8o!t1ZM)sFAg*K#2rF|jw#;s(*|TZZw~~D~ zv}aIY9*^B|*r?0EYm{sDXSIhVVzc_0HJ#l{pB|4jEx+s13^TIo^|LC21sg`p|I6jC z>~uJxkin<_2y|lMChnvEY@1-{D(&K4pZ!RKZtD3(u~j!8lKba35f4YqFn3(N$Pzy? zdNTO#;KNNj#p@YUh`&CGFOQtSpWA%?B~1~YuU7u$BdI90Zef#Nb|B2seSDl%{buyO zfE|>&6IBP3;|snRO9|BN(daHg29*{f!9x1fF3e^Be zn>#Cx@LhueVDTL2sdF?{)*m=z5;MkGBc-M41prJ`(nL|-CqUKy`4xMFF?pat}W{O=a^>K$9qrwkZl`YY7<%1py` zjVI~zIl$wqS5R>{p{?%biYBQ!V$o_Uv3?VCmg_UO#Fg`d)+^U9TF?LDC0nR5-jtaI z-6}Vbmc%TddBqiew@_WBP?sBQb@L+MdG%S=kdc~fw;X8L-Xq^B~qHApp;y9s{0 ztmMmxu12-&WKGf%bT*#!EiO3JcxgnQm+5EoHWISAJ@dQL(T7n7Gr?GF4DqXs$E|$BE*Bu&f;sgl1W-H={^*>7dKriEmhL6db zdyI++itNfa&OXbYDYGh5Q^u=e*IC(UVS%3&j@;i^>EQ6HLxZCBV9iET8X8c%(}H_Q zi92#D_kd*lF5$P$rHO^lzSSv|-S9I+f>5|$00ImH#Qa{eD#Yj0vrT+9>PO=9ru8@~ zKD)C(B;;vE`D;=^N2SOL%M9yenE@oYpZJ_&8M8mdFWdWXnADe^%7%%_?ZhMum_A+H zL20Tn3N3j<0kdKc2}46Xzyj}u*Hyv$E$t24igoH~f=qeqLkOymyly5(&rgdC&O3M4 z5#VknKW*-aFF@iFA+Z2|(+&Z5j12NnXZYjx-H3%-T#<_3`dA(NjVKWCioiawfcM34 zy?}v7bU@4ppR?=j!EYY_4)pXvM$VC%(4X|cSU<*#^v)mj<%g)|vxSs;qEf{hiQ|^~ z(X0CT#yw5N*_ec6P7oITFy_uY#K#`vh+(squ*CENddgPUTba9yQCjsP1+u~rg&_A3 zZTFvItWc^Su|h`pF3_YqvRhSD@&#K~PCJtd6CtfG|)u|j`+ zr8vW{N|@29xiL?4z^av^;%Sh({orUXAl9D<4dthupEh^RXVC0{PR8H7eKAMi7sR;B z1ZaX!C$AQg;MW( z(W_&1?rpX&Rk z^B}xe^6?MhN8`KrL%cQah&Sf_v8)XpO8QA3s8AcF>Uc70fl5OLGHn#^TEutv9Hik% zylvc=DZNb9vzif~#zSs#6d~ULf4&8Pm!ZetVv9}UwIi$ry2r&|J8>~?S7V7qZYRN4 zo-e%__(}@ki$Y`ggd623K{zX^WTYo~ey9}hz{`?6;PUq1I(VD`y*$>itqLSJmN)cE zZrrUQ&bfb{fhxg-E#ln$q0q;)ui+CY_-42D!)d31j&e0m^aFp=rDK0bJmg9aAfZ`A z_xSoCeFExc=@-Knzn^%xSK_**?z8S#L z1);^EJvY?bb7lHrW@6`XXTo3lEf)gx;Fu&hPVl}jc;9!o>?T+^$OEijVEycm9i|&v zIBtI4A}POgbH&Fh44}gkWz7};;zfH}_tQ(99C|rSFS?RRFDK|__weO(M)~j%%F&5T zps(}miifjf{U0`wX~v78L9i{LKfWQbJ?9la)RdTja5o}3g3P=y!#w|vi$Wp3GE*%* zC9wmYuH;o;+8o#AQhOK`pT!xrDhWlnOTFQ>@i47}HBL*`{OS>Dk_pU5=D#O$mp=Hx zII`4q3^)pKTW+R6vgUHjv-Uu@zFwKqA&zH1Db%yM^jfS==y4=KL4acqE~z|Tzi z_Ku(ZaOlZQ$4|3I;rwHZP|^5+RnT7t9TKNQVOC=ic5febJ-J38$R%Oyg7y=0?lIyN z!tlX^27_r0UlCLu;12ta^|9m_QG>BcYRBekXCFyN?;_Rh>a!euStQF5Lc@>(^kyS3;>NS6IUHhGy50s_XvaoF-{gY# zX(Ohio>Y4>f7?eU{;o|prC&fzna#bQ+m=&n=A#D**`ei7SK1svM0{{}kg=KXH}IYP zuOHIg!G+x|q~EmT;U7kqbLbO&E&Deh8$}UK?VqOA@*w3+4zML?cC%KGrq$d{ofz(h z->W@-Yt?4nKFd#OGV$L%D*n%7U>owfQxTbP)GgQ2W0mi5pls#%>Z{<_(CDe;b-0+L z{oy^R2H4P&04dlSZ}oFdqa8gakuj#kWpK~7xf?zJQzsav{wsKU_k{O;r1Tr%HG*Ny zAfI`72la&asarM=?_XJQX>)JC|G&YzU;?bj3Df6AZgPes|hymiB`;GOWB9{7!a4ZJ%W zynFtS@J_UoP73&8)W3tb8~^qO-g_SC0q=Li+wQvShja0kx4G%>{BQWZ_b)y8Vcw?y z4!?qT463!^WiQ7Oh;E$ z&t6P75-q!EHYIyU22HJ=6vH|a1JvD$|3O$_&N`!BKq*$0(yUu~iJre^Clzh-8JLBF(w z+i4oNOOE7F0|jvs09%rKp$$K9ko!PicjT+#R|`UuEn>0ECFRNajnDNr96A_b=Fr)o zCQ_@j(=fmI42<~KR=X$lIdc)O>)ZmKvtukh{^0II$sXdrQdGW|AsfOhSQH_Qk^gFq z<%I;?9DW;5HH4kHVl=p1KDrN;+0q~JP}biRXKkz)T}xBAp-0=w8NcP>JNBqBF5GhD zFXu(6HM zJ(2vaN@jN6_8^@<&Rt*0&kj!{ueOf|d}kyd9~*E|dgi=gEgiE;Im@G0YJC4;7IIVl zmqfGXUD?~L{-u{`HEYQ~wxH%sR{8(VC6fGY7n>=BSzUn+`kzsR=SS$I8ji zP3|!2&dq$}3dSeMmYdxc%wB5u+|7PHrYq1gJO9Wh|AJ)OXwBY-Jn@Hvw`xibxU{sw*^}Kr|l7@(!#m>Jq#d$vpIx&_W;W_Csi}f4Nhd zV{1GrgI<%$)8x^ngqfNx_~7~#Bk0Z@PK&v#rQarLvWK@uf6$sjV~i!DDZyke72-ax zxwGJd;fs-k5&rm2I60AQvqm|>D?NWTk6a*}DXu*>UAKHH`{Ei05Poy~=i|5xuRoW= zvhV0^@>uGz>G8{_@afVMj!TbUwNa;g+lfQ=or}PiPqnj$#AZilMzNpnvW>}_@BW|Z zNws+7akwS6uv%EHLCJ+pv?Pj230_d1z z(M!@#3bm-xulf$TjbZj!t{@1efOh-fD}ko$pg-dnbd;5r~2- z&dxAVSmHj}k`SAR`6K-~L-d;}`q91SiY9fzk2d{GTWK$H%RAt+X+|7>-Ag0`@agoP6^axMr!03<@Ou(iXE;8}mp7KmKK?t5C4L3!c zz$=_E{#6q5)C9tMt=iU#C4%e?;)2dj2gxN~PaatC*_|%r<^e7uEj*9Fb4Zq>2<2yk z;Qc+p<*&q!i29pADJ@-X>-M|p+1)W`|=Mz8!69#A9FWb`6ub0%F`f1 zAe|5Y)^ zaim1G#0~qG=#n3!+!L(R=avSU3jk;%Hz9K850w8EU%8bgcXjgf61Hz;CI-5+Zeq}; z=IgVk!w_vEH7!V+9|Z=)rjxl+kA)StF#+RX4k(wrRWp zz96G|WLed%O6wL!i(yQvTQ6x-U?<2{or??ZzeT_1y9CV-*(YMd?Jb(URhBo1x+rAv z2)YRf5>5~a(PR3vVlgEk5}b+y?I2JY|Mogn7=8d$f|WSLFkP!Xb%|y>lT;@lq&WM3-N`?R@z)(~h4My<`#lM?Fm`sNh5l;c z4b~#8eZ&oBE~9_Axl_!sh8l`PsGBYlu)1Kvo$sqU=!{5JuxrfSsH&b{Yyc@9r zL~#jyC!#`xb>sII%ERw)fI`^ecf?b2%#3oP7%>>Ww$mgFb$*%F@XE1ye`q7WMI^v9 zVsf)k;31{M*{r#0rkFzgfA=L%)hfC<5^uf@yC*VW9aW3&D#_jKlIsEZH2RsRtpDu> z?=L*O2!&7vywHW#hOZ(rX( z-`MRVP7%x;zXb_{FMTezmvV8+hjMl1$PC!kpr;?8qmwq7_-)s~&U6QYKGJ(%9;HDS zp}X8u??Ir&{AqKG=xTOsz9U`mgNuzmxQ=^66kOM;zOWeEq~A>V%K&$y-ZdW=GkhT# zp^M-bH0I;4%OH*Eje7g+&kOA=IZ}$CKHxMo@LYxwP?DI>-QLgTCSsydEywHKT~Mtb zfb)%{NTbE7%v4kx6=*?dcQM0As;#Vk@q&dMjtNk-;Y|nwnC+VLu9AI58zWomD4})~ z3Qk=mU}}V_pc`~*&wT6oZUokiGW#rjl-yLl!(tjJF**o{KZw(xe`~kp22E}Aaw5$? zF}o#y{KYZpz;5&ojv2bF|NI$xFwsI}61SQKgGS>n@Ii;1@mSm1P_d^B zs;Sy`KSQ?El(B3Rf0UNSFt8EYL=P^(t}p@=!g@yc&$ZTtWAdNH8ou;-kR4`JUs3DL5He2@0{9)_#p1%a2K`Q+EJyt|^l7>XZOO(J(O3|x zgL`Bj0BP1$ZNc2Lc?pM-v^H1VZa{=$G5bkL3yQ;Ta&p@#+Tsce5Wo|3j3(Rr!aSo> zOLfe^Mr@ifjCxz~$>({A_=7N(VCO&?1psBv^<_9W3CJJNlqMf^Z-Ag#*1!E2D( zlw0O@0K9B*sGth;(`v7uwpYWm|M`$`fquG2zvw6Zl06^C6mb~N>_hh!zE3)g(uWt} zf)RV6g_$Q>2F8`HO*Ew6hQ8F8GS#yCrJotPCq)$2uh)O`Di-iAE`{6XRV=obc@<6i zHTLzlPRX!EeuHuaqX6d48?Leqvs_GmU04J9I{iq6?~PZ!dJ#%W-Lzd9AcE zh-Y%1c%MUBI%`^aUSh>$I#xmq> z+t0KD1D}^Elx0^X(d;CeC3h9`SLvose0YJaKB_X&a+=^-G1?jq(x;S3s2MQNrvqqM zDzhEXO~0?W9muH1ENU<%G-3prz?I2-K!Pul1V2aHc5VY#0X}*qSQ^c-p91P(l}H~2 z3+8sxjI6#6S1IC2YqS(-T*RrmQ3h1A42GtQn4L6>JWUrB#~K?&?OLgd!|T$cG1#YH zEj}Mom#U=(8SMy1kV5b8`o55^H&9TUyHw(Bi!)!9k_1y^KepjRPh6tHbqvHh^3UBMR*)tTDyQmcQo01M z)CjDz^aL(E^7+IeWP!brnnC(?k#43SYR8q<1Muu#Wk0&Ocry$huq~s3Pa`Y@TNz^ ztJZ&6h7Q0_zd{`Xq)@HQeo}IY-TPaqiXe5flmzD0Usw4lo4WVHj8l3v^yCmy zJCyph4Lv-8hE7#OZxi+4*6QgPUtj;*BCVMtw?XwiX!VH)6&;jr-Dp6|4oEk7{4<=m zzG1EjzHb`GV7n4GTveQ-R^A3v+;7RB@B8+S{7s}i+ql*Y9o-+vNAE5Cw5m{&4>Fvkaaq7(7BdBFKbdS>{h(jtr16KANbHrkf3Y^OL7#Hetla zhswgf<*4_@H<#Bcsz?q4e2btORge63))(<-?TKxID_+M5Qea%mV;3ry2^4 znY`Z7ctbypI!Dcy@TwQ+6(co(gci=AuzN`KwFpMEa~v1^v1(}Sx1vc8kb(W+{EY~C z-oA<0TvXB3pTwL>3IHO_YSEART%~V2-Rgz9%>)|LkzQ-|kmmPP=9$$mU2s599h6+~ zZN~nQ9J^SHnKcOz7&2=o2o{zH`3~Tpt&|GvT2u5mE_Xv%O@%q%I4eSETO=8`D+yo# zGEh9Xvt>IfI_tJa*?j-R{|5Ae&2gknX=Q zlGB_G` zSOF3JYOHUR_5u;BR>YEj)0>0%ZW8$&Dc(V#mhmW*ejc_=qq4Td*}gqspr$b*yN!yL zooe(AA6Xv%I{^*eutbdOAh@$>SvW2fcL%Z-OFCHQhMiIr%e~lzpl#Tk&W{V+>zfhs+R-KqFv*;Ewa`b7#_jJ+i zPK?Klb}@HZ@7_9P4{E}HJ~VYjlZr5Q#oQg}FS>Mebf>U{(zR>c=#AQ@9*kwqOQ)XP zy}qb1)tSENcGpH2#k8T~3tc;pn{8Hbn;`&Q?rSzXS@CMOxA=fv*D+J)@m`k#3zzP^ zoSPQiU)NAyaEPxDC6(_+vgXIib=i9Dc!E^!1-#%?)xMjjk2#Gj+V*p4?*j!d1TV9z z7~Bo*F!Jff$ld7kBaP~XOL!EUl5Tws(1mCnP@3E{I&nFX>2~V2+3q;IU~hSh(GKsJu2v-)Og8(8fsj z#@6J{#4kQ6(grgh)+56os((2Bc1QPL~e-!&v&GbKOl*C$7|jm`#%q!pg*ayDn@=wii=?vF)AZK=PF` z@@4yjiAxC!d2BK7qZ8LJ9^H4fP7B>Ls6HssvXxPSaP;@o>lexl9WyVBK*lHZA0WE} zg)C4zRXEYZ3~^1@788A%qECa|(T5=KHTTViyBZonaBpN%rCcwVa{;qfX1As9lFYH0 zMIG%-%=ck?&$&y-#o&a-9jU02O(e0zHO&=Gv@ezo7f93E=JP65)?OY~nYb7)ZYExp zfA6@6W2YZBdz@p%E?*w6pdGkAbZ)rB(eUjQn^Je7^(q|#Wmf>ZKVg}=iLj9yD|B?0 z+dj|`^dEJQsGXnyu4O_w5r0o}JNT8EyjUZkX>NTQLy1fP|O24~2 zUmEVq-QBGMcifZo;V96*d411$|9?Oa13!Fs4h)9ApVG9^)aapb*UFwMPqKO(?L;COsP>IPz&clYhA@IawXJ`N!t;%qm!G86PiuM zc;XP1I|6y;TaX7FRqxi9pg_w8gXy03qNOd8mue9wdd}% ztVnab73H4&2W;xD3cuB5n#%TMTlKvnVz3YZW4$C0GC*9vgXzgkw%{k46)!fi20J7ZB@M zV_%8$t}x|ZY6-U^*p`!{O3ubzY-(#$`P6cQB>OTQX>(7po*1O1tK_PzZl8HVo2`di zerucUS~rgZG~KtwHB)RU&de4jh#UfLls`*FSlJ~u8+vP{X3;jBFqO9QI0-bZw&#FV z^~qosl{<_(r>3|Sf8p8JX`#)vK?X8Y@@znd~Lq!2q)#r)q4gB@|riY-*1u-M$z zr4+%>gtQ$K3`@ctH{M7Q86AOJ3yA3Fy)KF9XSg!vHidQtV;(B)KD}k)1CEbmvpMnF zFq^jMx=yq z{{zUAiJ!GGl7RMzxmpt1+>fv2CXU?+yEi4@MG9N5|EDxa!TP1xE6{$ZHj%v6BV+ca zBARMELOm3-Cl-Cs-&lR;;pkIJjH85YH_9(ihK8AmFtEs;E-P}E?t_4@%Ut~>zCel8 zgSkkdLN=-FWD^dn?PQa3cOS^4x4kcl^w!X@Ru~n?Muuj+W#aD~8_8y5xG&6BZrT32 zm1Wy_c_f>WLFK7za7cznOTp)2IKa10N@XXT42rNxx!cmiw|@^Z?H4v&X$`;Wt&wAT zz_(=qd^H}vu|42Zd7u~+!Z%Rxl?%SG{Z(_j_h>&`T|M>p4EdiT(BY5|@ds&e_lv=B zN4Pv8^KyC9BT%j=95x&F0H5d159g0#7WpA9%w$3zuEA&Gdp;WG+J#)XbzRm)k9dO* zX#fzwiF_T{7yOAY{$02w`!OC2TYIp48PHvu1eXLUtqlO6J8u==Gx51rKfXRCHnz`OZWA&A4=&L*jws0BS>Vm zs9br{SFaZ8Fxj_ZV33wF68OO&oNhP%JzP|3d^x|C)VMZzadA;2*JzMETrJ7XElnDjuCuwv+4Tj`l_=cGU*mV_6`bFpC zY)85ALcHS2B5f0|{3_8rR29%sQ=uB@ttQ=wfzrr|$RsK{sDZ<=N*6EL2OF(@b3NZo zC9Zl|9$-KWR687RE2!huAa;gXMhrsMV6mGKX)w{UQIOO8NR?!8F(VZ7)uOXA_mDb# zEhhn=X){9}_6e={hRq-~B$Zk1o>XnBW>zsqF*kdFH<;N*j{NM-W+>BN`odN@2IcM{ z`_^P%o4Y>DeugQUe0D~?mu8`PF@o~fr+xiSpO&O=D_ z1l=G(b{4Na`TalnvQRL%3}K3G?&QZ1zsqgz)@?i->BmECXE{94N0shiKBeQozd)O$ z6D_8&Fg$C;GyuhH1lkP`(lv`Ntc%qZ{b^k4Gu^itEP3ysx}v}E*q3WI`;Hs>SzT)2 z4P-ew!+Ix&?hvS)x!YK)ristN><$^=iMe8^y3E`d9X%$sWE|IXj@xacg*DG1W!$GP z5rz{CT{^CMO&wRia*)!!m(_8}?5Hv(Nx{%{{_@ntb(sNu>J-o~vsiNz0+5aGM-i`p z-&}8H?zXq3#Kp^*fs?7Gt534<2{;x7cB2OOs6i^6Bz15@YK^<|Rm!F|E)>-6XS}qz z7@qL#ebQ=O{|fLs?T24C+~8*EXp(C%F~4tg4l+fog zVhrN-`Su?BF@BCWU74EtMQ2m?P|#jtj*e-d&5>#oZ*CYL7TAP&li^g@PlXE8W;C_{ z=@cK+1s;lz`P+?N6+QI665vg3r;z?*4a0 za>0>QAlcB5EQGkOdfB+tOWYc}4hGYuy4*J$6n$kAm!SHqMj8)WZ8I1${deJ3o#|sZ zO5X$1Ss{%um=jbRq(;yr2VLlm`y>CZc9n?Sl;02F?Qh`Y=%j)z3`q zi?TXY8s&;={Vi+%Ffm~{uYWoX%s42dh`(51=v84LE|_p~LXt)3QFwtYBnab<3w4}-)ot`(gK_cv4w zX+3p#FK!%Sd4=zLE&VWYDsYv>&$QB~v=g|t#mr~rS*U2OtN0exRP3u$1or;X-iXXB zjnBjO(cu@c*`Q$ImVdc(YE8et+!=hDwb3Fd;tbBu`s7bS9l9#Hw5oM{#XiA;XF~=E zKFtM1>&eucLpc-kSDn4`W;(DW+dtDk#p!ja7l*FO992cz`v#f*^L3!z(5Ev;>%+Gd zDKo@G6@W^x{0u8)dT@OhOS(9E+Sb;8b?n*4_5rW&wKGO+L0}~qvi?r9&-=DtnA2xI zoubbJclDpwOwSEpsrMs!SB52&TWz@c2r8}-jxQiUCn(bQL>Z@xwrA}yF3$XZA4a<@<(h&la7Ok$&HFR)Ne4%2BU8+sRgl${JcQ^@_H&9t`D!SX z2lp`pIz2Vjh)N?*HyHU zZNX&zrGSs2Y@%9L)p~0G!9lX4--S;> z)-$GmhYD`7O@g|OdkL#|Buf)~x?aNpI#e-Nw+nme`zxAglVc8B`C%wtLfA;Eec>6r zxvg+Cwz(O?azn_;~_~#%~&*49xopIsBn!)Q=_WB)OcVrY?e6wg~x1h6cW6XdM z@0eNmIrOK@Ra&fDcf7CmC_jY2$bijzhW~weX>%Lz2mc@Wp{xrZ!arB#MePq^a*(0^ zsSx$v)^PKwA@`&ZT3G%<$_HXcEH?e2e7)C&JYh|XoM6;cb-09${cnxf(5rMZ*_?o< za1vB$lOVo_{T<03ckuyJ94!eCRd*UZI~Bsyc^?8bbk5&tt~P{8^&191`4=@Zz>Vn6 zPdihs0K_PR0gv-ieo2pPb|tRw2iYopwy8a`=`JatxPyccLEMxgD+4~aSZqW*w)lJGx4JTbvt@i9{*78x~G?^({k(^q37!!MUd z@W3k0U>+J+ORWAVk+ciBj3qGBYJ*?nR*E&&B3115kgTT$SK#3|?@k;snSp2V)3MrB z(gI!GJ=zCT#-g9KFGF^QR+d}#Q6;DX&T0$|8|e`-sXv?l8Px@~;AI*UlPX`j^o#$q z7XQUh#~L@ElhrxTi9f@_{2rTI-JhS@(=#>;;fqL!qhLDZBDAXA$lv92(Lf+1Aao(` z*9Ylsq+M&>3A914;`?={^F=netE7P@Pk>~_{ZQXIVPJUo0zp^+Tepsm4Q*FJcYz=K z{uRw`SlfZ@Zal4LPYhWF`4JNOb*zyES)wIlt)@LfvJo|VubAZyVg%WL#-Hs4I(Bt! zwoVDHO4wEjU+HO+#S)4?lI(MJ6Yqhkxah^t(hBrTV$Qi5*$eIi3Dw9*V<~cX`3KP= zc%{;Pxyq+XL^Zm`r{6v{rc=(B$Ezl5@i$XC?hbkJaK^R$vRepLTSrp^DCnw{3ft_Q zf!R~UH|fI=;>*{m;L0+elYyn3WmU=iA)TVqd4cf z`83i2dk@8EJafB%5TC(}d+5n}ROEJ2{xs-L#mmm%5YxwNxlcS3A945)t5lp?qOQ56 zz5OJ!ELrp7k60N?w4?-MDxUqnajdw%aV!09IFBfpsxJdloAH4FNX_g1?RNk6vVXhC zzkTwBb}iVvbP}Vs&C+)JWE%wC2b% z{iHkC&VGp2<xg0g=Z>0 z-f2b9;>H?V4-kn58Ec$P#mSl>2xsilCU+kWbV^P?EP`EIWM9j;?@9@`&Q8z}kf}L^ z8r?89+1YL~$}BoRQikv__7A=&iUfC(=M7i}Gya1&xZ z-gH>Aklm(rx8>Uh|Kjx=p1Mncc)2>4861Ic-hf+TJHJKFt4t369M(Q#+4S zh82gw2+Dt>3I~}B34Li&jdf{jq^^4T^bz_Tq#jZZJi0F>YtB_gjeW8bi-ogw;pq}AP6K}O?cMm+dBOocH+2j{hm#}R9Guv~s#zqA*~Ht(UYHQ1t`!W) znqq5cw;+|Y9+M%!i(*F{2s_v@_2Dg}Gl>uU%OAo1dPMBJ$Aq)xz~YwiO`DO~&agm_ zsrR#Hie=)XEfX|s>O^dw0L{NKoU|HFhzS=%M$7!bt z9p|AMo|YSuE_tF5^D)Lxv~1icxN5#FXsg-(Lk zrf7yupWgg~`qZAA2dX#jzNewuJ=l=vlys|cN7`5eBKw|PfKHGHwEDT}2XiJsp0-4l zJ)f+(`uj%PAT{dw>?Vy@sZHzwG3%$@HCl74v#(i#b~|R`cl_N`SPoT$0*`<=Goh0Qn?VoJk*d@CaVdx3ZN)@s4~ zfxDE;Iia*WkY9g5QlUHwqN(BGBlXBy(+ti%ZrO(?J`%yy($_!gL=qgt`Woq>b7^H*c z4XHGv$;AKlyHH78SMOOb(AnjsZ}B-lwILstluFzUZdoRkTiG zeYICc6XDZ`4gU0OXRFyrru=B9Jp_H z19(G$J%CZ84%NHfe8~RU#OcmhTQ``;lu|b3FS(-&L`~HBjFOCu=AfHCH7E>(|tnw{gDK#Y8(mS zX=RL$bdCX)t}qy2To#Vcm4&tqeHqdN;ZG z?$Q3Kt=|GxEPV9cGM4!PyTsk_q(HbsRs1n;XoSC1P}yZ*Fi|>WQy_^LrJwvdm?}Yl z%G__BhmvUaaeR`&RgmvyzwvZmQ3qL0go=R}@TM$#HkRgWjd? z8hW3sjy1jlV{rCGZcFT)ip)_(bhupC70T+TTNUYeO2vyyxC%#c3`<_4c>LEY9`RPW zk(c?-`_uHzQK86gYN!(bVrpq;g%0z}Tn#yO+;~GKkVoXJOH>lh6t40861{o(U7~n$ z$wrONtoG|px#ZtUbRmw!0+g4y?e9`NNPNdr>SC?&HOJR6SBP(IFHiZGFDEEvzJD2K zFE{v?GZ-UU<0)PugiZ~RyzMbeqANHwos-kUeKkJ}JQ0wUcBUh7-2O831(xF$Y`r$u z=VuT|{?J1GkeFk$mjZth1nhDlja(7G?f!8w1v@hZoZ6;qG1`#cGkM~kfVp7beU{-4 zkQOeAakn$(Y1a6fpcgXa1rQWn0N;8O8W~)Ia|J+y;tf~|Zn+$j=l|)84mUVWMJMmy zE9MS6#E+nswYey-D^w>{LV|3QNZ56;+M2ae9#*$@e>OEKS1SHvpm7H**5<~`meAI{ z?fm)ku&+AYV%t0{qQx`!jU$NUta@&&98&?ZOP83Mz(c9_Z2o%s)*hZgo*{tUE5Cb< zMNMW;sG$ zbm^(f=|Z7diGK4%oheM;i$LSO9NaRS|)HmVNxh8 znEMB=pq#k7diBib@OFLtQGl!u;r^$$dD_BSz6UDC8jq*bKdlspm9~>a-ja`lSW)Ay zJ&~EzVW}rZyluM;E`{YkLUUaYIz4XIh^Rsv9=loPJ zxy&L%{5}luG{6n`t2KFG^vFolV28YAC%6od{s0#DlQ%8nbE6}$VV=a?He__i_-ej) zVkFgKx*G5rwYgth1LQi)sB;wT2ERYyFM0(|m%LdFA$O@>FP)i*_fvla(YPaQNZCg3 z8dA`J^X^d|aEakL+X*Kf@el7oRX;1taxcZP(jQ7rUv0^#rAnQ{iq=DyNQt;!4|{Pz zw~;Y5yPPWBv#e;K04l)ej;e#4Rhr}@t9<-)jX1HytzbbpNSoneMdfHpU#$xIF4Y}G zD`x8p|4{+VUUGwg8Y5@|j$T^XuvL)W8lLqL^v5GmrSHtsNVE&`7i+wfsFivO!;mlX zSygz5Z-2%-svrC+M9gXs(^S*1700d*ZXU_FSSvr|cISC3#XWGQ7uu3!&649(IZX>K zsoAx(kXz;7G7I(QZl_zh$AZiPYuz8GJ5OC@0`OB=s_FyweBQH`X`L!Cg%Zls;viR)Zc+12OERST97Ihyh0W_6cwmt0B-1z9|ZfWyYt30{# zVe4PLf==nXfj`zhDeSpzqdp)-EIM~Ll)LdBzM1194I6xygbka7x_vx+Kif5u&EOkf z0NrQvTgqY zD;wfptkAp(zQEWmQ~E}r%W)XU20&D;Qn=ymUaOR7;es=3xk6crYDL`LHBNgFFUuEQ z$NStO_waQ%ELcct{6oHm_i%H#oB5po@QVB&3{c*q>N@5D9Thiar1asR-Z}+f!`xfCxjA2s~K%fhW@eyGM|2Qx?%rfLX4g5Q)nA^vE^I z=NfOhdW)35fQwv8PIc(iW#(ZX4ymV4z=o>wjmt*x4|cB!-4wbq0Cqer>y zCV0*Q^{Uqdzn|}?i!wgre9VpZx%|HBH`U9_;1~B}U+Xqe1K6;9^&<81@wxPJkB)pV z=}b3e$?o+2iKOC6!sR3k&(iM_N1$=JQU)a~IG$&gQ$mB(Z8wMGxp99;ubM_BHuaO- zL@A&$bh(BMcNnf_aTiXU3GxKgd)tjC-QK{P+_1^d`^_q;zM_o+jZ5S%FAq9aj3LkX zG5*Xi#Es<;Chsd!?Rm_ycX;twHppFonbcUCd|aj3oXivrm{o-~5Nn}kkjt=KDIhqZ zg$=}|oedA)kW0GN3}EgjmIK=={v-n2nZXQ5cWgc}^N{VOy|-(iAm@0$e^s$&*!ay) z@M|~c!lgfXJHm6rg^u0}p+-0Un)ah^yamEJu%mGVl@FV}Nh6R##c>ENz^;rf(g%=W zdOva9vgQp9Z+Ed5tv>giNUP*!f5rmwz+){K$}MKF7V!79(>K?C-^Sr;U&yUoAf;vy zEMlaMG~SK3Y5e#ejqB3uHg~WZZ_Q7z3ffQ1nWO3pU5=S}@yxLhvbaKKW1cC?+~u5w z*rglI;8n~~%Ff0})?9PArVD!rR@90=N-7hd6<($1&PaO8qTD={%o()IAkL_Ar)Ww4 zd3Q}Sg7W=NK?wow25-{CTi!LFrRQb&MmjFXdBcapFNt)(rWzDuzVf&3Jy_9Xvn~>o zHERx22biii*$RjnLUs5laR@I{_51Gx*tgu@>5iSE+zmeFv%=>j!N+H@3G5trCAqR#HBK0yb!ov`m_srT6h>A`E#7ZxYK>ecuY$@crB?Yi{$ z$0Qy;yf|-`J>69E&w>H#C`E2J^|%NRZ5k6tA-mHv_+e}F@7*C0J= zP4cqh-hbRzSrTJE6N1<Egx`~xjazag7ro!<#KEWO3M!@CGJVK zspoFtJU1<1rXc`dITNR@Vv>T^?jU2j)NyQz)-dMT+bjM}QEd$~Y*8IHUCBqSmr7Ib z$nCw&Ya0)bSd@&pwP`!kFmqu?>bJIL|M}+D?A5O+(m(aE*aR-~h)(1;>R2$aQOTvR zgv;N?fe$l~k~U6g>Sv5&G6M%`2+Aw)L2ft)9Rx^6Wp+3jR>YqLR{aCt&+%xenFW_- zFJU0%R{Nv*$v5mOrtv~yqgHsj}`zOaz16 z5OocRsdHlti=`FHUn&;p)an{yy6JBV?Jw|`MnKe_W&DlOD`F2C4Q+RM{3`XS#NBcP z1I^q^Fl;_d8d83Ki!_e9Rz13^;fI{uS{0^b*yI>2_K29_R z)UH7()*y<1MU$~N737`{bcPX_KQP}&?m@><7$WJnIzK7In{K=`VAd?o|tuk+Ox)}NSjzSlok4CjDB+Ng}+o6dsMauobYjDYgvHgAA{ZEZ*c z<B~c3YNF*J@jxcNL91TE?v7Pn#i*U1O=pPX z%D5}cqlwd1aZtyq022(y*_A{bIzOG}JI2~4NfmVB*eaNLr655l>L z#AA~3lYGj(-=@8ec#?N_+H^}hE}yn9rQ|Xk$%>kJ`l@h@I7d~ zs9y0OR!@6&w!Racc6el@GKM_;0VY#VTnNT02N+hWuMR0RV_(DA@w~fX(=2W0eA*Yn zrW(f29PiZd)4(H*)J3;f*|Niz_lxWIyqIoYU?*`*S3x?p zT8tp03{JEmiJ^4h#b$o7!nAN7#f)AI#PE!R9O=@%4ycQDtW1@j$;V{P$&#f+3wFAR z`4q@CR{cwt_L-}nfuGLN4=34SHgP%nassesab^6d4}|~NX-{PC z6^B_%{&*D-u&GEyW6Z2!tgw8;H!wKeq^x;E?`1!XimZ%Kj5}zRj?$It02B32I7I(vbt~nboy#wnZ;VJ}$V58o>cZDQ9aH zTBJ|O`Ydm%`RD`hHUmZu|y``c%^ValaK5zCOG#%Ny;hMag$W3&vSe}PZf+3H5O1S|FOeAG(|Ht zTgtRu?1~97$o-#t;!*>nk5MaXR(_1uiQ68@63tK2Cq{kn-Qg}m_Qji2va_$`I#N{$1qlJzS^(*K&_z!{`8=4L$raVERUxaxohJxtXWetwt_KgUR|7aKq-&Kq#0=XzMs zaWtR%4WW>zn0D8~l6-ECG|?b;5zhp}+O=4+paE*B`p8rOg<2J7|d+NXo^i8iF=n z5#5Kyw)R?%oAVO`W{LJrpi&b^WTL=9bTZ62h|azCQ_S?EnL35FH7z!A7BlfNX;On zjEDz*22?M(zzM{1__T7Fo!zSwa*cv*>J_rWzU+bH_YskL0d?bQr_GYNm97M@t$W}og^rb7{~$&|iuwql~d)zdt15&(p#waI*P$!k21 z#D1Iv6kra2)nNf!=4$z!fgDfed8D?LSSnE&l82ZG<%#rvjwQ#MEx&F0==b_;8o?MP z6|kQrS@W*(bjy`iX7*x!I%aFb9tfc|+oQ+h73)Y~u1pP?oo~T#c|S-j+0tOW;zoT< zVbm3~lx2euEU{R5IDOWztl58vWv`KDOC~zv+wU#MkV!`TRXxu|!*;Sz=Konc6Y#34 ztM4a}D^ZCzD$%H*QDX&*8WdYnxitvrMS|jtLo12{wNw!j#4?z86X1Hd7%a99sA$z% zwRJ{Ns|i?wGlNwesyNkiz1rdks5Rg3zxFxFNuqtDN89pg`+ zuu{c5Rj#g-TrQ?}IK@lDKlTGh)G*De`Ui*)kyFx&5@bd>uf0e2k96Xqqc0d~ZT^l< zd=mYk$^R*SUWTvg&5P~q-Zl=J3xqpor3vy zS=jHGke3--be|W#M(-2mtLPc*2H)c%5V@)ykuWzsV-lkv$l|IiCNOA{z2Zyp+fKiV zCr2FL)V)+~>g#+CByN1Ywt%_caHdH3lx{-=x+UhHWc>c0hU+A|GE~2D0qmYB`5TY6 zHJakZb9YNUW#CX{DK;=M=i50H5hpW58++v%11>9ht-qad+#~lo#bsP^b2^I4o(5ZV zkst9n#g6_F86sTKjSzAU#Uk_3o5Q|K7?JbT1L&h?K?=U=`09{L_#>6+lwUa}?P{Gp zwS2OKU2Wgs;9t!<8F+57LP8OQ8ZZ{gWifv!lQKM>&pes(Vn--~s=>TboK9HuL&EA3 z1C^#$O4`m!qhhz)$0=!nWQ%R9BqZ1_Ot72;oIZxSv^1i89so4{w>L@o>^}*TuXiNx zXqU-1`5ShYZ*_@R&oLFGNl_ZFc!owbU`Xt^BB_D$kBSDjRW>TAEwOnDLe$ccV~fuV z&H(%kFA8LYj9qRrfi|tWN10=-EsP%`4eSdp=nnojSZ+yqa+q=;)~Bf4h#elrTw!H| zqyD)ZOHIChVeID?+aYga+eMESH_yJeZxnL2|0T%zM|*$hf}c;+q)uIgN}B4We9(*+ z_e8IV-Oi`qa6So{|AbK|LGrBQh;}6bu~4TDu0P9vG1Ur(ny=QrO!ht1(NuCRC4-<{ z^o^R!4qjo0c~l-DmOoSUiE%6XfWKFuW#%4P75k9Td|A%_!HY{7YqgXV`-Du>%AIQi6Y(ghz!xc*fpkx?p<5xGAA|HSr7t{h(l%6;R@z)`on zkD4BDypLbC28k0psxH7}BNYo1#f*&z-;%>DVxh35&hZ02+hYCs_4hc>5Zyb>nKMiU zIT>l|Tbxw{yo`qi9fh{mD?)#+j~SC|#i$=)cw3)jP9E2HiLJ5Y*$%MHeI zZF@#~oiqx6o{M-ax|6_6J{J?wV%{G=pN!O_}@f4{1}yQ znONTC0Tz$w>l&={$>R-QsHs9UV@T0^vz12O6fwr^-B6oMmpn&!ThR-O<$MoI1fTpi zAcq~8q&q@ zC6}u#l*iPkHoBEs!MVH5I7n-jsY(XG#MuM1W`!Chfi9An)cA6%I#O6H?TwYIDfFCh zZLJUA;o4d;@4?zyyzw>lLC*b{CHw%%4d5^|N$wIV!S4_&jYsG0&pf%KCNfTpdMcS* zNnd9rZiqTm7+*|w5z`KjFpOLQ=O zN}08!Wfr|oF61@arV@wJg1nl3!kNX|TDN}_g{n1fKu#qt*&CS=Z+MX5O$00xvkZV) zuGI<*t4{rrsb6c`-#kmOaEXFl$TSNn`HQ-x&J8(}Z?EJhh{MW~3V!3M;e^=OuA?ya zv}kW8UiJOz`OSY#nZAK>r1O_dA*l1RQoIq1mUwh$qO5r*?506A$0sN6Tf2e(2+m=d;Qn+T@;Z^7p(&x}DQ)SYxFvpZ_{&<$BQ5h1&PolqGC9 z+dzW-;mu*5o4e@D$1mQ{TN(p1j*jt{`LpsWNIe<2HyQcC(vnhXItk9 zLl=3P7Tb23-$ewnMxuoi#dca28KI=!)i!EWJ`-;otZ$@GS-TOdaW3QzHQJs(S8_!& zqIDjZR=1;BgI%|ANi}+Dsb6x>*0BJ?x{g?@PHQi`+lUodY9^e)Nb~~e&0eVa(_j_? zV2}9UBO<1fD*Q7ZCib^lCg^B6twK)+ne8s0#Suq9?nk}b3Ok}-q%dZ`oL@#^?M&x4 zyG8l|pE+xot!wsDvJVsiZqWJQ=-nQ)(gyDzDb0pUX!i+=tNu4yHL?1M>HnQB zpQZlM4!(<{64>CoD5#k6lZwk6eCbcS!gq8h_%3_E;H&>ZSNN14C_)5gJEJk22`AvMEzTHW98^%wSVpd(9=XxwxeJL1$x({=cuKX;+wK7N{e$m&`ykz0SE3_n(G>M7K zBBdr;6Y!`_st++Kxsy=+t+HE4z+UwJ3Ta{$O!@7;8|1*K3a{kP;HYw;Cfl{ub%{qd zX$&r5$Nyxll`nf#W!3KOFS*kh(OI?)?xMTs3}=f7wCWB+4E93qEqh*;rej!UHo(|A zZ@ejw0cXi>JF+;7Uj~9~MuoqVmh$bMkj$gaRA_npZ&-e3B{%yq==Bf&8A+~phz`0` z2mdkWT;lHgoq{^gd6FAd2>1QEp5UGlnb=UingrSBkzm8pYX+?wws}+99U{qDlJkkG zTvVf(UaAc&GFP5MT+gin%er>{o33O z96@}~hH}~YgTnEhNN4}3)Kq#c;qrr;F89;P^K`hWC@kaasMI$-;y1(jevivkw1lh< zgVWqchhEkxYwD{Wv&+H@xl=PZQ2wl>$Fz;7y2@e{400YEgzAq6Sf(>?J zN+QL-tnMrF;%sz{3ZcTuGBr&jw02j;)54W92)Y(H&4r?1ZF3xIFi?_dy6tw;T-jXu zF3HBsdPh|S50TP*2XcVZQ0`OFy!quOfoPafz5c0pPz)oDL_M@$D$j402qPJf6)PC-2L94XJO4rY5}kY^*kd8{(!jr5vi zCLft@vaj^B!&=_napa&^N2b@09Q4evmTa$)gVv5rzc#ETS3Gjivm?{jD*4fwf}KZr zMVViStx6Wyqu*6LMhc17cGi?nEhpuHVu2R6D=U1 zGZVW#(1{8$4IEDRa>#>FDETq(HnGdZKDs!_|LhKu`tAARjlaR%n@Y^>BMI4XIUf|h z4Sm(R$$5Nxu@s+`vCH_4r>Y4Fr!5V~OXthPt_ll(p|=BWsRAOi%{%xGfx4CVV7AG| z#?-Pp6nJWW4+aqZ3 z(?MXyFBue8>dm(rbV_)Y&VwIf2ba89EidmfhO@VK<2UK6m2-toW^7!SY-Ot?R z2coN1=HNG-qpc;o(sibI%u{3~8Ev73G+82FwA z!J}x8FI_0Sb8W=ljshXs``t?x$i98s({#xBe__;^M_<5o@nhyBVG-Fg8JxV>&O6E3 zmQ`P7^Z5Gmr6wYepN?O%f{5QWZ@WfBzma&GAAdUuc(jV;=9KY<<7EfP#QtgFEVRsb zf?7jo>d`e|0i=`xL*1i+Dd#H@E|sXJE-K@UsO3r&npXV%#t2B691*g(Gr^%(TiN;k zUHE(_JsE9_E_FeaQ=oFV+=DIaWAow-tXK-13luN3-N6-9>ck5ypuID;cj9S;hy7&= z??ETtKg_?4k-j}&yy0L~ppqXC;2&$+VjHVJ9<}>=ZDpYO!{WxY(7}K8nQ~UxZ<~cl4LW;iLKRN?xNt%}sw~Uu)dg z@9@IqqENB7SMm}HhibS+fsMu{jG@wGwC~qDtcg5zk2$7jC^i0)edeFSFA3VCS}eeg z`10tk(vm$_XTZ??wniBG&oDGM7|@liDab@N7|&Z`&5|oYCfutw9BveK!WMVkYrK+E zS8#{;2d&kflrUj~joaTh@^++yKiesjT!L=-ct_Q%;eCJKYy|2pvKZ_b4fzKlX8rPF zwL4hvl<}r!HB6jll!e=Bd-;2fYHQ0q%vq+Ff6hkZ=G>dIsaW@h?z|`UZv6iXb=+)k zEEzl=0AbF4aVKvC+#(Dr-9JTJC*pNsgyX;O;N24dL4729guo2aWe?E@#k4p4tqX)> zW66f{J4FN5^CzlLGSEEG%ZV}zhh9GM-;38w>;}sRjK2=@iHEXJ(n1D~*3>*kHCTk| zQW`_r831s)Qa1avD0{_w{~suO(M_T(7`(Y1rPs8-c@DV^?lFtUs+0|qW@cjbvNufv zi+g7G4X|jusKG_U<&f%hYcl20<{}oH7s;`=a@_19R_q;#U}nSqZ6f@=&(oQ3 zE&i*Q>Lj>V{k1&(-URx+_-XPN9!q;BeG;|ybX(7UPFU__4@e~@qAM|q+)7l(^i<9b zUR@|m{l7vgXZyd{i#@ch1X#`4UhL2IhCX5b)~Uq9=vg2UWYK~SJ5R{adyN#{0*2O9 zs)pnEO`ISHG}bC3%6@1dLImE?C8*1%zjzFd-W7eV+kBk$=xINtt*9IWQ7-sr{Zo3N zo596)3f_0{?_|E2^hl6;st{js&GHbzelF+#l+tte1V!7UW4>?e-O_TX1HrpwMzBa(Go!OISMtsTCvT<9%^X>Kgje(&A*g4+({7lZ1~r@BjhpdycEE)@ZNx3A zgwg>-a3;lpoF0>V2PdZ0uwY_Bgl~+Yj=kJi@aA!mh`q#6hY``_pH&U=4(LE0E$jf_ z+INn0p43N7izjKtT|W|Kvgl}DSV?qUqSsqcz2@Ltf9WTnBC5soz0TQeO2bjxvg0j< zA7$)!=L90+<+g7aw{p8O(3h+uur2nIqKp)oVH`UsCQ+xy}OGJV6 zZZcMsNv%(6?wAK$gn}afS+sdlQ!T#rbxN&2RxmGA4Xj7So%7NXLbEf$g?+|G5S#s# zKDqYd>;TLc^CXjigYPo+PfXd^(f{Wj^HvvVyGvURg*CMM{# zCSkg2L;kAzCHs>zmH0qV#~XW+JY2MD{JSOu-q?yj;m3s~wR{WaBhu|kI&b0UKw7zQ z6Tk7sSWr>B^z=_Aq%QI18!EVA24(q&(%+LF0~4~naUdb_Yg+W)(8{on3F<)m7$7xK zp`X#HLF?>w4X>K}sJ$?RZ3&!OQTIeJ6XAMOs=8skwc$)<`;z;FN`CY+TBk+W+B1x) zarlce^~1^qQy&Z(Ye%+0RYW!-p?6iAWvq7yJ6>LH)1& zJE&jwuLC=pkiFO14@~2LDZaFZ#r7|4v7L5yPC1j5{tAtgYDd@D;}rXl;g7kp7VRxX zwp8Vlp-KvCxJv|l`_s=6FVg3f*nG?m%)VnP7uy3h%Sd`RXyo$FDE`IkCBN(4Qvdad zXCA^u;17@}m6%S;^5P3_R}R*H!*-tVb%2d7)ky<@i}L)p&vexmi}5PZRW|%gC<35I zAd$hG^b7)`vz!%0U6XrghSq@hdmB8B`Lj!NG9`!imWvK@3)xxdANWxqVN~3~j0M}- zNRZ7*FQgw_(~{k&S0EVMRnoovgu~a^WSVXjDlY!@bO_a}8Ey7=WUfn``l@w~>3rCX ztHFw_#x43!FS;^7BcIvri14rDATk3y`#dU`zumj-NsKHuEd~ot2+j;V9;>o-P7UmL zL1gUNM|fP0^%KNjk{^jER>Tq)Q4w7j+f@;BiD>fgABm8B11|axO`OK^X7zo3o!_NpADv5cs;WAQ~#^3Nd zLRQHcdf2NzZz9suX6VKfJ-0e`GHUoI|1u;(YT0y2+4zF(tlnzX3lv$xl(~XUF{Xr$ z6$L8HzKnp`3qxO!&y1X+urW;Ei(SE{O|=F_m*ZAz(zlmdCI9^H?O?(^Hd*;*?JvEX znt&#aOXL$Oo?9w=BrCs;-@Fn}O~yDNQ0w|Pyk2{l5Q(*q{=PbB8sj~ub19ru>~*n9 z$v9bpkda7dhH^ltzibKdeg6N787*xzal}${+80Z#9e>0zIuXji(wklvo$k%eftNGMlXkS(z2Np zO-&4$X)SkERWyO$v~yGjYSb}x-i08G@nRj@XH(|GI*InAaCpa)#QEeH2S6z3OLMg+ zD9qiEFQ?w(y06g~{+4HkDBDNUTCYO&r#j>|{)l30FTgWFW$KSiwVAra3op?&$60WY z+J%}B=x&mRaoVN&EK>3%-|vg`$sQ*b3Byg&sa*fQ1@PGe$;@(9!`^_ZvwNtf+#-Uk zp>~k=0fZ(warWm{NRoR#7dDZe0Y=v;%nK#)dX5>*UMX& zKLY1&(Zjj&xb~4e(!PV2|5tR&#Lho87?f}S{F^|l?V*J?k>4tKxy3)oBj1FnP^nb;Ly?+;p` zp#~lk=f}%A0V+A6(bKsqOj;XB)=N}7AV|idTbIGEs0PSXvpP>FdK8O_DTMfVe5{+uF{}k@J!(>f2{+f1iXWpty zEMBV~L+=gII*FVTkB)jB!Xv6O&66_3Hh~?DHV6{)!xj!gKkQQfr0MjXJN+?&hS9ct zjO}0n&8NG;)4MA?Z%CE+U&6D~e}LzyOAVgC(80bJ9`+lTck6$3iRo)hVlJS0O@^p0 zy>UJftLpCKmsw*dOm#Go29QF3_ecJ#P8m`nxlBcDOQ|L+{hjZF_6L0$#Rep>YitTh zl;=<3x+vRG{=e&HE9V&F?Xe}oMk1mAA)MC14~zB1tz|Dnk{KJX43arE{vu<^ihFcr zW96qwVK;kTJ#51~eyo0CzOS3@>);z5Y*p+K1IGjvyKeT)0;~AE=exqUZzuRpcJTcy zsw0{hP=25YyV-$)Z;0Rv>VN3nNWs?4j=?Lj$*;k=B>QB0H)~fRJMnjX&fB72C;vUp zKYhXYDWxc?uIe;DsHW$oVWLMnB)g`ACqMY#GLb9B%GX%SXvg*B3r>K**?)<^lNbe4 zY?=JeUHm_FsY_}=!B6Ph{sljwSM{)7-l_f5PU$Ld20kx&qx~Z%9y$QdMna!HM7moj zap38=(VEiCS}LCG5G((lN;hutzpO+RTGUOx#pf(>{g)v^?L()MzS^PxU~RIcSriaM zFbgdJAq0PZzmOto0FzV$&Ocn4uc>iyUQIFMs@SaL{IS8>pNf$xGH}aiple(uZK`!x zgmy@#XvP#k69^ichvgp zVKBf;Qq3qA)$I0DVWQ0PaX{%`=ibNjPK?J_HfH2oE?f~bogmtreHtB%(=hrIbe>XO z<-R$c+&@|0hwz=QDevq5&e_oymPDkRO(dT{R{=n~)7AfEE?wc96h9xh^t&ApNpJpj zJ6tH)G33V-KHSNU2tFAs*l}4U7G+Kl*?QSpH4eZ*AKMCsC6lSk#^%-Luk^J)D7U3u z^0=4I9j>EvWI(Y5O|ZAU)!p8;s_qdA#>gU5Xj=0p*&D1wOc2UwTL{mv$%-V^@zX8k zV-ir9*#L{ffBc93?2@aJ$;ryX_?#QSzp<@m2brRs8Cpf~QVnNi+6BxTwvN~FQ?5(& zdD>*+PsroNR*%7!h83?(r2~Qi-fmWGHzEGnqHWr-hF9-|KIw(G0oAHHIrz~iqFU?4 z2KtLi+16o0To8NE)6cTQbYqyHwO&Q(&!$9kM;G9a0XTWJD5+HyZS!Qh>5x{)vD|@y z9NUS82wG5t{5H%<@cO%ptJDe(x5&iqIXFoE?xCHMn^=;%kTV60P~+St`$1^0hX zj^*UYzGS=``+Hb?!}lbfuf%p1Ol6YGAkH9Lb{0P&8^J%&C0u+E+p!c3ddE?ua*zv_mhA6a!0E|f}j%rjL9YfW~S z3~pK%suIqmJRs^45E1KoN}Y_P$v?=?Iai(_bh4 zoW}L7(Y3F-MBk@Ow)iKr9oBDtMm2_-kdBY*`yXaBpI(?B9gRD$uO3#1p7clm1=^Oq zED96=^cVjif%)m+pN^rys8N}m9KT|qlqqAZ4j1fzl{O07utzBpR`2>tronDs^4NMp zywTP&jd5D*nk@xUi33)ulQsNK8Q`|kT-+ZwB_z87+!`87L*CVr=9S0ysrkGAMN&zi z4=Lb|dX*(K3A@rHvWw_B?w^Fc-p8n#LW&%3@tppas= zD$elxeaP{VA_^#?E^*-s;IG*aEl=G^%SD`}yFT7vtCpg+`bDS-%rfr~1 zoIU*yA*V$EY)fmX3GdrH7TE2;lK@(-jW|l2v#&1uam%?5_$FApIK)L86wJM=D*b{H zU;!g;VQN!8>oJ`?=yP{5c2?Th8E+f{w>XFCOzh0{k;xBUxOx7VvjLUP(=B4Ki`e;! zh{|)Ia_m7w{{;^-s2p%#^cY(*`!hh(00ZX;hqGs2+ z#5Yf>W!PuhyLVd^Qo4gxp=clmi;;eBvTsp5MHexx%ia*I(|+hWMPcsYPSUB{_}L=d zcUA#1v8v(0NPRhLMNPOpT%Z6}q{Gdtr}7<6kxt~@+#`vf!aeJJvL3-&ED#koJk4IQ zOzdAr1_i$Gwp-L-^}o5s6b;|o*RWb`{{}q~RTQ9n`Pi}4BM*>3`^2NrYq>cNerf|&{1=;m|kAA1E0CK@t^yK(bdm80J8otqO8KpoyOPr98G6Bix@DJywQm<|18`>)S5z| zs%m_Cmi7Onx>MMd$`V43T?_%Y_WJ8Arek) z^7^}8SKL|LBFal?A&^kMI4mz)!>7MD&I#FpyhXbxjj58n9HQ}hNc(sl^!Y-GwNm|1 zZPAhdphAH#*2w|h#_3IG%-hu(VZ^oVWe1%3Jl9okh?<< z7MEV@9m>me;ww>&DP(dL`vd=B_8h51$@I9fNpF7nJQbauR|?tnX*B_mf4f?t)}|7# zzHhnYl@b6|UuN%i5+v6gF676U zU%OdL(vX%GU6n8?gUB_uK+Re%%b3MNkV60Eo1BoK4fFgMc`D~^XQy9FKcdlVU;8jS=dsQ(K)9adPc)hPZg+-6|+e)e^Trig)D31eA{T zplGqc91?g%TZYF-3@`Zlw*9i5+>NkPzL$I3ZP!)uaW#nroM zJ73OS(Y)Mk1EW6>ZF zsX{p#=n!W|&&+bs)Bkh?p+8V)W;!g-0J*_`lQ69%uGJh{MN`&f!-zN=QWX26;n=#w zvUkNK4c7{35KRnOflAxVcir-({N~A-4Qgf!ZMx19wZx5B?I-)Y75+j&Q|wRwVnC=>g4bVIkfzW(JDi^z+f zabgj-xrm1ABKqi$smJ#e0YkLbea|ByH`3v@iM%v#Wio?iwlVLZI zz&dP`-f}{UyC1RsB=S!~!|)zsi+b zE~4hutV12NelI1MBeKYGdU4X50@;uOHJUrKyHhz3q0FI+j?9+x-n%?AJHN6ue%zMi z1l+^fIAiRopJM;5$5f2z1sWFEx{n3Oq!T+kRaBQ$rbUb54O>~hn*S@0x8gN2r%hJ6yC<_t-^m(*VkocmXBw=;$rKK8a6g*B-`Xq zz*jWs{fd7)xvd$ngXFSdhhb}c2Ya0>glP!Yi@)0~j)D8DQB}13&Nue9mPcCp1tvhX zvQxHd8eKs z;NCpzhU~$ydY~~pp4{aZa!g*FYP7z$jxKLG4lLhI{-`z-1a+8&4aa3P)6`#33DPmUV zh>H|~J4x(k77nc+e@P%rqKBoht~!Y;`}*K#j5);t{o^~zl%bI~FT1@HV5dZnlITZ- z|NG-5z@BG9n7tN~gedQ#&mHIRO;^&CQYInQP?4L_R`kwcb_mJaK0$Oc^7=&rlehMFwwg5uae>BmQhkMG$>zQ%SRAP@;OgTN0G@z@)TeK~;N%ZAh207F* zV~IEPRyp27<rIrm5`@|Q# z&DSVzS+go?Y>PLnRl%vtr=u*da<7wleN1`0`-YN7i_^DSru(WS4Eb(ww?_SxgaVX} zBpfT>j3!Ywi({dOuA<=Df9f+n_X?8)8kJdJ;1GdNbp$8c6AD^nl>8mrF-%z!1m5*l zPb)d~rM%wt2Cp}DdeWOQnUbsGsXg0E#^qJp(9IZOLfFq>}klCONfftmN3ZWWIJsm`23p>Z)ti^Z=Q7!`ZgeQ80{CGRWs6ed}46`%e=!Vr$W=KppmIzp= z{wZ-3%5X#ZWGf8Od*Q1#U*(v%^QrHRcrYnn&x=jU&1KlJ0Zz?%0GwB|4=Jw>Q>Hso zPP8?pU~(3l7pAy8k|Os;d+n96Q*IfVH+3_wC+O#Z!iJyMYo zR5`AbSs|z%4M}Qx2MmE$9f1MUk>e2q;8+8|9GzV!4LcaHX4g}5_&o-Dim&M z^vGLoZ+q|th8`_b@Iibu`5Q_YyM~jO5dwi8QEpO+%h!pAkBau`V_BuV{q@mce(*}V zf9(hA+LvOdE;=|^A9hNw@iVwAwW{9rw8e}>JFFcoBWU~hPid!8ny#`4pt=?($Z!b+ zc$nPE;K=yNNl5=9cX0c6V1vxW*7Oc|yp@-LOUlF-RqEQ@2-&Q@MR$)a7!~xs3_Z+s zJpe?9p(6@Xz4(*!>r zZxzURZ88ajmDi@1=_NDtHD;s}b)9C*MkH22k7UN21GxW1CDt;T8u8l1+){s(d=BoV zzT~c|0_?PMdXsQfhDox@EG?nJF6gn#@6~~3cO%VswG%1&L#&5YxflIdTKjS&Hbqbj zi@C>=nMVb@|JosNZ>3Y~Ph7pf)hJ>Xa(+Xe{~TLhoBS_#B8~Qob;al28c#dfX9ed( z>67aQXg*`x>gH)%UCoi2(&#(Bl&uo;S8w4}7W#u!7%2j7cdU1le zw&`QJZIn$fmAK-0BXgq=nVBcjC)0>tAtsMT`%_PIJDny{W(T{}b+C)&;ohG$R?faE zCq2*DI}5;+eF-v7XlQHrk+#tbJjT8#Y=5Cs|pol;Hn+oU64gndx06 z!w1!mcqU}EXB?|xAf~hS#p%VBkQw@nSda7XUlgNlhj@8rqAk-0X24e}B-2)B&xZ?w z{+~qB)DKertjRaF2@HrRIZXOhKAr>{>r%gueY z)=dW2`s3s|a7l2x`7^UjC^F~&)&3C%*P84zHY!oZPd{=UVIm~4!+2ErsFQ=h?1`4n zulLtrg#_|(7+wocn{@V6hpo|w>7CXICjBftL!J2-O-JLw?p`_f5_i(%J|S68ldQ%ton+>%vc zSf1P-1Gnxkv^CkLC-2(H_En?GrM$^xf<3HQ#4GimJ~Ura-5`(eSf?zh#Jghe+T%cg z^6HOQ?Ml*LYn^r}>5m4_bz99mlstpt%BLKB3@cD%X7DvJyIdo0W|@Iv8&&G%k&s@U zyTgBE2gJt;8z4Ib6+?*cjG12}2vF{wRqGx*SWC)%6ZLzswx?yxjL(0ZM5r1|2&9uP z_!FOSWmR2b)Gbgn-ncIT{+^@7nX&z$M$&@?WXJy&4x^(~B`3V5<0}TVB;)tKn#}LF zof4%F`+7g6?YDRjq}4-KeC3<*s~%$@NUzB;Y8I?9f;zI(`Tb)?;aE1JygD;BA3a0x z@KqJ&{dCr^RgqUTngWwvVyGUK&&E^#0t{$UE$X0w_kK&9cBm*s_vl?tRH1*|R&|)7 zV#^xKw}m-yYyR^JMW5Mh{~Eg?mELvDX?lVq6MY^=2q zY=GLNyS}iJdh1a^tJohnabH@+go*y7;Viw65V20DieEpD`dMtAMo?SPbbd*|;epBYi5P`! zt>whRj)qb6t0Ab_lgt`mM+Abontg;+9k;gz$$W=!Ev^wmUWPAMPzF&iu5#+3wlQK8 zzEhBUL8q#JN_}i49JF66`ll$;mlJEk%oA1v{SBo;<=Xh%eT-L%Qu^i`Ws0>7UUPef z?5)UK|Cy6<%OA{JQ!;HwYvD)spLXipHA3S+LwTJ+*6tZ)vgOam=UZ>m zpluy4hbXchSrJN5ud2#m+Mmls?d)TCJIj?*T4EU<0{oLF)JIBI?n(!D{k3w<<%cF| ztXgS`Qo86yV#%~anCW(*MZD=mLUxm82AQH`_uJR-o}7SG2v!}OsP#X)Rj{E03+vAK zUUZyF^-6|V;r({B%sQ76s)?3kB@2r6L#B40AeghlFFDo?s3eKyD|I`-NwxG+?i{+4)w_b|%O*ZRJE8`Ka)Uv>u?(WIeiJb27YPB0&t@sO*)#w){a zrhO(&x>5_`rA#mWrX!*BwOUk5Z{k8LzZlKYAI%Tneovk_vVSv3pKJWj?YY7Kh^N25 z(%={2N3=_H+dTiG!=+tbTL_@<(%YFcbc_$$uZ8n@C;wiDU)c6AHNd_?9@w{@3+)m^ zZ_w~=7Qeu-_&V2j=KkdmrjFdLHb1M-dWsIuSIw%$WYuQ!Ux94AuH>C!v2`kgV8}Jv+{l zE%{RwMnVKkfe;i~mW8`PNU0XgMsct!h!(ViNMb>5JRTj_pd zoU&Rb!dGbGab%TZ`?pi+v*QdK)9;O7!|=NMX+%IJ(u3FM9Qx-jiX=1B$7hNl8Jt40 z+g-9r-I7^;k~v~t&mBm+B?cB(6FLbqhIgG&2bvI>{%=x)g@KczX= zNS_Q>EP^Zi%Uzpq`)8#3-BkS@KQ?5%wjmNxqKFI;P5vWHBKrG2 z94metTbDTHNknSA@h7lqT_Wi|4&)=1_^o}+-NjgCBTq_2CUy&@S`(K%B9jg}35!@V)Nz%l z+%ndP>lx!pHWpKMW$bMpv(Go~OM1OY6HIWhc;H_1L-u*QU1R1vQIUI)ULu8bp7iJR zGup(RIjt@Ab&vR*cL5}|wLtPwjMvtjo0HnQZOte4X|5B1*CPb)7AW8nN{zOwvl)Mc zl3GMz>_S236`jGO<08~}=HJwsw98OAK2>v#yxH%GQe&aixRw6=!_={yAp&F1(=`t> zw7v2K7|F!y(7tlpG+-DxlJODu!*vMC%4cdnw(BU<#WXB7P#PM>K`Z7ZUnUz z?cpMjBUIVMRC|K}>9}d-_tu&ajt+?G636~U^l#W76^5}e-`~nkZMD0wi94zkC)6Xn ziuw!8x%nIy7GK(&-6}n!ytmu+sWiNOG=!(U^#?`PiuMCs|L23P9~ERH z{m44lNEh*gu!NW^;oj(>Z9h^8eMyK=Lu-yz0=reWVW}fz6?&5tK(%Lxf5>R7>#{E* zb=jt|)6hKCekV)36D--rTO-M~S51eIj8x_6W~*d^1jI#S_&LoLd}7pR+k`>gp%lgV zHv|qYLyGrhm7&zX>lmw`cQ-iJG8$1qS#pA_A>To=XH?>1D`5O_3Hyc#H@FdOhif7r z7b@Z9By=qciu|)ndBws=%3ex&vMaJQEV5CpYpUjFh6DHD=mz>dmF3n$BPdQsy>zl%;(w%N ztwxq~c|Yvz5;X6`5sxyDZ{t*a4n!|bW}c|~?X?KESK{;MX`HWI6Q4gpFKGr}=k20) zwKa2qZeiYXT4iVP)+J{6bjX^bRN|}U)@$D)#_n2bc!4*sWN2>&3mxw&pvE<t+v2PFR=x#k#5^<3J_tJD+)a4d7RP8o%mJdVeZ$J1O(xH$#fg8KlK3<7D!| zo|c_U0?TIG*XUj=whyTG>iyrewZ@+0Q-9LKs_ey!{Xt1OOiV~6sRgLmRYvZy_Z#P5 z78XN$`S&bR84%H3%#LE8DY|cGbFMU}#_+g4f8Wn# zWs^q&lujbKgHs$rrs%KQ$JriMDgd%Jzj%wyh7@(?c>V^Lyy}HStIHaRfmiZU5 zbtvh%E{Yd+(IHk7J@}G)gB74s1A>`cY$x9Iry9x(DZ;eD242yA z6y}xOy>xUQlix+n*=H465?5%yYZUq#j;z`35knkxRKO$s?Ao_k*El48+^d}Xe+yE{ z&who7D-T3m7x^|=UA~hGIaFIl!A7-v|Lhn%Ip}GpGJpo{>GJxO6hef`qFs2z7f8iI zg?N_fQVm426$>`>c~c7*H2S2z&5t);M-p#F@d$5t>8Q#r@rDH7=^3TWy2=K%rM_kN z&JPG7x=&R@TkTHXjQ-V?tu@W-P%GY)BL$r@Qbj5@qcpY1c8R5 z70Q*&-mVU>f|exRB&NcUe?pbMV2a#tt@PaQS<>w*m@#zz1xJ9gWPPiX%B{1vt%~2& zntjkpnkfknwq#3FPI|f|K;>#?udZeg0t_M%^vOLX{5SlZyo1`@!B&~r!w&^WsSa2` zn;6DQX&QoFShdn$v<0TRm!8&1d+$15m;rC0mP~>kjGYiA_FhcASIF{;*4R7CC-MfA z4+YnVte92FI_uihY$l0ZRDqRc-kIh2OwiwlL2?}d#W8#%%6HusF90is{GxDK?nzQs z2}HM0>VL8s5GR4KD2QG7|3P)ePV0*ShK|Q_u&yRf^1wf(^2CbBL9@kR0r$JWF$2Dj zB`bID7QZSbzwvx5v*tCPO5|%SsNHjwoqUEcbTNTQo-_8r5LYhk;UT5s;`nO?F)ZbRWYI8(e~-g!^sJU)!FAm z<)*`Wi9!1OVd5ti`nW9@_&>uCMx8_EL=-xkZa0h~0s_M`^W8lgT$X^4UiSLnrLSD^ z<{rb7o3nTx@04uWdW3D|Ko4m;+6o(Uccd^|6#cOZn-Dwq{(z}3a0&1KT_oZ5G{N7& zY7Gv7PBU607}tTXazP~Jwo3V4k_Znk3~PCFQi+RQvFWHG2#J;FKN2K1G%4jjbTDxy zcK^+hVzticvsK)RU7})@@^J^iLsv&qLf$-oLXgr;5J-77DgDe5tOzc3_qymD{J)_c z)6*{MA({r;OT3a(?Q@ac8AH$8TWS@<_0KtB&1E$QWPyNPcY~g+h-9wRSb-8bo(_s8 zHhahjZ;lpAn&u3(vwBm zcU-bHQG1|KHcc{`(if>+E~Y2#(%}Z?oNj4<7F4dzX({KsQjd$yrK~}R29-~@Wap90 zpA573XCzps`dT_$Yb)}kEqe+Bf&bT`{NySAaN?7OS!VI)`1cUe1-RV+&hKN%VzE3J zjpK-ceLN#hyzv%F_Aez9?Ed+T2<~8}JpU#L<-e*}Wysbj@i8v(_R+-fP@aE@603f@ zLrYBdie_hCtm)$i!j3Tj?rZH2LZ=2G4sm2bv`1wqPd!<2`*ly^pZirG(J6K~R*H9<WOut{k3{>nL3{$qOf#5As`niem9RoC zem9Jo1Q-~k+C{0Jbg8!MmTH@zN^}>J4WUYZIBETZe&X7?TJ7`d#zJcuw|)+x0Fkfk4FggTj03@eg8c7EfdH$=S2qg*@tBXu%prZa0j#!sn7Rh6beY@q6N+|@t z;)?d7T7ZEtJ4lwaWcQKGe+&}%cMMUL@>D_P_KGg}8Y4z!Y$A{Nf~y6F*PER@I*9bT z4f=!xwUEH%0hk{T=ACRXXBRDE%QoZPFJ@$*DUB~(ejl&QMW*hQ%p}fSzJK1ZWjYVe z%nDU?ZM#qPlPw<y?iODFug>nR8_>j>;yJBUcA0?+jD6sK-4ArTs^MI8;rt2V#rxOFlyX&0~_*q5qn{ z;C|{CoqZNFu_dPNz-MpWtaG#B&U6dMTnveQKm?-*70!#j&by9le}peD_C8;&7RD#$ zX|HId3h_#w(t`tRe+GXS=f`g3(>$CUZOAV(THrxxS?27)E!;idzHt z;0o(meRLhSj_v;`neu91(cHy3M`~@d^@=5`n?I^OP{qQN$ie$0Ti2FskWzZa{dPFan< zq}^W8&9`G5gic@cm0povpW5116T5En)?C5n4TILeXccr-p_K~L9ikJaWL-t{M$R+c%Y zEmyAg+t?tv5p0dsiOB@_MTJ*%S>w~Q2T2>If|B#Cv~@MD%ovwgN&QZ=px0|3qJq&u z1-U<{ili{;7NFD5m|;=FSJEJ8kMUDX1e^S#EL2<;p<*X|+WD!a!X*}5{Rl3R%|DOQ z%ms#%`@PsBZ88FzO=6flFpKUWzzlS7^sT&e#Dw|u1~bx3tZ0YGQpmm(=AXES%;~dy z;F;dm!BwiV&@+cpuSqimb`Qv<)4R_+O<%5kmj$EkAyIR7#PEe-b9I(FrYbk_N_E+Dwu?@l(%e>{E?oe5pSHqAK8Xv0SOJ8Q1vsON{ zcpA^GcTEqYI}%!D0wif@^M`%_0(*5Ju%rE%hH|@)%l6kiuYOYh(GV%X>3hm6^vncL zn59235iryCd5Hd)iM6Tr1zf+iFNSH|Nn}BSkL597#o7;D=ZH6+u7dHtsv?|~&b=CX z;)BOt?#$3_XcL_M_}6L^8%}!n&m5ayxpvCmGlP3zAA8WQ;?R*hT%JMgNU)Z7ddgov zDd5sIeKB#2L{Ms&O_{bL~-Htk=JjTKwpfDJaZT<)>qtNgnvgYU6BE znET=zI7Pjod>jD6-U0gRpAuH_Em#p*3ZRqRrCcyeF>95A9#7NX5tLJZnWL9~21S9t z&P6R(%lxZxs-*I7bCDs^7NT}5RnHmzK7`*P(vw{$fZ3@~3+E89&^0pPYGC0`l7e!~ zlO2o={%c_D0%Ov$c2kmDcaJi4<@%aK<4frxi(fS+osyqk0~zmkWaPHJnzfqjTM@KK zm8V#`mnbTuIXc-05zrnUcG(Vo{T}~)HK9M^nQ?;Bb&bbh?=dqYcqw&~VFR{|Ot%bM z>yI4JqPt)l=TR9Ks?=P<=@r(SY4>^71$Fap&EP?8YW`!28io)ViH-KpIx8OQDzZ75 z?$ZLuLttxz)=4l%V^fB2(s@X*m?5?cRJl8pPfb-TUA|%UTk8mz)(cB1^Jz5kTvou$tE=Oeg6!X3A*mS|#w&oF)tEap^GE-2Q-m+;#{Qi{M%Iz+#GIXn) zZ=t!&CQMkvYWyFu^8cOw`)dVGr!(RN{t)N4Pa)-MbQO(eLAl9wRFFUf*Op)fpLY@h z>oh7PQz>{H2QkVseF`%tpclalHG*RCo64xO3J>s}5VQlfW(x8%Rc#50z^Ol;`&$!c zFvnPd>_#f_O7s)ljRjW2U63LZyR$XI`=!MC{Yu39M{_4eb|({h@K0p-S6v}BhTek{ z=yH&%{pcBExz6crn%*fv=lK8k@<4vK0hQ~KXPVVE!YQf5*2Saq@@M;A?CdScyq>YM z_-$*hjJ-wh>~)>M3L8jY_Mh8=*SpqGYr5Kj+dG_N#h}A=mJjf?iIgwD)Y?JVXT!d! zClz;`#~Giq+40j@i5Ofa_<=LVtB;OLW49hwEE>v|mzUeVZAE(=UNUnv-ZBV|fY%^P zfxm)pt^Tswljc7_ebKzeL3oJwX7r6&^`dHvod(8Wgd zS@@L^19?sbWq$J4t~eW+ksIdPXN%b$Y_fK<8o}tn^EZB$J#zx zu>etBS?n>U0Vk1UV^{iX--7GdpwLMJrsahs?w#8%y*j;q(7Mf^rC&we|5PA}vAW=| zSuO3fg-q1}Bhr%7Gwe_r-g?wbOSY=_XiVK(?JK1jt7#u*>pvP;8sfCc#Ikc@ie^|E3+){Z_vTBKEcJr~Po<$D8Aeliq2ia(lXjx61(g(`5Q<0ne1=5Ur}Ue8{%5 z6^!_062`|DI}Pha4MZ?UnaB$DLWacV{C>ccVl`Of_+m=hJ@r)^Uf7w_^C?p0oEDVx zmXWnMIhS)UR8!{2d^Tm-Mz^`_vVS`$OAp|O4F)3q_@`{(-LVPispAs3{1x)=!$~^H zmfSuAUTb-$N6S||GjFV5aZtHcAIWk(sGE8{nsGD7Vsc7@Yv%OFSa<-hP5N_zy_|2KGh z#OE(EYIlcu6xbHrnW2LW%={MsfBLBO8eOKoDZQ>b(|eaOnNdB)RJP1Mwwi0!2dt?c zuyPRL1%y}i5JCogtuny2%IMAiC_KIT?3&D+P{2Cf>}{$CG$#je*Zi|;GW7+Gq_o_! zKv;$Ce)-d|-Cg?6Na=>Dr|Kksrc3@zm-4A0UsHmH2N|WMLf)x>%BlV1^S`o?8O7|~ zo_hlCI^Qzh*aFuRGG`9Y(6OK~$p@rAoc|e+fArXDZ@4x*G~BN;(py;Y-$&G}W`(JV z3dUfs+X-IAY@JGzWQ@1%m~`)EatwGN2r$^{jhd@$bLhhv1cU8~+dy3iIxYo3v$o0yD0y0L5uGc@r? z>Z3X=WT`qKHO;6wtqE(#dlHu8su4AlwI6=0?4si(q%@Qijsm3$DfS0!FQt#9?X1Sx zIWPyQLt0j&n@-LaA`(&1j%A3@g1QV|&c=!s;%on~LX1}h!_^{r2XsM(W&=?f&LM*t zNiaQi)a-aWTP?FMS^Sw_nQ{idBD)%!FD>bobbwiinJ`i^t>+~QhV=777bD@vm-MV~ z_Csf`ma(&%AxheBS%a4Myjygu98>UKM32XlAog8v2e2+QA4G^wh9}g2sv2 zUr|U08W0BlA8{)8Z{uefJcG6RZT|y4cvh#^`OhibYM;Uz8xnrW!(XMJv-Pw1pWn9m zr|Ru$-p~}DUmDRNcNN&LZl^)4=LQC`n}Ds8c7>5N=HVR=OWIUn4NUgo z-r~LE;XTcP-VyH=MtILDU&%~;ogoCef5n*vx%d3kE7~~NxxVsabV3t!-+WZACgY<2k=HT$oM0tP}0@}VqU;0jbYxPdm`V{?9!eT$$k{jwn5ti*V zK2AHeGrxlUvUE{x(`cMN*MT8B+)HC`I<{y{GA|9x(5uk@V7+|*CTVz(mr5ovjaZSb zzrXl%*z{%pZ!huq4fS@aFFq%*zrrt*U=_w=eqs|dfpR_}w)H9@L|tM+?Bn3Q*#E?MW0BqjM16vYa(+^^X7 z=db)GAOGCUdP2X~{u-ZiAfgQ#4iP>pgikIHVM`R~$e2f_^F zN9L2bj4`@K*!GGJFd*_f0db6g5avPpo2-V=qc2d=UeQDzNCBWRQvqWXx8I=uO&ykO zc^B-?ECstmnUeiTwbyQwOb;&2dD?9DgHK_%dLgv}qz(~Mccw6Z2g2M;5|1fi zyz!5sPiyS1poC>ACPB?0DeXM>rh zdh9$P_DsbZ5EiCAu4cn&PeyIn);m(07cppdB*H5Hfs1%Dx;kx(fJH9ij&2d3_b_lX-6CFh5jEW+RuIwTfAk{k z^av_bAY;4m)A>@oJNdt&^b8al838}DgOhprR4*08lq)8=Y|sm*j{eE^ydla7EzEo7 z`oohMGD;E^`-LcA^=y@>tPqQ3AtYY|2fd`P*ZCq#nF`VqMsfO&G_$ftr6IZFX^s6B z@r_NT4FA~4K}IG_dCOw_JSxYJjE}`UQ=3c6h41kObR{eI zTP|MW6+oY zKu>Anr0lPhpDAU3ev1aJAD99wmsUDM(`^w()gCo}R-UolnNLL``YPgF7g01N5&=iBzt%-;*Dc}@7x9lvy5`u; zMcneMNQAAO>-brqdi#P%#I~yA1J?eC*yglIg!saL!9`@pb&Yt~MLgFnVzG<3w_AkP z7pddwZV?x{h}v!u$GeDICr2tblnf!F$v+1-@$4*S2N7*2s(;XbwmARQ9L>d6fykwPYCzG>%R* z-NA-fx-P?4$&8a!lnyGm7)ebUd>yS;O0d8P`=J1&vo8RAaltCRE!q zhYhjPv;nrgw9})d&3DR%vTAqx2!VxOr2RE>57x&3HpaA{vb(o=j8D`_yQ!@^#2YUL zyyO$VI`3DLr(AsgFOroNwI%h_3n!g7$QjeB2O7~vFf=@4HoSa4@u?f%ruDa|1 zM2E8vV089ZVDeD@VgsEb)3IJF*d)@9-|RBYygNSc5F%)mBi(O}O9Rr?>!Ta#YGAj_ z&|PGH)Tv2Zvrni%jt7|(;a=-8FOQ6JZ##SX$5JkLN;QwjOUIsQV957^?ot1gdJBt| zYyB(Hsr-@r=wp^XhVawmzq6YD$6WRM`k$@W9VTw+X3s`IZs{4ns!6S4h4rvy5;k>- z=ToC`2I-qxoxgpoLeON2YM&g@>9Di9#2=KX_H~ZUqm0^7#tY}ySDrnowy5s19+PT& zEz>y0NvY{@_ELFoCql&W`bM8AY}wc&wYo=co>>v3OhV-x$N6t5(D4d<)K^|~@kQs= zF2y}=yeP}*UbX##m;-U-GZ7wUAM7Pg4AJa!P)#(G&S;PcQb&3Y2-tz==wx1sb;QdR0s-7L~8I zEP+@Yj~SxqPj1@nk60{@WCT@{$D0lEP~{JN5M>Iq%pTUilzWpXY_5pR6e1Tp7p#m>3S%`*L0S(TSb%asC%R_nYig3W6(HQKA&WRM;Q z)TeUN^7hRv-JD8%Ykg(g>h!?P*(ne_nf|sq{nn`T zs_L}wzw=%`Mzc-H^ycg-#8pGt`zVa;62)fpTMRXVK7Mg+1Li6rJr zCA-V~fBjr2)qWuuu0n!%NVP2}1x?1XJ&!6vJFoE9WZ#Ag)|1UnTJ5PmB$0u`lEL)s zUH~{My|p^Mc~rVp!0%_kZ>dhdn0+6ysp_YTckZ+nAoQzY45@T#))Li`i4D3u1Re3L z9Dt6%ucmor{$K;$R+S8N#BgWITb~a4R{c{ONVd`+qSgCLk?sCLdMo3N9ZpXpm##(p zV&j~P_hOTO{7NE+b`i*(<|oq-ydRaxcEC!GegGV8qoAB;g~nSyadJN7k&NLJ^+SnL zoUZ79&S_1#2cr6w&S&`_%lr7$?o2l&p5H@q*N$;2+aVIPadfO4rNv;|Mp9jQ0P z{u$h0E((@KbV7ZL3t`M)Cx|ZJEbVaU(g=0uSKBy#HJ9@8XLzi#k6H# zQ;);NTFKj3k>@_TOyVegeWI_&{R5imCbgupfmQW7z?_>$r~VS3^Q>^*%|B)=<6W>P zy}Bj0*Svz=lWnV#Z7W#;WS#!o!dcs5#hO(xDr*quu?o;1q z^{@bv?sz$L^iIlW$Sz<--Gl`4vy*#FM1PQcnABO`fZWg-C&_J1^^$fCfw_XF^v5l9 zSpT->#^#x}F6Tr~uynv&Dt7M!YK{>MR+ohY($PnE8gvc^i`|8H#S>>rM9ObQ{Nm|{L@rFiTEuqp3G&k#^of_jUR9ke*&vkln zxBM()rh!6R7~Z9*z7|-}(saXHE^!^945dj^LEKi=m;*i4mwH0E%A$BN@ok3o? zVb+Nw;*S&@$u8@uCmxq6s5{mxSf$gL-)0rI<_%*5(*Rh?wV9Ux%wz{GN?`Yrh3L}U z?ZO1?k3-1_?FQNE{}pe=CjTnVfXZ^dMmu+Qga081e_3=4)9g&Q$Iu06NR4^~Dv0*~ zK7)(<%yVV0pGq4}p$|?yuiCYtRc#pMCgz+Cv1|O15vP2s1V`Y?KqGs?|GrAaDo1Ea+Cd3oQW*Wo>bLZ4onT>DOP@7KWpuA??@sIF{@&y^4ojj#wf zp9-xyXpfGx>4oBjOy4>v`ewD)=gl$rRlPe3FYT6hd&VC*bI;=QQ(yP2S({31p03fU z?=h_f>i#%Z^nDrEC%5p^Grr^S;@myLo7CIq&)<&<3(CdPh5lQ4ZlMos&vz|>r6ov8SJj^ZHQ8NQj%4~F}qvDVBIqQ7f)6P2o$aLScs&Oo1ggF1) z>Odfl;h3_KUX$=S(z~`?kMy{d;^>)zQa~Cy+=~;t2{G6*1OWL)99*CQ3BH zfIE1C@gC4>TCEQ%T7(25A|{+fI3ABiYg=#ip|x7A)@o}J)Y=5BfK=pC6}2jAtNReE zc&UI|^L>A2?Q^n|pih6lKfbRouNOIcuf5i+nOQTlX3e_&t*YzoVdKZVJwE>T@nber zb!{Fpe$1=mI-s-wwsd&qSn%R%<7)$_V9C=iL=NdA)}j~7p_DgSFE*38?f z$wPlNDRJlrwee?b%l|TS7Z9KEXzFafKvd2-yhdV`yir5W(X-cC&(wRlqEsLyK3pO3_DbDzgvQd9myBsSkZkNxwc#MrND%fFgA zvo`)W%l7>M3fX{iipvHRW&3>QZeqmz3uw$#37?EDd+`9eIg>R4ZGUa9zow& zD?S{XG5jT{9=R8c7&&=7_YoZoh}!r+yBA8j%9y<(sAX;totMTRXgb}F{*?GN@`zkk0aN3I8s1{pMo0!^B?47le9WmBEPxaHk)KDT30Wsx&SOF=y*`=OChbHw56TyM$rW#R4dL$E=DxerEA81Rm&0 zJFnee(T7TKU3dex>57QJIJG__ty;b?T70x>0dculZdFKi5l7~9a!r8^2;9cH{6+|w17smj{NBAyvXA-3OQ?di#K=%XPL3`e1S+yi~|D1 zGjz`L=K(UYUg z#XQ+aVnBc06%&v&{Y5=qKRB!&+FFvqDKRCFGdpJNE{-p<59mee9meCv=fuPkc@2n2 zy7xHm4Mb#)L}a@+cn%|ONrgpK6!d=Q(>|iX>3|ZAl8k7SPz9nv{b7yzZ$;zY&w528 zP@Pn#Q2no4`i%SkKhx3+_v&rwG%=qrS!YV;F~gPVW^2;-_O$<<X_nT)!T>newM5N8VW*|9cJo2DWwDz6BW6 ze>Gz8ump-KO%=q2f=D>6VPYcZ9R>gHC&3@VF-=|~r?`!^74_5QFSKh}rG!ZsdGUg0 zEA#OA6!Q!VOswKNE_bbR$LotSMuMyyG4q;@Hf*{xR?+h#11ux1dsI|$G>(^!2PUjE zaR0l@!m=x%4N(lMLEXe|K{wGZJ*^Uwe{dO}6LKpm3;2O;US(~ft`fhiab~RIX60xa zAC1=)*2KpZ)Wj<*3I2JKPjOX-7U2&(!Z?R_yBYY2|euG4u5`$>uT@-@>zs`K<#<7Ys4Z?^JB_5R2r8LprOU&UEfEaq}mHvSNkbMQ@$1WR85;1us zi5P`-{V&$={XqA<-umJ|1mEUEjYeN9Q=74O)Ka9+L=9H*Mahel9A}TIYa#y;OW&3j z($r*`$u=-rB5_hUb0xpTt1dT&EyHQ4;Zgz8^bha)@CQoBhM7}GtF()GDA?JIb|E5| z<=5^?l|g-O;Dg`LWY#3qd7PKD42OcWHz2FaqzXSnRm{6iF5x1p?i5c(s)grR#S52-#yXCd@^}YF)(?NVoA_vpJ--=a z_2Mlmg>_lPuWU)3O=Yon#)Bs_n6K}C5HEQ%7Un$AtkRjZ?X#e^s*NS-=N3kj7cxbB zSwXFq>OUbE$(e<k5 zCcTLw&f8Z@?cW215AA8I{~o_aR5aex{ba1-rAtNlo;94SMXmVGQ^W+bDcyI~f>llY zKR{sa0U*Dja7}U!JlyEt?EsQ`t35Fx@nPzJgbi4q6RWt!0PkJ1V!Q#XjbG~N@Gezi zN4D1{zlX7OlQM!m$-$;ge1Dul6xwBJ*jw%T&6@HlUZg#nT4EI=t%7{mQ56|B&P#Qp z=(Wiy7>_S)rsppd-~OCK*x$kfkf9{CoP7Tm*QdlP{&a~LGrS+yQ|(qunBPAEbei9B zt44@lYfoGK+4?FWg5N2R!m)}A4Kkd`u)H$Oa=WCuKi7`}1YEBa*Gn8&Di~!?#`TXd zMgiA{q+w^c&Xr>U*Pm0ieq7(U%3zm?>wo3h3Cl8j0`}I_PbdV}%OdRwo?;dEO%+?x zTrW#C8PF+oKD}IzIiQvP9D`$AuO*)@^E)tO$1>vu*BL7C#twlmFkTwbVXvRE9TAbo zPcFC^6+Y%-76y8FzZRd+A54Cu=CE-3^{2#N{XW|Q9uKmz;X&4P3GyZ{x<2*ykEPD; zP$KyE#!5Pe>2j4wTd7>S^UYsDGQp+P`wU8XU7}nSJj)`;yrxZWa9kPnhD~n`7^v1o zz|-le*qhWv)ax%|4n$5*#-az-ocIK>*rV>GTllC5vF=eQy?n#mZpDNs9`c!8>?jj) zx%&g{bzK{ccloh(*_;-(QHvCsd8D^_`Qp$r2!asI2QWGC-_g+C4Hn7VyMG$YwIp)~ zuRj!?&~N##tpAEiJ5|$e)Fg@ADfs;g$E2F|sh^pn;`<-i`!@gG;Qfu@`%Ct|$zNmd zo&K}@s^@(=_+4!2oBW6Q75w|`z0gKCtoa~}@BQ;)FG}2eViHjlA~8YW)xI!-W6V0S^9NW5ToB-dSM!GM)M|};xz5D=Hmj6H05JJ_z7l?~@#NX3^hbkz{uek*wMVPy} zG^?q|OVDDHePfB_=oea>3Ikj))}PPph0_iT3RTfCE4x?uSF192_pEB{gMZ|@KWZ4z zXFmuTdgoZY^43lWV6~<4QT0^e;Qt!dGdY;YhdMs^3k(wtKVfT!JazIthcj9#^7$>% z?~2MYd+kaM*2dT+Cs$R@yyn`ybG`UW-qyD?O|_2L>*gWeCChY}iuRvj!%9_cGn=il zX6{CC^bZY~&d7q_Ay{M9lbStqFH-ZrPwK3E{H;jaY{^`lom}S3b-l&1Zvtc}@vhuG9h6BS*CGVR}!qP z^L0gfzz){b8lNh~r+^U(j$nn#RGe+^jNupJYx=iHD3ZB*+#UF|@^^%4o;kIiU5l}?ed zQyy?zaf^_QbZAZytuQ2wN#Pv=R*Rcy^Cl+H) z`b;8p)Gl6fRzczf-Pe1GNt-5(oRsD4VoG34%sSi2QDq`en>D|!tdJ|Q$~8cm26ZY8 zMrwm-TlhY*7t5NjcCMuiH5nQ&)5R6Qs>@rzvf6pkh)$rW?iHN1Y{M~(d z9`@^2&{)N4mvAo$#ELw8`Z}tsi&gwyADXTKsX9SDH&(I8Qod8OqOy|Q4E2L3Ob{dC zy-w-9T^yl{O5Djy=;(MX^c&nmfq#yBsPiZB(7h&BG2TG$1O|28Kh>VkqxIniouNbM zql6c^r;QRd3x^OX>hy zbvG;ESJ{Uxx=ZZWvS!KpN*2!XTBGpDO8)`A6C2dRxf%K%-_E1|V=MJS>UfgGF)`_s zSjE-niEYQiT)Md{>}8lDJ9Mfx$WFbk{BYUk??nw9IvH50XRPk4JinZ`?q#uxQY*a^ zrM>PyC=BH9uP^uaiZXYg8{ASkaYaE8ly*|H3Wpn=_g?tQ-+6Upti8NUaTse=Yw>DMv+4=csv@jPO1 zbST6My&tVl$=O9-e4FK9SfjztC@b-%i@yxBmzVvW?H4pZQWI7ys?AxkXC44->{c?j z=Gn9-A6X%Tv-e%%HfD1N{?%j|gFgH1#EMEUc@+kNeZCk451e!k)e)N1l@NVwZp>hn zOw1_q%0Fowt~u`VPiF4K?)1X$zwx)AdyTq?5_1f^*qjm!&u=gsTvCvjLEMSkGwNs) zEv7H%##PZ64~kJ;3NhSKE!0iJXm07V#v>btc?sqcxM8C(F{`Y6cG*n&AlwBUk33)3 zdUQY0`~EX(;!dmB91a=FrFb{&oI!(f75yKjvE^qMM%vqXVqe>2Ny3l36%%Yk!1>;m za0CIcN;2Rajw{lyS;=t)!S!0I7H3Fjs?gA-7=P{2nuO-w9{Pby=62Fth3ec9Q*On}qlFtSg%#CL(`#V6QOY3%8JF7?lr zI$c>Yy*Il=3lqmD&?=p}rsQg+HeKb#$rhXEWi?JBH|F$0OFssn@ag=LSjFj)VIL9gMTK1e|lI3;{mwRf9!F%>5~-$rxRgg6~D0Tj7}yNbiY70^lhb|R5r8;OW8Jv z_+KVZUiX9K$y1(7l;`J|5IAo=Q9TLjiLNk?UtP)lQ1FEth~WQKg?_m{o0YWg={xp1 zkLou1qpakX6vyt!$Q}8Ekgu)vdwxDwCwKVA{tS4!taHHl@$2~u4~)M^_Ty)T`Afy> z73xt2^*{U1;obHo5jl%xw zPvm)PCNTp#R*`$Awb*`U%YcJ&f>IrQduC7{t0*~5nHIbb!Y)kbalxfpHPZF~X|akw zpJ7lm5aBc|+MSV1tl|NsHeKn(#}#%Ub9>yB9{*Y_iBXV^e~0fQ%`c=A%<`K*a)Sd6 zgWRn_^m~ji7Ja64(H!Fn5HStK=8$D=bYcujc`ogw{I+wsqhh5r(LapsrQHjeQ7G`g z#batJf*-5c(@t28lf>PWiy1nRoH>A0!~# zQj9;0%`hGGeql^cqvwD8W8hVo67@D`|9FfqUJY0;T$ad7)a5XV-1fA-2TfaKO?&6b zu4!p_Y#J;^;U=6e7S9Ss9*MjKUXF050BG$J$U;H)UV1k+(Z6$^{l6Uc)=RNd&Vj=| zZdF6Gfje-_#Y)YmD$@J9t*Bkw{YSM!3GKkT;mpTQeH7Opce&gil1xT_(=Bl1i@qGm z2%%^8d!CbT+FS8Bx84*v$?${a_Zfbmafo_iLNFSZs27N5h2-JPw*_@Dp{{^nF~e89 z9=y=N)zTec<;l+!eLJ8tG@>smqbSSjD+k2GR8j+&XyUz8U(eAR{N|n^ZcCcQtwG#UxG1C&stl^z@T| z+|9I-4iPu0?bklRdSF1S!wbbMw-tqV{QJ4Dp{m@@`DCbrDTc59q5nwhw%B?8TbAvZ z(V=WCl*saPm5t5QMS3YCmwyriAOE`!>{sW6@>{=k786t*{%{YDFYX6D20-1<^!4wP)x~Sw{A$-F6D^^N!<4g9+GEqV=4=^JknUANql73BWb`zjEMy zI{@73w;i}<19!Q=6=*291QPb$z47MykK=luO0xB~`&n_%G5(_KLP z=bHd)5yZ;|LX0m87+2^&|FRJ~VgSTXK}p0G8iGF+xG@4Zav(U)-cz^Ww>nr?9MGR} z_Xn`h1W=nOSpS4){#q62M{KExRm1v6IB?${0B*8@3!Ox^?G1qaSP={DxdXs0fkN>PApq7C!TL9BbM^P5 z*AsTq3xAvgx5of*ml!y=#>F7!3F1A1c%#bngIFi*>ikcLVk5?@_wP^aJ^^;*1G}eW z=FSl;tG^$tdcpGiUprXW4S=-;H)xDB;?c zQT@605AYGC$S2^g6SxBe&gu_?i##4*Vq$bd@ggOZbB{eW^DRF-7LfbQvl-Z21ZMSq}wmxY=wpg-sXv@)+F@_36Dv1rYo0qw%Qg!U-| zfchXNbd<|5T_B*}63~1D8uUf2&xn!B{i$)f#Uoi0O^4R6KfhZb`t9!#Qxl9P5;v=Y zwyX|1vfb60Su1NkA`_i67s<~f^k|0`G#v)M*T+gI#BDkQIL66wjHe5SlnL#m*!$Y^De+4mn8jcw0w)F*9~vaxjPAj|ZqGI8t!$1kgK`pzb`RNSJ^k+v(StgSQkeSV(J zZ6z%`HGyY4$jbjdlg=Ie^hFy>kP$RM<2;(YENGxYJFAHXV8GB+iRY@3sF$=3TN2CQ zw1AW>Kf$6FfTri%D@#=-zEBG(gsL0cF43jKeQy>KghD~^E?g_MD^fy@pCZ+C}#-_-dd;jng#vMAx*Hc+@#b@r(*a@~JK(7^F;i`xnrX_EnSH`D80dRF1P zJ1Wo7tY*`}sCg;zTpdHzb#oc915~|q%&G+ob(^KQi9Xv1HTUwl&M4(x#Di=BEjTo= zGYO)(XRM%OZYdXBD8%bECp^WB6lNxt$+HGE8L_Sr%4U%e5-S z=yA`s?3SgA4(5$8GVJG~+~eHOk^K0pV>HXV2%T$@UeUk=5DS7i)72nTC2UivqgjZg zmkMAZFow69gXV1UmxP(j7Dw9u4rc=CtXFr@B7}g-OK`3N#T&e&&cz{q;xJd}BSrHy1x7Y4TXCz^Ttn4{h26mGuqzUUR zER;CC&P$%Ba~|$6(i1F^NidV9n*V)Any}X9g6|>#SZNAVwpnt~m%qK-DiDc<{=p_* zX(l}YETI7kja9wvhbXE#2v)BK33xt~SI-qi%^AQuX^VS|Jh1^70f%OqVPdy%P0ssRutPGC&6^e!(%$GHfs)Qz;(Wi4tKgY0gi6s2!bLuQt1vEqDGRrbPZoaQk>)qj5nf*rC**;MqLb4Yj$zWKlfm6^95hIS zmbNbxgITD`i@T^-Yq+KcHVhLKY5SLAFxcZdPFaeyZ`502#LwnlD!J|b&{J_ihQAbf;%%Iv-zgo8 zG(K$kv$mvWHSQF9du!~u9L=^)Dv7ke&WmKIYJ{0`t-9+ZNjlKrU3hw)QMibdfFJQ?8E|fE-B^>Jxe6X;37l`F67|(xVlvpF)#*RHs$$ zbQ&-I2Cno~Qvb~>1RfJeXcz$wdL_JV_n-GG@Ft+8z18j$VIAX}wnd;WRL);T-`%>t5*LAEl> zcHdt?`cdX`{JR3$FiDu9*wU$DUZm|(>}zaknZ4YoHIwS4B{nj)Z9~lZx&;4KW=H)W z3RWGkGS)Pa|GB)F4`N{7P1P-PERPo_ITJ<{^n({}>K^?2PAb z;+Mfz%`LRUA^E5Cb4dPL(#luP-Pb>ZL&E|m(LY$zRH*25y6EQRemxk#!b!V_h|UuW zuZ3y;6MUth@pK+jWjt4&63z1821xh)H1(l!E{rxY`Z8QPk2apF2D1Slzb%VIx_VYM ze8w5>EvQ~Kdy52Y9}wn5X7io^3HZ7y~?U2+?l zzc*>AgZUF*u!-8_17Y53Q0tpyf$Y75jvaGyQ(ll@LKQ@tZn7a0-XLu|wAkc|PNKly z=fg0TX>*-A_j8hyN1s>YWj%q(W1*K4LXxWiHK6dQ{c}D+PTGoF3@!SY)VsE!JdJ;! zQi)x9*4d)RJ_UY70b2OyeamS_f6|0eT7Z-3v__GM#6CS61g5YLnByE6#cn*V0Fg@F zB*EwRXN!cLsZ@Bh7lw*UfEVMxa$cArZfx7WNNfL3oz2)|3cJ309mszDwXUY4zb;XK zU8MfHC}W^ZOVov>7mc?~z^qxX+olCXiG`cMFt&Y2q}|AjEm5-$YRdOo-Lg`&WyZ-Z zOSFOri+LFarUOM7@=8c-$MDJD9+M8_KKIhe2u1#r`jOrrs-7oNlb1R$DEa)x{w4qH zN_M!Ct?82Irc3Gqm)Q0^?r)(U6x-yEkV)elf**sLjuSq+l!l;6!Tn1d)F}??DQT!W zm(}pm$=ND-Y;~xl&Hf+mN^W@(5)%1u=|_~{Zn}~hW2@xwNuiQ^s?LAUHy+&WO8&2v zWWaNem8{H5F$95C2(YjNuDiWs_ZH6Vqr`TV*i( z_@Lx@14>SECHHqF3(_TZcC)eOQa#wkRGNs_#Z-~D^LcVBvbN(-C^Xgmz1UJ|d=`$4TSuQjft8&u;}~n6p4Id*tD8{z z3zU$|sli=2eY|s5P{eBaEE-?RD|up+n@}zw&%@sjP9?K11^;WNdf8bahV2DZ|KL*Zj$9*c?7icyHD4@4(GKrRm3hCYyak zCx7;P+6v6i4xxmTn&nsbLFw#1)q4G_J;zl$b3nE8`czw_YM=Zwf9`Vyb{$ad^Y?~n zfAi;t-7o$W!tOi5?mn`0_-kiieiHNmz2-;bS7^)xps-&ecqiA-6rq+?GpEroKRHew z?$FjT>lX}DhClw64NZ@*g2R7Mf9~TC{gTR>Lr9&B&zddLXaL)lzeQQE)}LAYNjpco zJmj1s7tLB)rJ`pO2XXgi^|O!vT$G> zG6^^OJS0zDPBqB2RD6D@JQkc^Vm}JGFru?)JV8GWNG0Ky9?;&cvqU_?u0`Nzn=qHG=&_Fd4_hkvuK?AzS_nkP(P4#^D( zjJYoVUhdk?#J{A=a=jlu*le__eSuv5E>GImg4Pg>B7GfmkA&{r>CmACp^k!Y#^(fw z&z(6TSccCJ!}#2WCc^(2kB4%Zn4c(o<~SJN*&O;>E_{CROX0KnNB=+I^YBuuY1aYx zytpjHpFD@pU&H;6^&-C`m%rJ;IOC!aK6WhJFvI8gzWC5Uq0Yah;>#aaBcbCh2(aY~ zu#teq5yT(U@U|(cG2;KaM;|iNJV6#^W%wi$xfoBfdt*z*;O|KMI4&o*am~r<6PxrC zXrg76*7#fR?^VyscwTZf{0r_HGzU8^jTZl^lsvlNJT=N>L}HI%{V^N!%FS%BAaG|l zzTYo;qQ>_dIBIyDMo-C+vBbWt2x@Ot4fIrY2%64yO^4>`v72_rgUy@qt{xAC_FfY+ zuhE*pr1S_38^MqU$jX#OBSpVBQ77{7`+~S>p+5*MR{l_3EfxPNfkBZrJB(MZg6&m= zCz*L6jgtXo2hlbv1ly>=G55`}S;^*kxU)9W-X?1BJZVar>b8`$Q+VLMjkG}x4|{mA zC7tBUYTUVHNg@2oYBc{}Mt28n01zOojdn=Rkq@{ zZHzpYs(njjZ%V}ZBH`S@u#P65(ql)%b#-$cM$R4{cgA{M+cc9kXy&*?w5^DfDF^jD z7kO}9JepI4n2Ad91^X>_0L_MQiV@lX_>Bi#U*P5umg3lD`4d^Z*?Wg#U;D8?=rMpf z6gU6SV!ue)ua@K`NQrSBqyPG4aAkF`xb~k9QN#cksL3?i5fV$OAPBFTya+YGrUSE~ z@MW-fEYBZJ-$v6|_;ThEY8=GO#Yo%OfX0A!fw`)dURnBV%brwfQbz!Th4(ELd;LI4 z{+CQqa2S3N!vv&eN~xDPx6Vr($q$rXiNsBA=uJMC&R{bAS329dg}hJieZR8>+(~L? z=^c<w`FH;Zp?V|d$ zPvkmA<>GHhghI5P4n{%fnfbN!(Sg{HYp!4;k%hY!seE!c;jaC5Ki(_{GCTw>C+iTk z&rf7OE21}?iz-joJEHgbpqbxKG~SBny*((|+!Oi3S6oG2)O~MDMgBoDes{H0;Ad^}BC)X}c>wC~=8)M<;lsX@?wx(n7S8CmH_#@Llnf8-@} z2@jX$G`?BS)VZeWoys+26e@Em$VKdS&lIJah8UFYMffG7`6S-^YxiSh zlicqt-n)OJ6V2}JKJn{-_enRlx=MvZ=oRn>o!8%ySb6(b!4&$a4oRSYF%me_NnpSB zcthCtaWUi*qleI`c_ubIY<+wBk321m;U5iLzIOIx?Qbe$`_bGn!P&=OU3;)emt1Ku zEXeksDRrYbTAE%;Vo`)~<3eI~R&9NE`ggshy%1N<-e17>>E`%80C&F@s?HLg)1ds9 zXJpQHIJqOeBkVsN_;7q|@BMgO=Hn)P^f&(y>e-*|9L|39FGA&^zd`a?FMD6Fz}`Y| z%bbr>{%Yig^OOx#u&gJjXKy=+K}0l}vu~7>eQp}97ueQZ)4Dy2$jdb&Q@fIsJ}9-T z`vgvU99+Xy!>4eWE6Y9RG3U2o?weZreA7!5z+!l@9u|hAB-fn2+Cm2tV@#x%Z45CY z3vA?`oHB%qiwAqHU$lZ@B&K_yI4%4BKUOmVI`Vi{kDL^V{mc^cH!LRc@u8EwCwm$F zYUF3jI8du5zLLAm+JCE>%U_8s_!SR2zNFMnBw^c=raXQr9*|h31}svym2tDw!o;7y z8*1S?iA@of7c0R)-n@a)oP(|1Y@=C-FFR7_L;+1uW~>;(;-rnI0{<5Jb!GEB7GQO# zc3!Y?L2R3s61^<4FPRPN!V8}(kh)13oT#A`|8Q2KrQ-f?VP6{OhibQ_h;lfr;_{`A z5Tuks!G?r8u2rzLt9uB{-cFT~*b!n^vf}Dz!pt7#5-(N@JU;Y-6pL_B@$0jS#M*T; zsbQV%07FKv@7bTk*0-`YDc+)du^vKSZ;Kw*#&^9FG@_h-=UQDCD{=`gtzXmS5AKzV)Q1Yn zv@UZLa~?$N=Z@mtTt)Ha;fnqx-z8bm=qfs=`zIlC+0wqQyRAR1)8)7%FW@AdHzV!l z07Ra8lPeS@i5uSXHf-WrYH!2a8R{SWM(P`=Kbjoz*zc>e#zFq>j{Fl`>KpK+iW9d^ z59r5W)oj>YTfVjm9#Boq2EUhXkgbldPkp3@-U0P*WLrgvWdfP0h`p++zA0T%_fMk9 zTh!b&Tn8@#5;0VbVyo#(AiPgiRwn9oidm4vC z(A2a|g=^{YR$1=KM~&7TEY&ue`XHD3F&xmTww3Iq=GN#j+#AhSTw9KfiG459v8=<2v9^kG5p!RokPFUj2H z(F|p`#nY6Hg0c?3Ee*G+{O#@Ka* zb}s`v;iuD$9KoKS5_74u*Lif>Elh>HrkY4p#}QYr0v>+t^R8afb-)8_HCHv#PiX&7 zN#t>_p{MKOxYuAG`4UlwM_1SzZ_qlyz7Q{4Er_IduZO~d6GG0L#jO&?xyA9{8PeXwY;#B*sNjt2?_eEfpeqE+Dr#4Il?C=fO>15&0|sp@Ndm)KqkfLAgW^$+Q@WRhkwH1 z%n|juPrM)fxlTSk(O)U~tW*_sZG%JMU8}NW7ki9XvzMv@42eZyVgE<8h~B`^((MR_8yv2rz||WZuCR(0<}PX{PBrtz zsy)67tKR4%E7ItG{8}ZE=o8PPOE}+4m|)P}BRT3VTD;dnTyg&+b;#fYOI5oQhz%Il zrWZJ7+L{n(^dN24g7$2f$6;A9#HbDS>ggPtGxHROZVX4pIE3W?-UE=>`& zDpNPqF`%+7%T+0fu@VU5&T70WvUnYiD8i>Xc({2m{yZIYZvN$_hb9LNk{$otT^*wimIgjdP){sJ z_JY2LOmOC426Na-5x#AEw7ao@_I zy7Ai{$K523_2NM)Urqi;vt>1SWHan-uH!;OD!usdViSk?CJsuGhOv&rz=CWuMBvE2;Jy{Q~i z0?PHqM)eRHo4&r><*s*UZ6tE1?G7ML*71@xJ>J%h-T__cK9x`tWs>>TR*}?Y&_;)$ zCJGxbNH>%Oxon3m1(xRx?%zf4w~!v-K#=rjvh|wah*R;4?PaZdnXH#&?uFH%!gl`F zrUm8^oH#M`VPC;o;Xd5;qtJ%~^xi(i!%eMh!Ch;Q{H#c9n4}=S z4aLgE!Cd#D#|NnvC*&vse1}u7*Q8!gIQ43XES4vVluvc)b!^b>KYWR)7g2Q^(xXvd z4pFQ0ZibXiI@WCU?tzqI8_3tVv+{|^*!wMLQJ}tGn1sHK7Cp6x>4`&n<{>(rh%~2J zCt#Z0W8wyv%~aDKyB`oTb#ij2O2#}HSyQMnwu;D>)G3*cb!vL8Epfuch;^F-H|x(d zRhD>#M{`2h!#YFQC32Saaj$OJl9h#fm34j9g=6uqHc~WJ(YTvjrf(xQ5560y3x-vi zay2u~!mz-9^r`>!q_#<^_|)Jfs)~#=pR@Q%nwO_sm56)|{iEsRqMe+?%iTC|=2Y5% zQAPd{`Yig<4~jLYSe`$88H$Ddv$F6zCy%=~5>(b9ez3Wj7NTC*X@QpBZ2kOw>s$?hE}n$1S=1;wEoHhMOddsFC3!ST$x+e%rGPo*9;*?)#(P# zW>)ywIZ*Iosz&(ayQsM2)I`o^J7}2mxf}OodGoA2Yg)HuF+`lnK}Tl~GtK-Z>?eph z`@ov=jWb69aMlzRE~?4?l(@o{Xynm@tGH@;JbNpUQR}3Hk1DB&KQli5@9}N_YCNW6 ze6p!$`~e?~k1YOIG+A-Z(rPXxT72l?wb|Towe6JT*v)oWPEFT82iGLWmYx!yJ0h$5 z5na=f$4Tj2W(RR4z_Z}T;FI&JBa2Jitz&ica`i-w=N5ZdqTb1pXKhXHps0iib#Doz zD9>L#SvsPTA}}#0=7izU`X3V&r@fvyJJepIDCY0Yx&)P|^x{s0OI0+_&sKUex9!z$ zBY1pC4@`ZZiFy@4wGpyA^p?#1*~U;dS~bh>3bGYhwhMoO7=Cppe^L&S_s;B(NWpvw z&T*$Q2zZf@oJkEtr_VjCE?(l!KNv0lx%K^(M)O0(o%&4%zwlzM-eb*$%v;+Pz1lib zm)CMt@z6-yF0$_gR%}HeyJv0W#X?9~4NXo$W|EyC>Kk1ge<&S_XoWe_D(l@a7tL}C zN|C)14F!vk(L#>CUZk429rb>Gxg6#Zdv$m35>?k%HV53Kt$B*F8=i?Nm7EU3jXs~? z#&A}X9I%#(qknZWJw@9Mjk8*hpiiE67)OtAl{st65?68xBzpoTmZ1f6*()%yvNn5Vw0vC2tRg$RdimU! zpKUANL>0_?1e|PrMhvEg^!6hTl8q)N6(O5v?^X5LvdT#NgJc-bF@01tghR^nqMRyO zetzDp@pj8d_fF`*$i2Bys;2Ax!8Nge45{IC$@p7U>$|HyTb|wc{He+FayfePz-alw zvpb{Z|C2ZCiD=^5g4%2j$v?3BVJ@qPw0%zz#ANP2H#sY=+W@fQ`TzR1thmDF-HQVc zMk`Mjf>1AO?e-eSxzq^Y$QaNuJyzUe*(PA&b#t1WnSXYD*%PHn3u+TOP0N~khv3qM z9a!0cy5J`4afpb-r!8oA>p@r$oSsVbvxD)4Nf82+mVf}maq5YJhE5%Tklq3r!uqk%|{5=!9GR`L^CT5aQ<495n3f+WhO%{fB>I zy1wq!km^Q3#D7tpOuf=+9y80a78 z7VRAvHako|ab8f6t--SGK{o&4pYi8*2lu0}b6KDQo!7{oY@Ucc`6IkHd*UUGW$Z{( zYkTFp%pT^IPt2ReC52NM=f6T=tFEQukBiX1#*yfrH?>b5c8(D-!d#D=FcL)1WHI^xOIK*0b%RF@;UE^-{0`))niU4+`v|=$h8{-WrpGx$pY=@t8xb|d_-Y2r)d?_NRM6NqiPdd@a&?!yX zc|WuqYI;RgNg$NyX@URY9a2XzA*LhK8)|5Y)kt>89|+pRE*i1UN_^lPSH=|kQF$HI z44eHg?F^jt9=K2`p_sa&?pFi;_b(5>saXcezz~W9(t$)h(YofM$m6q!gK}@?$J&Uv zW@fHe{>JQ=*k9C5qq65ae4o6v=NQ+XNU#Rsv}dU*#AMqIOx9Xo&{|{G>z2#O9(xq) znb}d4l+&3ev*YpA#`mNKC2fPf;w6JS zn&20aApI%uQ}i?9LZO{zCbys-7Lb&N=FdKvhW@=ZbgzCSF$^Nj?&JJaeIQ2|iM?@- zi_kA!xcy>5mKfVvHyvqz#Cl8ZT4kU~hhS@m=)qf5CHOR>TQrY3jkgvn3V?z1|H(xQ z!m&VvP8HiQ_VV(R?k*{evX{JelbUslnstkxV122VxSaoK*y(w2+rk^%{62c42D)Zc zfj*rBTfNbAk>-{=v|E-e0W&)9r;Rq6);MTeLr&F1qc|rZi}XEBYut%Iy^y4T3#v9H zx-?S=D(ck~K$sdj*1FlAt-De4Ok`6!}0EW<|szV}Y5%B6Uzk3{t;GpKn1rcsF=)T2TAy;z(L+ms?Newje_jGv#$< znXMz)ZX+_Qkgzmgx5FvuR*NKmIw0>_%+H5oo%vxUUU~#9WhIBFHt}x)YZ2GNi)Spi z8FpCbe`>pS0tw{c5*mkg?a!Y{)`imyDONPgFPZ*vs57%khf}oHIhnibyigZ;uqr=- z4;}t_)u_gMy~Cmel@kfDTiasWi}qgsBsFJkc;|o(<;&-8MzH!WUk;6*AkhY|rcdjK zLQ(7cOr=5CL&YunMW6JG2BwD%T7)O>c7xYCC)jmd9qkkKfQo#AiT&B3mJs0VDi+g7Ce4D!+QA__;RH;LztUZ^8p7TP_ zh3~%((eY_qCP@Kl9VxUvvPTEBT7Fu<86}RX&A$MBpgf-Zt zgtSSPpvVSdh12(C+Sb~6m1>0gXktQxIp&Nl>U6i)O7i>T36-El%_BluG(sPy-72`>|yk{!&N_#Rz}AWlI|Ya{l8M%lXQxP)@PS-!}l*Yykh{vVHk!C|g9?K2=TB zi^&JtPhGb7>QFXxBg=n2$cCLG+mBqf(+6a`FUZzl**ur+)el0@%$8gmWUIGq2e@p* z2SBU0Y`td9-+HqV`|5KcfQH_81Auh~aIMRB&6-d)^R$Nq0M!(hbFr(sW&rnI=YwC! zEWJb(>xvwt2i0MTxf6ruC3f<1o!y^6czJ@8$&nSVx7tzJ)Ho|vg{MzzJtcmr=gJq#t0+hpW%y7jEwQ|Zj7mL7S^rw1+eq=G`j8YK05JbP zaXyjz!ZFnVMo?a2B9x5F{}E~l40D!$4H^9<0+TicL^IM>gL9?CnHFUn?yCCJd;K9C zZ&jrg=5;q${?7VPHdC14mMx?(e{ebPe>Rj8nzH=OnxF?8Rcpw{UCupM^v~HzPX7xR zi$CVW&{vB*ervkXJS4p7>szW|XZK-nUWjXU$mW(GvAf~A4)S1VaG7s3p~230{s>pg z@81p8VhkJ`V4F6Sez(K+%&^c8QMJ2UPFw{es@k>4gJFJ}PO3c8Q>+WMXt^6)zQ_PJ zEhnG<)pg;PgI$in{>4g9=Kj$Ok;v+yEI%pi0AFIj4|l-d`%8!_x{WOVV#^k4tz2^Y zi;w|7;Xt1=HUxSEUCtket2U*0(Q=wM3BcJd+v2c6w_fDoAe-w& z>Rh&y24J`#$Trmo8SSzS9gwXd$kt%l2Dxmv`XMSzV#|YU^_J~5*R!s9CX~(Cvb$vq z$<(7R=dA;B`l^ZcaJ|U&F59syLjbK8>9TBX*3eetLtztkU|fp1xkcsF2cB-V{_XmeCpp^IYg3 z^AO*XxsU!J)F8#8e!okNfklO(54H>}hYub8caLSXv@;WOnTXLvUV1*j;xk;zwZnK@ zjC-is*z1&)-jn^-&>4qQHnbEXac8I4Q@%0ME9AXG0B(m*Ts3o0i1{|LzF?}g%J@A)AFNfba35BU41KUZe{_C265=zN=dt#-g3VIi~UC&goau@iWcWX{I|Eh^h*bC}AtH4{~^kSIKdq^o_BBgU$*7IM-@QivOeulHRczUGgzuXcMM zI%QQqWiZOXLjFH6Xc{DOE`Q zASF7|>uUTzFfdL{vKU@Q`FQAUzhrfKKJH2c^y}v1R2`5u3n(V~&gog3P^+gInA%*uM^9mE1R~X2S;sau$`nKNkjfG!w<6d5 zmYg=8Y?)KcQAh8Z(n(%8JJC()?Om<9Xjhmw7M4ZYrqW*}3WzS=c)p(MbJ&=2qn&LL zxYsbhjL7^Ad*pI*|GG$0+gm!4XAJ53d~oD<&v_TF@{&2Uj`PQ5b*Zgd2GS9E8u9G) zk?YJtCa$cri;Es6S7JA9Y$$&&5@kmF>^vt0=~dsooresnGx|t}Xc+9Dby7fsl%xm| z>R|0WEOXqJIWI86osR~w)qL`)Qm}-evThLyhz*b1f=`QrPgyEWsGw8tt-(wnMbrJ6 zXmcnbmTo`HvT-URbrDOq&7B?J+_W<{!38da(F zio-%jhgbrG7us)7mJnlsa(g|t>4&kQi;&3(6!|At8tK^g^g4f6+}8IQ0nZrlKuiS; z#$acv%rWEp2UT)#DYKc_Cj#F7;Wk-Ve@BQWgW_XpNBjZ8`Aw8 zcLbRk>s{DsM(Ft#%lO8Vp^P+JmfvW8OWMJ{&t=;$+;drXQyaK9PQ+z9Eo39BdW1f) zQ!ea*?JCfF2cTgyX7EV|`k}`|7$Cu{KX1i-I?NIBm+-Jq4ey`%eW1e)YXjiu+1kM@ z`Y~nVl^T&(c%#4pB4k(wu?GtvU^b?*3Jgp*YtOIbOb#&4`9}y98%F#OsHlP+P#M*y zWbRvk50$au_K{XbGY6vb#cM5Fa&ah|B)}gUWNWZ&50lNWnZuu>94;fnqYESa+y;ls zjtQ?g)(J@qu)Y67NKSK+^KDy0IGK<%(r*nfAsihrA^B7c1GE#8pE}SB{usi*gyeZKEYA_L=%1ml#;e0G z5Rk7El3~aE7eaD+nPg+CUp&hY_1_BBVX|?GA-Y52O7)3FU~h-Y7+!l>8Oa8cSr<$# z`HwPvPWDS43uQMM@kKqns53TSPd5J`#KSLeIBgq1_p#^mbw-ncdpH(y5x*;uyFCC` zZ{Us>xR>Cd-{lIt@@A-hBhmk!e9GMq!9ls4MU7$iq~G~Hpx@jPs!xmU{0CG#U8s*g zv&BtL+9lPk?{`RM;}1DQ&t%F%y<>z;>*!E!tX9v4`Yy7JYsb7c=Cd(9-t}Xi})~1Pq>q}g4s09Zl230n*nO$3=oA^^>cf99TLy+e-3OfLG7F^8??svA8mdun9Ze|GG;}tg|4hZHJp`neL62uj3xr zn#ifo)h3Ffw0uovSbhbz_+c|LdrC2j{ELn#|blzo<_! zO{-52{v`wIqh;EPTa=0MNw61U4^??{Kl;x5@9I;$%j&bh*Y;pt7CL40Io~Yf>h)H+ z=-X6zV}`Z%&}%=$-~Y0Hbyilt^;%aAs9(~g`WNZ9xBjC4tNzG!D^#M-c?Q8ed7W!( zC@eGo{3grDQG*Z=g{REjk7dYPbS+nWN>`m^*dh`2yeJ=nk{(o}+y(yIXG?XbArUb< z*8nL(Wb%NkV}#fs-}RvelsJUl4@DNUGcCXJ2Btf*S4w!ePZ-$Pnh*#bw@$@ri2j&^ z5ayA1>0yrd;dkV^xREhX#uyb{pt{+KxxMJx(%F-rC{j*ce9guW>$+^D(5OMYoGwV3 z-pgu{>VISg*Nm(DH8_H)(8UliqlC>A0^j|j0rp?4)t;nli@|tGAB_9qt6?kc123n+ zRdi5x3oJEc($Rwg$~G==o?#7_6&c2A9Bz*{^vekft?@9~LZObMD4O;bF_6$G5^TMr zK*n@EAs(xOKnk-+mxe zYH5brr5}B4)ewEy`e{%FeO|_)Z0^!%N6Rk44 z`z@gd+6sj<3Rxt{&wJT*1aMv-)1AcBZg$@>gKP&4DEl`fRf)(L2VvP>5jk!Y>S zf(uBBG#F=L5je=(5vKANJhv`6W$%E%BO%-$9nHZ`AA4Kh@VdS_F?zrocF@yN#nI8M z`&5{Kj0M$rCx!m4G^LReP1dm{T7fj6Rz{N}F#>7J92}r)M1q&01lDtflC>>+W`sSr zvF`}Qn)1)D8Gdr2xTCgw^)PiKa22nYS(njJFD4GKXaUZhWg}i{~$Xwcc@pPY9cp0qRK?HI){tJ zAZNAJ+;)WVlO_T2q3CMnVv-A2a&-UF|MXBaGQNuzEA(q#ba3FHf-i6e)3t8)EVU=R zv4);TQ^s`ZHjBOl)o%Ww)8Y>w<^EhRJJ=gBG&t(3q?O)T&1dhXZ z2*Y*we;Wm_-t5b(0rqUxuoY zcI-?O@A^>xL?JcjoB9ts2B)u2mBHnl&Hx?t)#*)~DbV3X=W9e3+^?79xISlWzS6 zd}M(c5zTR+b$(vdbw)I98cg?7UUGil13G5v(6j$s(~IWJWAQ287v7+ls)ucq$tr@J z^0hj7X05GE?jX_j;U8oNbLa*fcRIzO32brN4xxUYo(QOB`5%nusZ~#(^3>r!Jdy?> zQTM) zYb%|P#u?&ErWq5EXSLN<%b5Sp<=@;^N50#?tyurIuE{0|OoVALxqBS)uU5f=_4OoB zK05THZu8z(+k<>-%h)M!V0b9?c%MmsjZHFfF^8tr(}`ZZcfrqOCy zKIt0m3_V$+mFvkG?L?j!9sN5z6`c=z{Kd5z9c|i&*8Jx4ADE{c;J=6~$iBah(U6EG zn%vnq%_+6gR|ShgQ2<5wXm0G42Id^UbdFjW>Cl1-@+t?w%%aIA@KoU6PPeTOWRow) z6M3!UO?v}@jpkcAg^PU0og@hzDw>XkKhE6u_s2FmdH^_0il;xoX9fa)^8tOM-71}g zf^r$dSsXMx$y#qdCuS89G=QSgA z;Cdr&b)!tX;Ky|16|Wc!^$g~6ip(R9`@+r&FpG}FNh?&Rv*>i1mE7tae*wSaVH+Gk z6T^oLMAWJtguytS?OX(trd=!$d2k-`c9yb0US3Q2VZpgeJu5Yt;367cY*RLa zk)`Bfz0E2jG3Z_!gX#$l_JV4*jPMRdj<; z5j(y5L9^|m(0;87=CrNq{(b)(kQ!gf0p_E`$iAfmVG+OjIqQ;7aW4r@nmRnFhmf0> zo3#ZPTQ{=jfU{(53}gqO3}tJY1{cZUqn2b9sD$hp!b{`R-34-soJXCoBWh~#crerH z`pMB1Y0DJb)}vjPQD9`#RHhASi5CS8;#98^h>Cvpm?5L|mn!5@An&Dw<5*nX=>)x; zo_F3JIQ7{r+Yf8ZZP|WE(>toi3otFhdfYJ-bu<$2m@D;UI>RR-Zar(ggbu(!tZ2YI zFE$rPpy?pxa?X)qm_~J>?SB#`=G&0Tg#VjBeOroAC_dH+Xnlt4fv^fB>jPkk!<5&l zygU`?sa}v8`U3Dbj6ivw4tH%P6nz~Y)+i>LPKM?AH|QsQE-2vgXwm}z4fblPJ)HkC zpgm@BINQLzP;qAm&B$RXGj{N1x?urx%NhJ5K(PA}+Bdy=ovR8LYJo2mMrmVeW`u8dH&-!!IbR;VnSN_D-Q@brAiq&cl&|SfTQ?}7eDPj#>VKh0eFdDe> zZ1EfvN&XH8H=1Av=jp_Vrw}9N0{A;gt4Zu!lRTFhzbSb&I!QRr{;;jD*@42bcSy?F zJ67@c^;%KVegWCNxOLP>C_}||c3wNvCyR&mh_ufFBQI8QO9W3f()I(hrY6vISwCf( zTf-QOFl*ivp)0^I8zymSwlks<&4n7LvT;=7+44^!3m%v9>Ab`;mBzwP*P=k@Q|3NX za1d#NVBI?sbm! z$Z=aGOp}9YQo_?6;v!8Zoy_z1W7bk6QXy7IMvD4xC~i?E=yaKf<2R&l!U|R~{}y4GO3NKL~IqpRy2s4c$%h=u2MJacdc=F0Pas zBGm}3dMDx2$*+WXrM=(fW}FFHY|(oL&s&3K1nFI;w+0(PZVlvYN>Ma2 zV7MBy8L~}9Z zTwTMNe#e<&Iq~yPD8**cqohN~761yhIq2MGEW|6KlW>7{TE0+bzKAdEN8m?Dw0B-} zm?X|MUQ~@21c?;He95)A#GN`)he+x!?9@qQ1)MOFl&6}^X;I@Z1ZbkVb!bKqBzs{z zsJ_5Insr|ioFc(3q|dzFi@)su=y3XopUJ(IjoMXE?f%}^f$1SbGK(R}*=%e1k(?Fd zAc9XT#+6Wptm8^!6$h*_({-y7;^PWMTZ0McM0$_y94OS;G*Sm*hM*D=RHOhKVr{a_@SoqdU=5?X*x0tL z?szo5!oT*r(0id8REE0!5yO1|nS;}0Ccr!~h3;y5cI3K{61LsH z*g>sjT+Cl=M{te-fEfpZ^ws}AX*x4Gi4qQYSn4X`>_Se?iV zo5a;jh)v&iTB1Zhhn1V|>5gL*;v&7-}L(a(1Id3yA(mn8-9&I;A*mfq7*RQD>oXN9->PM2+4bWd6bSJQI z-kRweD*>-~C(iAD9<|b~(M1kc4k?$U2<20-300|-)OqT)rph>|D!H@%V;|8@WTy`? zx77@}O{8$rmKSGB>McPI+&0NA>T|yeCy%aqv5)=z)p3EKprj7-puc04j@nrN)bTWA zCSrN1(@UqmV0%{DZ+cx&TX9S9zEQvMqa%3VWbdLW=@H{p2cho$ZA&J^>;`qv3(@*0 zi(+TqjNK_#ar$$TjjJ_c!Au(|y?w~0@_+^or%)^4viwqljFq$2>Sgm?w+km}Au1_7 zcRc6C`6lWWc`+47(5%f{pOGl&IMhjbVYNu6S3St0oe_23M7`KuDT`;!6qTtTO2xT9 z+)Ar=4T!bIqXRY%8e{0M`ITB#BOFk~o@nr5yfV3PAf1XrsAK^`AJvR5Z6#tXMRB<_ zIejVcC+&g)?EJO!wUO(7DADhGK29>X{_-N)85#ZEn{MP}c+-mc=l{4mOFQ4=o#G@u zKwCQxElW)kxwOh;S9`saQ)uw%_@8)mxOV>mQA>;0<7kdu8>^VP(yaA5KGejAu8l42 z5IIf1Vu|x@_H>7rXkDUWiJL{ZcgW2x`T;E|N1lJ=Y{!4CvP9$=?Z>Ydj95jXKsOOU znJ-9QVt%IzCa#yDc!yl?q%$z@{`<4O)Y>0Y8myPV%wJ?+)~yhj;efs0z?g2XOZAw+ ze8SS=EB%K`=#k&{l252E|8Bh{6$IeZ&Acc|SY*PG~`_VuGQ!8m1s-CkAy%KgjGqz)U&xc0X@)Z}e}s_qFQcSIQP|FO@A`J_J#m7Zyb` z$`^T|_4czWkwtu;Y4C=zHGgv7??B@AF$_#354E-w2NNw$2s@kJ5?TeIRk++gk7~Mq z^Ue1DCXFw?#@=W2cpoouL}Fi5wK(?07hE-yi=5BPLH};Cr(B*E+S5*~vzcd4LpW}{ zktcP6)^R7V)H3YBthHc1GLn2t$`)TC8y8LFFmgLJyQX|qBvwY5S{jxyO>Ke$ZOS*! zBF;3Cq0t}~qzul}%uQ@pWy)S&lQ?g08jggIZHz`2BWII7g@~RFIwmHE4z6Kq^$itN zXSX5Js?T?Po2uomV8>hFp&jgGiuAbxFzH^*#%i49izVU@Zh(d-&7PLE%%MJw*rwJd za!_n~Iz#?kB~v*DR`bIwaaja-$#R27M&VWGzjUgt&8nVxFj$~^*y+5Z$>#s3-YxZ_ zH1_6y&tX~C=F^nq#ypl8P)1&!|AKOJB-l+NCIB;7U={~p>I_W1z}ypnX%RNc3>c`F zBrhblzk%=m)541n&GKIJP!tyZF0caD|Mk)`Jxxo!zl)<~Z8C&}RLmdKhn5Xz1Ao*G zXlZar3>FfTghY9O#8fYs3d~^R>Gp%=k{Ua#Y>bz<3h%0l;qvE^*vlqOFB9g^nWV#> zIbbXjd)yLD9yms5xEf%y11hMzXe+BJ9-7QxCY&Js0ZP7pU~6 za`MT4h!g~Q`2I-nu6)Yh$*=OSwBM)fT~6;3-lHs|FQ1p!be4P{*L&!wDr8FfhAE$m zJMh?nU-WQ2SYcKp5jF{|3kjk+DU7J7rT<>Hw9%D3I!;0 zG?=zb;gf$aJ2m_cSL4pV36&nI(vKfyV7tOcDiJWEKjZ^b30uEI50T8>^NUbH0ux#O zy#I%_H-V3;I{*I@NFXS9qk=|@HMXh7YBi{BlS*nLL2ocoRJ7EkKUz?!r8YtWs4T%r zAmcC^thKn*YU{V!*4DL%xFw*1v?^+AUFxoQ#<7Z8Su6R!KhL={nFO)@zW!fcFEaPu zvpwh8&vP~vWck^1WYDS&ti?;pt8-ztxGwv;#x1u`o82Au`@FqtR$A{37}}-$2Fs2s zP#?o!*@;|}fJ??PVuNI6D}!a8fmGeJrq0G3w=ys`U2bXO3>)K6eKx=VCwsnOXrB!<&_H>fJG

#*Cm>Q&)8&hNpPEJ;7&F?J9(1H_%?ilf%q>IW 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

bFOIRNi*3a$? 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

;^qZPRO1j6f2^8AQ-)6v*^ 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 z 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