Coverage Report

Created: 2026-02-26 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gpsd/fuzzer/FuzzClient.c
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 <stdint.h>
14
#include <stddef.h>
15
#include <string.h>
16
#include <stdlib.h>
17
#include "gpsd_config.h"
18
#include "gpsd.h"
19
#include "gps_json.h"
20
21
1.58k
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
22
    /* Production uses null-terminated buffers from recv() - replicate that here */
23
1.58k
    char *input = (char *)malloc(Size + 1);
24
1.58k
    if (!input) return 0;
25
1.58k
    memcpy(input, Data, Size);
26
1.58k
    input[Size] = '\0';
27
28
    /* Allocate structures for parsed data */
29
1.58k
    struct gps_policy_t policy;
30
1.58k
    struct devconfig_t devconf;
31
1.58k
    memset(&policy, 0, sizeof(policy));
32
1.58k
    memset(&devconf, 0, sizeof(devconf));
33
34
    /* Test json_watch_read() - parses ?WATCH command JSON */
35
1.58k
    json_watch_read(input, &policy, NULL);
36
37
    /* Test json_device_read() - parses ?DEVICE command JSON */
38
1.58k
    json_device_read(input, &devconf, NULL);
39
40
    /* Test ntrip_parse_url() - if device path was populated */
41
1.58k
    if (strlen(devconf.path) > 0) {
42
68
        char modified_path[128];
43
68
        struct ntrip_stream_t stream;
44
68
        struct gpsd_errout_t errout;
45
46
68
        strlcpy(modified_path, devconf.path, sizeof(modified_path));
47
48
        /* Ensure port is present to avoid getservbyname() MSAN false positive */
49
68
        char *slash = strrchr(modified_path, '/');
50
68
        if (slash == NULL && strlen(modified_path) < 122) {
51
47
            strcat(modified_path, "/mount");
52
47
            slash = strrchr(modified_path, '/');
53
47
        }
54
55
68
        if (slash != NULL && strlen(modified_path) < 122) {
56
53
            char *colon, *at, *rsb, *lsb;
57
53
            char temp = *slash;
58
53
            *slash = '\0';
59
53
            colon = strrchr(modified_path, ':');
60
53
            at = strrchr(modified_path, '@');
61
53
            rsb = strrchr(modified_path, ']');
62
53
            lsb = strrchr(modified_path, '[');
63
53
            *slash = temp;
64
65
53
            int needs_port = 0;
66
53
            if (colon == NULL) {
67
34
                needs_port = 1;
68
34
            } else if (at != NULL && colon < at) {
69
2
                needs_port = 1;
70
17
            } else if (rsb != NULL && lsb != NULL && rsb > colon) {
71
1
                needs_port = 1;
72
16
            } else if (colon != NULL && (colon + 1 == slash || *(colon + 1) == '\0')) {
73
4
                needs_port = 1;
74
4
            }
75
76
53
            if (needs_port) {
77
41
                memmove(slash + 5, slash, strlen(slash) + 1);
78
41
                memcpy(slash, ":2101", 5);
79
41
            }
80
53
        }
81
82
68
        memset(&stream, 0, sizeof(stream));
83
68
        memset(&errout, 0, sizeof(errout));
84
68
        errout.debug = 0;
85
68
        ntrip_parse_url(&errout, &stream, modified_path);
86
68
    }
87
88
    /* Test parse_uri_dest() - if device path was populated */
89
1.58k
    if (strlen(policy.devpath) > 0) {
90
47
        char uri[GPS_PATH_MAX];
91
47
        char *h = NULL, *s = NULL, *d = NULL;
92
47
        strlcpy(uri, policy.devpath, sizeof(uri));
93
47
        parse_uri_dest(uri, &h, &s, &d);
94
47
    }
95
96
1.58k
    free(input);
97
1.58k
    return 0;
98
1.58k
}