Coverage Report

Created: 2026-03-03 06:57

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