Coverage Report

Created: 2025-11-16 07:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/serenity/Userland/Libraries/LibIPC/Decoder.cpp
Line
Count
Source
1
/*
2
 * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
3
 * Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org>
4
 *
5
 * SPDX-License-Identifier: BSD-2-Clause
6
 */
7
8
#include <AK/JsonValue.h>
9
#include <AK/NumericLimits.h>
10
#include <LibCore/AnonymousBuffer.h>
11
#include <LibCore/DateTime.h>
12
#include <LibCore/Proxy.h>
13
#include <LibCore/Socket.h>
14
#include <LibIPC/Decoder.h>
15
#include <LibIPC/File.h>
16
#include <LibURL/URL.h>
17
#include <fcntl.h>
18
19
namespace IPC {
20
21
ErrorOr<size_t> Decoder::decode_size()
22
0
{
23
0
    return static_cast<size_t>(TRY(decode<u32>()));
24
0
}
25
26
template<>
27
ErrorOr<String> decode(Decoder& decoder)
28
0
{
29
0
    auto length = TRY(decoder.decode_size());
30
0
    return String::from_stream(decoder.stream(), length);
31
0
}
32
33
template<>
34
ErrorOr<ByteString> decode(Decoder& decoder)
35
0
{
36
0
    auto length = TRY(decoder.decode_size());
37
0
    if (length == 0)
38
0
        return ByteString::empty();
39
40
0
    return ByteString::create_and_overwrite(length, [&](Bytes bytes) -> ErrorOr<void> {
41
0
        TRY(decoder.decode_into(bytes));
42
0
        return {};
43
0
    });
44
0
}
45
46
template<>
47
ErrorOr<ByteBuffer> decode(Decoder& decoder)
48
0
{
49
0
    auto length = TRY(decoder.decode_size());
50
0
    if (length == 0)
51
0
        return ByteBuffer {};
52
53
0
    auto buffer = TRY(ByteBuffer::create_uninitialized(length));
54
0
    auto bytes = buffer.bytes();
55
56
0
    TRY(decoder.decode_into(bytes));
57
0
    return buffer;
58
0
}
59
60
template<>
61
ErrorOr<JsonValue> decode(Decoder& decoder)
62
0
{
63
0
    auto json = TRY(decoder.decode<ByteString>());
64
0
    return JsonValue::from_string(json);
65
0
}
66
67
template<>
68
ErrorOr<Duration> decode(Decoder& decoder)
69
0
{
70
0
    auto nanoseconds = TRY(decoder.decode<i64>());
71
0
    return AK::Duration::from_nanoseconds(nanoseconds);
72
0
}
73
74
template<>
75
ErrorOr<UnixDateTime> decode(Decoder& decoder)
76
0
{
77
0
    auto nanoseconds = TRY(decoder.decode<i64>());
78
0
    return AK::UnixDateTime::from_nanoseconds_since_epoch(nanoseconds);
79
0
}
80
81
template<>
82
ErrorOr<URL::URL> decode(Decoder& decoder)
83
0
{
84
0
    auto url_string = TRY(decoder.decode<ByteString>());
85
0
    URL::URL url { url_string };
86
87
0
    bool has_blob_url = TRY(decoder.decode<bool>());
88
0
    if (!has_blob_url)
89
0
        return url;
90
91
0
    url.set_blob_url_entry(URL::BlobURLEntry {
92
0
        .type = TRY(decoder.decode<String>()),
93
0
        .byte_buffer = TRY(decoder.decode<ByteBuffer>()),
94
0
        .environment_origin = TRY(decoder.decode<URL::Origin>()),
95
0
    });
96
97
0
    return url;
98
0
}
99
100
template<>
101
ErrorOr<URL::Origin> decode(Decoder& decoder)
102
0
{
103
0
    auto scheme = TRY(decoder.decode<ByteString>());
104
0
    auto host = TRY(decoder.decode<URL::Host>());
105
0
    auto port = TRY(decoder.decode<Optional<u16>>());
106
107
0
    return URL::Origin { move(scheme), move(host), port };
108
0
}
109
110
template<>
111
ErrorOr<File> decode(Decoder& decoder)
112
0
{
113
0
    auto file = TRY(decoder.files().try_dequeue());
114
0
    auto fd = file.fd();
115
116
0
    auto fd_flags = TRY(Core::System::fcntl(fd, F_GETFD));
117
0
    TRY(Core::System::fcntl(fd, F_SETFD, fd_flags | FD_CLOEXEC));
118
0
    return file;
119
0
}
120
121
template<>
122
ErrorOr<Empty> decode(Decoder&)
123
0
{
124
0
    return Empty {};
125
0
}
126
127
template<>
128
ErrorOr<Core::AnonymousBuffer> decode(Decoder& decoder)
129
0
{
130
0
    if (auto valid = TRY(decoder.decode<bool>()); !valid)
131
0
        return Core::AnonymousBuffer {};
132
133
0
    auto size = TRY(decoder.decode_size());
134
0
    auto anon_file = TRY(decoder.decode<IPC::File>());
135
136
0
    return Core::AnonymousBuffer::create_from_anon_fd(anon_file.take_fd(), size);
137
0
}
138
139
template<>
140
ErrorOr<Core::DateTime> decode(Decoder& decoder)
141
0
{
142
0
    auto timestamp = TRY(decoder.decode<i64>());
143
0
    return Core::DateTime::from_timestamp(static_cast<time_t>(timestamp));
144
0
}
145
146
template<>
147
ErrorOr<Core::ProxyData> decode(Decoder& decoder)
148
0
{
149
0
    auto type = TRY(decoder.decode<Core::ProxyData::Type>());
150
0
    auto host_ipv4 = TRY(decoder.decode<u32>());
151
0
    auto port = TRY(decoder.decode<int>());
152
153
0
    return Core::ProxyData { type, host_ipv4, port };
154
0
}
155
156
}