Coverage Report

Created: 2026-03-31 07:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fuzz_string.cpp
Line
Count
Source
1
/* Copyright 2025 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 <stdlib.h>
16
#include <string>
17
#include <fuzzer/FuzzedDataProvider.h>
18
#include "ruby.h"
19
#include "ruby/encoding.h"
20
21
static int ruby_initialized = 0;
22
23
// Wrapper functions for rb_protect since it needs VALUE (*)(VALUE) signature
24
571
static VALUE call_str_dump(VALUE str) { return rb_str_dump(str); }
25
571
static VALUE call_str_inspect(VALUE str) { return rb_str_inspect(str); }
26
571
static VALUE call_str_length(VALUE str) { return rb_str_length(str); }
27
28
571
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
29
    // Initialize Ruby once on first call
30
571
    if (!ruby_initialized) {
31
1
        ruby_init();
32
1
        ruby_initialized = 1;
33
        
34
        // Suppress Ruby warnings to avoid log noise
35
1
        ruby_verbose = Qfalse;
36
1
    }
37
    
38
571
    if (size == 0) return 0;
39
    
40
    // Use FuzzedDataProvider for structured data consumption
41
571
    FuzzedDataProvider fdp(data, size);
42
    
43
571
    int state = 0;
44
    
45
    // Create string from fuzzer data
46
571
    std::string str_data = fdp.ConsumeRemainingBytesAsString();
47
571
    VALUE str1 = rb_str_new(str_data.data(), str_data.size());
48
    
49
    // Test various string operations that might have security implications
50
571
    rb_protect(call_str_dump, str1, &state);
51
571
    if (state) { rb_set_errinfo(Qnil); state = 0; }
52
    
53
571
    rb_protect(call_str_inspect, str1, &state);
54
571
    if (state) { rb_set_errinfo(Qnil); state = 0; }
55
    
56
571
    rb_protect(call_str_length, str1, &state);
57
571
    if (state) { rb_set_errinfo(Qnil); state = 0; }
58
    
59
    // Test substring operations
60
571
    if (str_data.size() > 1) {
61
528
        VALUE substr = rb_str_substr(str1, 0, str_data.size() / 2);
62
528
        (void)substr; // Suppress unused warning
63
528
    }
64
    
65
    // Test encoding operations
66
571
    rb_enc_associate(str1, rb_utf8_encoding());
67
571
    rb_enc_associate(str1, rb_ascii8bit_encoding());
68
    
69
    // Clean up - force GC to release memory
70
571
    rb_gc_start();
71
    
72
571
    return 0;
73
571
}