File: query.cc

package info (click to toggle)
sane-airscan 0.99.36-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,148 kB
  • sloc: ansic: 19,749; cpp: 156; makefile: 108
file content (108 lines) | stat: -rw-r--r-- 2,796 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// Copyright 2020 The Chromium OS Authors. All rights reserved.
// See the sane-airscan top-level LICENSE for license terms and conditions.

#include <fuzzer/FuzzedDataProvider.h>

#include <cstddef>
#include <cstdint>
#include <cstdio>

#include "airscan.h"

constexpr int kMaxInputSize = 32 * 1024;

namespace {

struct LogWrapper {
  LogWrapper() { log_init(); }
  ~LogWrapper() { log_cleanup(); }
};

struct EventLoop {
  EventLoop() { eloop_init(); }
  ~EventLoop() { eloop_cleanup(); }
};

class LogContext {
 public:
  LogContext() : ctx_(log_ctx_new("http fuzzer", nullptr)) {}
  ~LogContext() { log_ctx_free(ctx_); }
  log_ctx *get() { return ctx_; }

 private:
  log_ctx *ctx_;
};

class HttpClient {
 public:
  explicit HttpClient(log_ctx *ctx) : client_(http_client_new(ctx, nullptr)) {}
  ~HttpClient() { http_client_free(client_); }
  http_client *get() { return client_; }

 private:
  http_client *client_;
};

void query_callback(void *, http_query *) {}

}  // namespace

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  // Limit fuzzer input size to 32KB.
  if (size > kMaxInputSize) {
    return 0;
  }

  LogWrapper log;
  EventLoop loop;

  LogContext ctx;
  if (!ctx.get()) {
    return 0;
  }

  HttpClient client(ctx.get());
  if (!client.get()) {
    return 0;
  }

  FuzzedDataProvider provider(data, size);
  std::string uri_str = provider.ConsumeRandomLengthString(
      provider.remaining_bytes());
  http_uri *uri = http_uri_new(uri_str.c_str(), provider.ConsumeBool());
  if (!uri) {
    return 0;
  }

  std::string method = provider.ConsumeRandomLengthString(
      provider.remaining_bytes());
  std::string body = provider.ConsumeRandomLengthString(
      provider.remaining_bytes());
  std::string content_type = provider.ConsumeRandomLengthString(
      provider.remaining_bytes());

  // str_dup() is airscan's internal string copy function which uses mem_new().
  // Only body needs to be copied, since http_query_new() takes ownership.
  http_query *query =
      http_query_new(client.get(), uri, method.c_str(), str_dup(body.c_str()),
                     content_type.c_str());

  std::string unset_field = provider.ConsumeRandomLengthString(
      provider.remaining_bytes());
  http_query_get_request_header(query, unset_field.c_str());

  std::string set_field = provider.ConsumeRandomLengthString(
      provider.remaining_bytes());
  std::string value = provider.ConsumeRandomLengthString(
      provider.remaining_bytes());
  http_query_set_request_header(query, set_field.c_str(), value.c_str());
  http_query_get_request_header(query, set_field.c_str());

  http_query_status(query);
  http_query_status_string(query);

  http_query_submit(query, &query_callback);

  http_client_cancel(client.get());
  return 0;
}