Line | Count | Source |
1 | | /* Copyright 2026 Google LLC |
2 | | Licensed under the Apache License, Version 2.0 (the "License"); |
3 | | you may not use this file except in compliance with the License. |
4 | | You may obtain a copy of the License at |
5 | | http://www.apache.org/licenses/LICENSE-2.0 |
6 | | Unless required by applicable law or agreed to in writing, software |
7 | | distributed under the License is distributed on an "AS IS" BASIS, |
8 | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
9 | | See the License for the specific language governing permissions and |
10 | | limitations under the License. |
11 | | */ |
12 | | |
13 | | #include <stddef.h> |
14 | | #include <stdint.h> |
15 | | #include <stdlib.h> |
16 | | #include <string.h> |
17 | | #include <sys/socket.h> |
18 | | |
19 | | extern "C" { |
20 | | #include "event2/event.h" |
21 | | #include "event2/buffer.h" |
22 | | #include "event2/bufferevent.h" |
23 | | #include "event2/http.h" |
24 | | #include "event2/http_struct.h" |
25 | | #include "event2/ws.h" |
26 | | #include "http-internal.h" |
27 | | } |
28 | | |
29 | 31.1k | static void on_msg(struct evws_connection *ws, int type, const uint8_t *data, size_t len, void *arg) { |
30 | 31.1k | } |
31 | | |
32 | 952 | extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
33 | 952 | struct event_base *base = event_base_new(); |
34 | 952 | if (!base) return 0; |
35 | | |
36 | 952 | struct evhttp *http = evhttp_new(base); |
37 | 952 | struct bufferevent *bev[2]; |
38 | 952 | if (bufferevent_pair_new(base, 0, bev) != 0) { |
39 | 0 | evhttp_free(http); |
40 | 0 | event_base_free(base); |
41 | 0 | return 0; |
42 | 0 | } |
43 | | |
44 | 952 | struct evhttp_connection *evcon = evhttp_connection_base_bufferevent_new(base, NULL, bev[0], "127.0.0.1", 80); |
45 | | |
46 | | /* Associate evcon with http to satisfy evws_new_session requirements */ |
47 | 952 | evcon->http_server = http; |
48 | 952 | TAILQ_INSERT_TAIL(&http->connections, evcon, next); |
49 | | |
50 | 952 | struct evhttp_request *req = evhttp_request_new(NULL, NULL); |
51 | 952 | if (!req) { |
52 | 0 | evhttp_connection_free(evcon); |
53 | 0 | evhttp_free(http); |
54 | 0 | bufferevent_free(bev[1]); |
55 | 0 | return 0; |
56 | 0 | } |
57 | 952 | req->evcon = evcon; |
58 | 952 | req->kind = EVHTTP_REQUEST; |
59 | 952 | TAILQ_INSERT_TAIL(&evcon->requests, req, next); |
60 | | |
61 | | /* Add required headers for WebSocket handshake */ |
62 | 952 | struct evkeyvalq *in_hdrs = evhttp_request_get_input_headers(req); |
63 | 952 | evhttp_add_header(in_hdrs, "Upgrade", "websocket"); |
64 | 952 | evhttp_add_header(in_hdrs, "Connection", "Upgrade"); |
65 | 952 | evhttp_add_header(in_hdrs, "Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ=="); |
66 | | |
67 | | /* evws_new_session takes 4 arguments in this version of libevent */ |
68 | 952 | struct evws_connection *ws = evws_new_session(req, on_msg, NULL, 0); |
69 | 952 | if (ws) { |
70 | 952 | struct evbuffer *output = bufferevent_get_output(bev[1]); |
71 | 952 | evbuffer_add(output, data, size); |
72 | | |
73 | 952 | event_base_loop(base, EVLOOP_NONBLOCK); |
74 | | |
75 | 952 | evws_connection_free(ws); |
76 | 952 | } |
77 | 952 | evhttp_free(http); |
78 | 952 | bufferevent_free(bev[1]); |
79 | 952 | event_base_free(base); |
80 | | |
81 | 952 | return 0; |
82 | 952 | } |