1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 09:08:12 +00:00

Everywhere: Explicitly specify the size in StringView constructors

This commit moves the length calculations out to be directly on the
StringView users. This is an important step towards the goal of removing
StringView(char const*), as it moves the responsibility of calculating
the size of the string to the user of the StringView (which will prevent
naive uses causing OOB access).
This commit is contained in:
sin-ack 2022-07-11 19:53:29 +00:00 committed by Andreas Kling
parent e3da0adfe6
commit c70f45ff44
75 changed files with 264 additions and 203 deletions

View file

@ -18,7 +18,7 @@ inline String demangle(StringView name)
{ {
int status = 0; int status = 0;
auto* demangled_name = abi::__cxa_demangle(name.to_string().characters(), nullptr, nullptr, &status); auto* demangled_name = abi::__cxa_demangle(name.to_string().characters(), nullptr, nullptr, &status);
auto string = String(status == 0 ? demangled_name : name); auto string = String(status == 0 ? StringView { demangled_name, strlen(demangled_name) } : name);
if (status == 0) if (status == 0)
free(demangled_name); free(demangled_name);
return string; return string;

View file

@ -92,7 +92,7 @@ public:
constexpr bool consume_specific(char const* next) constexpr bool consume_specific(char const* next)
{ {
return consume_specific(StringView { next }); return consume_specific(StringView { next, __builtin_strlen(next) });
} }
constexpr char consume_escaped_character(char escape_char = '\\', StringView escape_map = "n\nr\rt\tb\bf\f") constexpr char consume_escaped_character(char escape_char = '\\', StringView escape_map = "n\nr\rt\tb\bf\f")

View file

@ -89,11 +89,11 @@ public:
TRY(begin_item(key)); TRY(begin_item(key));
if constexpr (IsLegacyBuilder<Builder>) { if constexpr (IsLegacyBuilder<Builder>) {
TRY(m_builder.try_append('"')); TRY(m_builder.try_append('"'));
TRY(m_builder.try_append_escaped_for_json(value)); TRY(m_builder.try_append_escaped_for_json({ value, strlen(value) }));
TRY(m_builder.try_append('"')); TRY(m_builder.try_append('"'));
} else { } else {
TRY(m_builder.append('"')); TRY(m_builder.append('"'));
TRY(m_builder.append_escaped_for_json(value)); TRY(m_builder.append_escaped_for_json({ value, strlen(value) }));
TRY(m_builder.append('"')); TRY(m_builder.append('"'));
} }
return {}; return {};

View file

@ -15,8 +15,8 @@ namespace AK {
class SourceLocation { class SourceLocation {
public: public:
[[nodiscard]] constexpr StringView function_name() const { return StringView(m_function); } [[nodiscard]] constexpr StringView function_name() const { return { m_function, __builtin_strlen(m_function) }; }
[[nodiscard]] constexpr StringView filename() const { return StringView(m_file); } [[nodiscard]] constexpr StringView filename() const { return { m_file, __builtin_strlen(m_file) }; }
[[nodiscard]] constexpr u32 line_number() const { return m_line; } [[nodiscard]] constexpr u32 line_number() const { return m_line; }
[[nodiscard]] static constexpr SourceLocation current(char const* const file = __builtin_FILE(), u32 line = __builtin_LINE(), char const* const function = __builtin_FUNCTION()) [[nodiscard]] static constexpr SourceLocation current(char const* const file = __builtin_FILE(), u32 line = __builtin_LINE(), char const* const function = __builtin_FUNCTION())

View file

@ -710,7 +710,7 @@ UNMAP_AFTER_INIT void Processor::detect_hypervisor_hyperv(CPUID const& hyperviso
alignas(sizeof(u32)) char interface_signature_buffer[5]; alignas(sizeof(u32)) char interface_signature_buffer[5];
*reinterpret_cast<u32*>(interface_signature_buffer) = hypervisor_interface.eax(); *reinterpret_cast<u32*>(interface_signature_buffer) = hypervisor_interface.eax();
interface_signature_buffer[4] = '\0'; interface_signature_buffer[4] = '\0';
StringView hyperv_interface_signature(interface_signature_buffer); StringView hyperv_interface_signature { interface_signature_buffer, strlen(interface_signature_buffer) };
dmesgln("CPU[{}]: Hyper-V interface signature '{}' ({:#x})", current_id(), hyperv_interface_signature, hypervisor_interface.eax()); dmesgln("CPU[{}]: Hyper-V interface signature '{}' ({:#x})", current_id(), hyperv_interface_signature, hypervisor_interface.eax());

View file

@ -41,7 +41,7 @@ CommandLine const& kernel_command_line()
UNMAP_AFTER_INIT void CommandLine::initialize() UNMAP_AFTER_INIT void CommandLine::initialize()
{ {
VERIFY(!s_the); VERIFY(!s_the);
s_the = new CommandLine(s_cmd_line); s_the = new CommandLine({ s_cmd_line, strlen(s_cmd_line) });
dmesgln("Kernel Commandline: {}", kernel_command_line().string()); dmesgln("Kernel Commandline: {}", kernel_command_line().string());
// Validate the modes the user passed in. // Validate the modes the user passed in.
(void)s_the->panic_mode(Validate::Yes); (void)s_the->panic_mode(Validate::Yes);

View file

@ -689,7 +689,7 @@ ErrorOr<void> IPv4Socket::ioctl(OpenFileDescription&, unsigned request, Userspac
memcpy(namebuf, ifr.ifr_name, IFNAMSIZ); memcpy(namebuf, ifr.ifr_name, IFNAMSIZ);
namebuf[sizeof(namebuf) - 1] = '\0'; namebuf[sizeof(namebuf) - 1] = '\0';
auto adapter = NetworkingManagement::the().lookup_by_name(namebuf); auto adapter = NetworkingManagement::the().lookup_by_name({ namebuf, strlen(namebuf) });
if (!adapter) if (!adapter)
return ENODEV; return ENODEV;

View file

@ -408,7 +408,7 @@ UNMAP_AFTER_INIT void setup_serial_debug()
// serial_debug will output all the dbgln() data to COM1 at // serial_debug will output all the dbgln() data to COM1 at
// 8-N-1 57600 baud. this is particularly useful for debugging the boot // 8-N-1 57600 baud. this is particularly useful for debugging the boot
// process on live hardware. // process on live hardware.
if (StringView(kernel_cmdline).contains("serial_debug")) { if (StringView { kernel_cmdline, strlen(kernel_cmdline) }.contains("serial_debug"sv)) {
set_serial_debug(true); set_serial_debug(true);
} }
} }

View file

@ -61,7 +61,7 @@ int main(int argc, char** argv)
.short_name = 'i', .short_name = 'i',
.value_name = "path", .value_name = "path",
.accept_value = [&](char const* s) { .accept_value = [&](char const* s) {
s_header_search_paths.append(s); s_header_search_paths.append({ s, strlen(s) });
return true; return true;
}, },
}); });

View file

@ -31,7 +31,7 @@ static StringView test_default_arg(SourceLocation const& loc = SourceLocation::c
TEST_CASE(default_arg_scenario) TEST_CASE(default_arg_scenario)
{ {
auto actual_calling_function = test_default_arg(); auto actual_calling_function = test_default_arg();
auto expected_calling_function = StringView(__FUNCTION__); auto expected_calling_function = StringView { __FUNCTION__, strlen(__FUNCTION__) };
EXPECT_EQ(expected_calling_function, actual_calling_function); EXPECT_EQ(expected_calling_function, actual_calling_function);
} }

View file

@ -20,7 +20,7 @@ TEST_CASE(construct_empty)
TEST_CASE(view_literal) TEST_CASE(view_literal)
{ {
char const* truth = "cats rule dogs drool"; char const* truth = "cats rule dogs drool";
StringView view(truth); StringView view { truth, strlen(truth) };
EXPECT_EQ(view.is_null(), false); EXPECT_EQ(view.is_null(), false);
EXPECT_EQ(view.characters_without_null_termination(), truth); EXPECT_EQ(view.characters_without_null_termination(), truth);
EXPECT_EQ(view, view); EXPECT_EQ(view, view);

View file

@ -51,33 +51,33 @@ TEST_CASE(decode_utf8)
TEST_CASE(validate_invalid_ut8) TEST_CASE(validate_invalid_ut8)
{ {
size_t valid_bytes; size_t valid_bytes;
char invalid_utf8_1[] = { 42, 35, (char)182, 9, 0 }; char invalid_utf8_1[] = { 42, 35, (char)182, 9 };
Utf8View utf8_1 { StringView { invalid_utf8_1 } }; Utf8View utf8_1 { StringView { invalid_utf8_1, 4 } };
EXPECT(!utf8_1.validate(valid_bytes)); EXPECT(!utf8_1.validate(valid_bytes));
EXPECT(valid_bytes == 2); EXPECT(valid_bytes == 2);
char invalid_utf8_2[] = { 42, 35, (char)208, (char)208, 0 }; char invalid_utf8_2[] = { 42, 35, (char)208, (char)208 };
Utf8View utf8_2 { StringView { invalid_utf8_2 } }; Utf8View utf8_2 { StringView { invalid_utf8_2, 4 } };
EXPECT(!utf8_2.validate(valid_bytes)); EXPECT(!utf8_2.validate(valid_bytes));
EXPECT(valid_bytes == 2); EXPECT(valid_bytes == 2);
char invalid_utf8_3[] = { (char)208, 0 }; char invalid_utf8_3[] = { (char)208 };
Utf8View utf8_3 { StringView { invalid_utf8_3 } }; Utf8View utf8_3 { StringView { invalid_utf8_3, 1 } };
EXPECT(!utf8_3.validate(valid_bytes)); EXPECT(!utf8_3.validate(valid_bytes));
EXPECT(valid_bytes == 0); EXPECT(valid_bytes == 0);
char invalid_utf8_4[] = { (char)208, 35, 0 }; char invalid_utf8_4[] = { (char)208, 35 };
Utf8View utf8_4 { StringView { invalid_utf8_4 } }; Utf8View utf8_4 { StringView { invalid_utf8_4, 2 } };
EXPECT(!utf8_4.validate(valid_bytes)); EXPECT(!utf8_4.validate(valid_bytes));
EXPECT(valid_bytes == 0); EXPECT(valid_bytes == 0);
char invalid_utf8_5[] = { (char)0xf4, (char)0x8f, (char)0xbf, (char)0xc0, 0 }; // U+110000 char invalid_utf8_5[] = { (char)0xf4, (char)0x8f, (char)0xbf, (char)0xc0 }; // U+110000
Utf8View utf8_5 { StringView { invalid_utf8_5 } }; Utf8View utf8_5 { StringView { invalid_utf8_5, 4 } };
EXPECT(!utf8_5.validate(valid_bytes)); EXPECT(!utf8_5.validate(valid_bytes));
EXPECT(valid_bytes == 0); EXPECT(valid_bytes == 0);
char invalid_utf8_6[] = { (char)0xf4, (char)0xa1, (char)0xb0, (char)0xbd, 0 }; // U+121c3d char invalid_utf8_6[] = { (char)0xf4, (char)0xa1, (char)0xb0, (char)0xbd }; // U+121c3d
Utf8View utf8_6 { StringView { invalid_utf8_6 } }; Utf8View utf8_6 { StringView { invalid_utf8_6, 4 } };
EXPECT(!utf8_6.validate(valid_bytes)); EXPECT(!utf8_6.validate(valid_bytes));
EXPECT(valid_bytes == 0); EXPECT(valid_bytes == 0);
} }
@ -122,8 +122,8 @@ TEST_CASE(decode_invalid_ut8)
{ {
// Test case 1 : Getting an extension byte as first byte of the code point // Test case 1 : Getting an extension byte as first byte of the code point
{ {
char raw_data[] = { 'a', 'b', (char)0xA0, 'd', 0 }; char raw_data[] = { 'a', 'b', (char)0xA0, 'd' };
Utf8View view { StringView { raw_data } }; Utf8View view { StringView { raw_data, 4 } };
u32 expected_characters[] = { 'a', 'b', 0xFFFD, 'd' }; u32 expected_characters[] = { 'a', 'b', 0xFFFD, 'd' };
String expected_underlying_bytes[] = { "a", "b", "\xA0", "d" }; String expected_underlying_bytes[] = { "a", "b", "\xA0", "d" };
size_t expected_size = sizeof(expected_characters) / sizeof(expected_characters[0]); size_t expected_size = sizeof(expected_characters) / sizeof(expected_characters[0]);
@ -140,8 +140,8 @@ TEST_CASE(decode_invalid_ut8)
// Test case 2 : Getting a non-extension byte when an extension byte is expected // Test case 2 : Getting a non-extension byte when an extension byte is expected
{ {
char raw_data[] = { 'a', 'b', (char)0xC0, 'd', 'e', 0 }; char raw_data[] = { 'a', 'b', (char)0xC0, 'd', 'e' };
Utf8View view { StringView { raw_data } }; Utf8View view { StringView { raw_data, 5 } };
u32 expected_characters[] = { 'a', 'b', 0xFFFD, 'd', 'e' }; u32 expected_characters[] = { 'a', 'b', 0xFFFD, 'd', 'e' };
String expected_underlying_bytes[] = { "a", "b", "\xC0", "d", "e" }; String expected_underlying_bytes[] = { "a", "b", "\xC0", "d", "e" };
size_t expected_size = sizeof(expected_characters) / sizeof(expected_characters[0]); size_t expected_size = sizeof(expected_characters) / sizeof(expected_characters[0]);
@ -158,8 +158,8 @@ TEST_CASE(decode_invalid_ut8)
// Test case 3 : Not enough bytes before the end of the string // Test case 3 : Not enough bytes before the end of the string
{ {
char raw_data[] = { 'a', 'b', (char)0x90, 'd', 0 }; char raw_data[] = { 'a', 'b', (char)0x90, 'd' };
Utf8View view { StringView { raw_data } }; Utf8View view { StringView { raw_data, 4 } };
u32 expected_characters[] = { 'a', 'b', 0xFFFD, 'd' }; u32 expected_characters[] = { 'a', 'b', 0xFFFD, 'd' };
String expected_underlying_bytes[] = { "a", "b", "\x90", "d" }; String expected_underlying_bytes[] = { "a", "b", "\x90", "d" };
size_t expected_size = sizeof(expected_characters) / sizeof(expected_characters[0]); size_t expected_size = sizeof(expected_characters) / sizeof(expected_characters[0]);
@ -176,8 +176,8 @@ TEST_CASE(decode_invalid_ut8)
// Test case 4 : Not enough bytes at the end of the string // Test case 4 : Not enough bytes at the end of the string
{ {
char raw_data[] = { 'a', 'b', 'c', (char)0x90, 0 }; char raw_data[] = { 'a', 'b', 'c', (char)0x90 };
Utf8View view { StringView { raw_data } }; Utf8View view { StringView { raw_data, 4 } };
u32 expected_characters[] = { 'a', 'b', 'c', 0xFFFD }; u32 expected_characters[] = { 'a', 'b', 'c', 0xFFFD };
String expected_underlying_bytes[] = { "a", "b", "c", "\x90" }; String expected_underlying_bytes[] = { "a", "b", "c", "\x90" };
size_t expected_size = sizeof(expected_characters) / sizeof(expected_characters[0]); size_t expected_size = sizeof(expected_characters) / sizeof(expected_characters[0]);

View file

@ -41,7 +41,7 @@ TEST_CASE(asctime)
time_t epoch = 0; time_t epoch = 0;
auto result = asctime(localtime(&epoch)); auto result = asctime(localtime(&epoch));
EXPECT_EQ(expected_epoch, StringView(result)); EXPECT_EQ(expected_epoch, StringView(result, strlen(result)));
} }
TEST_CASE(asctime_r) TEST_CASE(asctime_r)
@ -51,7 +51,7 @@ TEST_CASE(asctime_r)
char buffer[26] {}; char buffer[26] {};
time_t epoch = 0; time_t epoch = 0;
auto result = asctime_r(localtime(&epoch), buffer); auto result = asctime_r(localtime(&epoch), buffer);
EXPECT_EQ(expected_epoch, StringView(result)); EXPECT_EQ(expected_epoch, StringView(result, strlen(result)));
} }
TEST_CASE(ctime) TEST_CASE(ctime)
@ -61,7 +61,7 @@ TEST_CASE(ctime)
time_t epoch = 0; time_t epoch = 0;
auto result = ctime(&epoch); auto result = ctime(&epoch);
EXPECT_EQ(expected_epoch, StringView(result)); EXPECT_EQ(expected_epoch, StringView(result, strlen(result)));
} }
TEST_CASE(ctime_r) TEST_CASE(ctime_r)
@ -72,7 +72,7 @@ TEST_CASE(ctime_r)
time_t epoch = 0; time_t epoch = 0;
auto result = ctime_r(&epoch, buffer); auto result = ctime_r(&epoch, buffer);
EXPECT_EQ(expected_epoch, StringView(result)); EXPECT_EQ(expected_epoch, StringView(result, strlen(result)));
} }
TEST_CASE(tzset) TEST_CASE(tzset)

View file

@ -47,7 +47,7 @@ TEST_CASE(overlong_realpath)
// Then, create a long path. // Then, create a long path.
StringBuilder expected; StringBuilder expected;
expected.append(tmp_dir); expected.append({ tmp_dir, strlen(tmp_dir) });
// But first, demonstrate the functionality at a reasonable depth: // But first, demonstrate the functionality at a reasonable depth:
auto expected_str = expected.build(); auto expected_str = expected.build();
@ -63,7 +63,7 @@ TEST_CASE(overlong_realpath)
return; return;
} }
expected.append('/'); expected.append('/');
expected.append(PATH_LOREM_250); expected.append({ PATH_LOREM_250, strlen(PATH_LOREM_250) });
ret = chdir(PATH_LOREM_250); ret = chdir(PATH_LOREM_250);
if (ret < 0) { if (ret < 0) {
perror("chdir iter"); perror("chdir iter");

View file

@ -17,7 +17,7 @@
using namespace Help; using namespace Help;
static String parse_input(char const* input) static String parse_input(StringView input)
{ {
AK::URL url(input); AK::URL url(input);
if (url.is_valid()) if (url.is_valid())
@ -50,9 +50,10 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
.name = "section", .name = "section",
.min_values = 0, .min_values = 0,
.max_values = 1, .max_values = 1,
.accept_value = [&](char const* input) { .accept_value = [&](char const* input_ptr) {
StringView input { input_ptr, strlen(input_ptr) };
// If it's a number, use it as the section // If it's a number, use it as the section
if (auto number = StringView(input).to_int(); number.has_value()) { if (auto number = input.to_int(); number.has_value()) {
section = number.value(); section = number.value();
return true; return true;
} }
@ -66,7 +67,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
.name = "page", .name = "page",
.min_values = 0, .min_values = 0,
.max_values = 1, .max_values = 1,
.accept_value = [&](char const* input) { .accept_value = [&](char const* input_ptr) {
StringView input { input_ptr, strlen(input_ptr) };
// If start_page was already set by our section arg, then it can't be set again // If start_page was already set by our section arg, then it can't be set again
if (start_page.is_empty()) if (start_page.is_empty())
return false; return false;

View file

@ -259,7 +259,8 @@ static void analyze(RefPtr<Tree> tree, SpaceAnalyzer::TreeMapWidget& treemapwidg
if (!first) { if (!first) {
builder.append(", "); builder.append(", ");
} }
builder.append(strerror(key)); auto const* error = strerror(key);
builder.append({ error, strlen(error) });
builder.append(" ("); builder.append(" (");
int value = error_accumulator.get(key).value(); int value = error_accumulator.get(key).value();
builder.append(String::number(value)); builder.append(String::number(value));

View file

@ -280,9 +280,11 @@ Result<void, String> ExportDialog::make_and_run_for(StringView mime, Core::File&
bool result = file.write(file_content); bool result = file.write(file_content);
if (!result) { if (!result) {
int error_number = errno; int error_number = errno;
auto const* error = strerror(error_number);
StringBuilder sb; StringBuilder sb;
sb.append("Unable to save file. Error: "); sb.append("Unable to save file. Error: ");
sb.append(strerror(error_number)); sb.append({ error, strlen(error) });
return sb.to_string(); return sb.to_string();
} }

View file

@ -121,7 +121,11 @@ static void notify_make_not_available()
static void update_path_environment_variable() static void update_path_environment_variable()
{ {
StringBuilder path; StringBuilder path;
path.append(getenv("PATH"));
auto const* path_env_ptr = getenv("PATH");
if (path_env_ptr != NULL)
path.append({ path_env_ptr, strlen(path_env_ptr) });
if (path.length()) if (path.length())
path.append(":"); path.append(":");
path.append("/usr/local/sbin:/usr/local/bin:/usr/bin:/bin"); path.append("/usr/local/sbin:/usr/local/bin:/usr/bin:/bin");

View file

@ -99,7 +99,7 @@ public:
time_t timestamp() const { return get_field_as_integral(m_timestamp); } time_t timestamp() const { return get_field_as_integral(m_timestamp); }
unsigned checksum() const { return get_field_as_integral(m_checksum); } unsigned checksum() const { return get_field_as_integral(m_checksum); }
TarFileType type_flag() const { return TarFileType(m_type_flag); } TarFileType type_flag() const { return TarFileType(m_type_flag); }
StringView link_name() const { return m_link_name; } StringView link_name() const { return { m_link_name, strlen(m_link_name) }; }
StringView magic() const { return get_field_as_string_view(m_magic); } StringView magic() const { return get_field_as_string_view(m_magic); }
StringView version() const { return get_field_as_string_view(m_version); } StringView version() const { return get_field_as_string_view(m_version); }
StringView owner_name() const { return get_field_as_string_view(m_owner_name); } StringView owner_name() const { return get_field_as_string_view(m_owner_name); }

View file

@ -64,7 +64,7 @@ int inet_pton(int af, char const* src, void* dst)
*(uint32_t*)dst = u.l; *(uint32_t*)dst = u.l;
return 1; return 1;
} else if (af == AF_INET6) { } else if (af == AF_INET6) {
auto addr = IPv6Address::from_string(src); auto addr = IPv6Address::from_string({ src, strlen(src) });
if (!addr.has_value()) { if (!addr.has_value()) {
errno = EINVAL; errno = EINVAL;
return 0; return 0;

View file

@ -214,11 +214,11 @@ int OptionParser::handle_short_option()
option const* OptionParser::lookup_long_option(char* raw) const option const* OptionParser::lookup_long_option(char* raw) const
{ {
StringView arg = raw; StringView arg { raw, strlen(raw) };
for (size_t index = 0; m_long_options[index].name; index++) { for (size_t index = 0; m_long_options[index].name; index++) {
auto& option = m_long_options[index]; auto& option = m_long_options[index];
StringView name = option.name; StringView name { option.name, strlen(option.name) };
if (!arg.starts_with(name)) if (!arg.starts_with(name))
continue; continue;
@ -347,12 +347,12 @@ bool OptionParser::find_next_option()
int getopt(int argc, char* const* argv, char const* short_options) int getopt(int argc, char* const* argv, char const* short_options)
{ {
option dummy { nullptr, 0, nullptr, 0 }; option dummy { nullptr, 0, nullptr, 0 };
OptionParser parser { argc, argv, short_options, &dummy }; OptionParser parser { argc, argv, { short_options, strlen(short_options) }, &dummy };
return parser.getopt(); return parser.getopt();
} }
int getopt_long(int argc, char* const* argv, char const* short_options, const struct option* long_options, int* out_long_option_index) int getopt_long(int argc, char* const* argv, char const* short_options, const struct option* long_options, int* out_long_option_index)
{ {
OptionParser parser { argc, argv, short_options, long_options, out_long_option_index }; OptionParser parser { argc, argv, { short_options, strlen(short_options) }, long_options, out_long_option_index };
return parser.getopt(); return parser.getopt();
} }

View file

@ -16,7 +16,8 @@ int getsubopt(char** option_array, char* const* tokens, char** option_value)
if (**option_array == '\0') if (**option_array == '\0')
return -1; return -1;
auto option_string = StringView(*option_array); auto const* option_ptr = *option_array;
StringView option_string { option_ptr, strlen(option_ptr) };
auto possible_comma_location = option_string.find(','); auto possible_comma_location = option_string.find(',');
char* option_end = const_cast<char*>(option_string.characters_without_null_termination()) + possible_comma_location.value_or(option_string.length()); char* option_end = const_cast<char*>(option_string.characters_without_null_termination()) + possible_comma_location.value_or(option_string.length());
@ -34,7 +35,8 @@ int getsubopt(char** option_array, char* const* tokens, char** option_value)
}); });
for (int count = 0; tokens[count] != NULL; ++count) { for (int count = 0; tokens[count] != NULL; ++count) {
auto token_stringview = StringView(tokens[count]); auto const* token = tokens[count];
StringView token_stringview { token, strlen(token) };
if (!option_string.starts_with(token_stringview)) if (!option_string.starts_with(token_stringview))
continue; continue;
if (tokens[count][value_start - *option_array] != '\0') if (tokens[count][value_start - *option_array] != '\0')

View file

@ -93,7 +93,7 @@ hostent* gethostbyname(char const* name)
{ {
h_errno = 0; h_errno = 0;
auto ipv4_address = IPv4Address::from_string(name); auto ipv4_address = IPv4Address::from_string({ name, strlen(name) });
if (ipv4_address.has_value()) { if (ipv4_address.has_value()) {
gethostbyname_name_buffer = ipv4_address.value().to_string(); gethostbyname_name_buffer = ipv4_address.value().to_string();

View file

@ -386,8 +386,8 @@ private:
extern "C" int vsscanf(char const* input, char const* format, va_list ap) extern "C" int vsscanf(char const* input, char const* format, va_list ap)
{ {
GenericLexer format_lexer { format }; GenericLexer format_lexer { { format, strlen(format) } };
GenericLexer input_lexer { input }; GenericLexer input_lexer { { input, strlen(input) } };
int elements_matched = 0; int elements_matched = 0;

View file

@ -243,10 +243,10 @@ static_assert(sizeof(sys_signame) == sizeof(char const*) * NSIG);
int getsignalbyname(char const* name) int getsignalbyname(char const* name)
{ {
VERIFY(name); VERIFY(name);
StringView name_sv(name); StringView name_sv { name, strlen(name) };
for (size_t i = 0; i < NSIG; ++i) { for (size_t i = 0; i < NSIG; ++i) {
auto signal_name = StringView(sys_signame[i]); StringView signal_name { sys_signame[i], sizeof(sys_signame[i]) - 1 };
if (signal_name == name_sv || (name_sv.starts_with("SIG") && signal_name == name_sv.substring_view(3))) if (signal_name == name_sv || (name_sv.starts_with("SIG"sv) && signal_name == name_sv.substring_view(3)))
return i; return i;
} }
errno = EINVAL; errno = EINVAL;

View file

@ -114,7 +114,7 @@ int __attribute__((weak)) tgetnum(char const* id)
static Vector<char> s_tgoto_buffer; static Vector<char> s_tgoto_buffer;
char* __attribute__((weak)) tgoto([[maybe_unused]] char const* cap, [[maybe_unused]] int col, [[maybe_unused]] int row) char* __attribute__((weak)) tgoto([[maybe_unused]] char const* cap, [[maybe_unused]] int col, [[maybe_unused]] int row)
{ {
auto cap_str = StringView(cap).replace("%p1%d", String::number(col), ReplaceMode::FirstOnly).replace("%p2%d", String::number(row), ReplaceMode::FirstOnly); auto cap_str = StringView { cap, strlen(cap) }.replace("%p1%d"sv, String::number(col), ReplaceMode::FirstOnly).replace("%p2%d"sv, String::number(row), ReplaceMode::FirstOnly);
s_tgoto_buffer.clear_with_capacity(); s_tgoto_buffer.clear_with_capacity();
s_tgoto_buffer.ensure_capacity(cap_str.length()); s_tgoto_buffer.ensure_capacity(cap_str.length());

View file

@ -377,7 +377,7 @@ void tzset()
StringView time_zone; StringView time_zone;
if (char* tz = getenv("TZ"); tz != nullptr) if (char* tz = getenv("TZ"); tz != nullptr)
time_zone = tz; time_zone = { tz, strlen(tz) };
else else
time_zone = TimeZone::system_time_zone(); time_zone = TimeZone::system_time_zone();

View file

@ -40,7 +40,7 @@ static String get_salt()
static Vector<gid_t> get_extra_gids(passwd const& pwd) static Vector<gid_t> get_extra_gids(passwd const& pwd)
{ {
StringView username { pwd.pw_name }; StringView username { pwd.pw_name, strlen(pwd.pw_name) };
Vector<gid_t> extra_gids; Vector<gid_t> extra_gids;
setgrent(); setgrent();
for (auto* group = getgrent(); group; group = getgrent()) { for (auto* group = getgrent(); group; group = getgrent()) {
@ -78,7 +78,7 @@ ErrorOr<Account> Account::self([[maybe_unused]] Read options)
spwd spwd = {}; spwd spwd = {};
#ifndef AK_OS_BSD_GENERIC #ifndef AK_OS_BSD_GENERIC
if (options != Read::PasswdOnly) { if (options != Read::PasswdOnly) {
auto maybe_spwd = TRY(Core::System::getspnam(pwd->pw_name)); auto maybe_spwd = TRY(Core::System::getspnam({ pwd->pw_name, strlen(pwd->pw_name) }));
if (!maybe_spwd.has_value()) if (!maybe_spwd.has_value())
return Error::from_string_literal("No shadow entry for user"sv); return Error::from_string_literal("No shadow entry for user"sv);
spwd = maybe_spwd.release_value(); spwd = maybe_spwd.release_value();
@ -90,14 +90,14 @@ ErrorOr<Account> Account::self([[maybe_unused]] Read options)
ErrorOr<Account> Account::from_name(char const* username, [[maybe_unused]] Read options) ErrorOr<Account> Account::from_name(char const* username, [[maybe_unused]] Read options)
{ {
auto pwd = TRY(Core::System::getpwnam(username)); auto pwd = TRY(Core::System::getpwnam({ username, strlen(username) }));
if (!pwd.has_value()) if (!pwd.has_value())
return Error::from_string_literal("No such user"sv); return Error::from_string_literal("No such user"sv);
spwd spwd = {}; spwd spwd = {};
#ifndef AK_OS_BSD_GENERIC #ifndef AK_OS_BSD_GENERIC
if (options != Read::PasswdOnly) { if (options != Read::PasswdOnly) {
auto maybe_spwd = TRY(Core::System::getspnam(pwd->pw_name)); auto maybe_spwd = TRY(Core::System::getspnam({ pwd->pw_name, strlen(pwd->pw_name) }));
if (!maybe_spwd.has_value()) if (!maybe_spwd.has_value())
return Error::from_string_literal("No shadow entry for user"sv); return Error::from_string_literal("No shadow entry for user"sv);
spwd = maybe_spwd.release_value(); spwd = maybe_spwd.release_value();
@ -115,7 +115,7 @@ ErrorOr<Account> Account::from_uid(uid_t uid, [[maybe_unused]] Read options)
spwd spwd = {}; spwd spwd = {};
#ifndef AK_OS_BSD_GENERIC #ifndef AK_OS_BSD_GENERIC
if (options != Read::PasswdOnly) { if (options != Read::PasswdOnly) {
auto maybe_spwd = TRY(Core::System::getspnam(pwd->pw_name)); auto maybe_spwd = TRY(Core::System::getspnam({ pwd->pw_name, strlen(pwd->pw_name) }));
if (!maybe_spwd.has_value()) if (!maybe_spwd.has_value())
return Error::from_string_literal("No shadow entry for user"sv); return Error::from_string_literal("No shadow entry for user"sv);
spwd = maybe_spwd.release_value(); spwd = maybe_spwd.release_value();
@ -270,18 +270,22 @@ ErrorOr<void> Account::sync()
auto new_shadow_file_content = TRY(generate_shadow_file()); auto new_shadow_file_content = TRY(generate_shadow_file());
#endif #endif
// FIXME: mkstemp taking Span<char> makes this code entirely un-AKable.
// Make this code less char-pointery.
char new_passwd_name[] = "/etc/passwd.XXXXXX"; char new_passwd_name[] = "/etc/passwd.XXXXXX";
size_t new_passwd_name_length = strlen(new_passwd_name);
#ifndef AK_OS_BSD_GENERIC #ifndef AK_OS_BSD_GENERIC
char new_shadow_name[] = "/etc/shadow.XXXXXX"; char new_shadow_name[] = "/etc/shadow.XXXXXX";
size_t new_shadow_name_length = strlen(new_shadow_name);
#endif #endif
{ {
auto new_passwd_fd = TRY(Core::System::mkstemp(new_passwd_name)); auto new_passwd_fd = TRY(Core::System::mkstemp({ new_passwd_name, new_passwd_name_length }));
ScopeGuard new_passwd_fd_guard = [new_passwd_fd] { close(new_passwd_fd); }; ScopeGuard new_passwd_fd_guard = [new_passwd_fd] { close(new_passwd_fd); };
TRY(Core::System::fchmod(new_passwd_fd, 0644)); TRY(Core::System::fchmod(new_passwd_fd, 0644));
#ifndef AK_OS_BSD_GENERIC #ifndef AK_OS_BSD_GENERIC
auto new_shadow_fd = TRY(Core::System::mkstemp(new_shadow_name)); auto new_shadow_fd = TRY(Core::System::mkstemp({ new_shadow_name, new_shadow_name_length }));
ScopeGuard new_shadow_fd_guard = [new_shadow_fd] { close(new_shadow_fd); }; ScopeGuard new_shadow_fd_guard = [new_shadow_fd] { close(new_shadow_fd); };
TRY(Core::System::fchmod(new_shadow_fd, 0600)); TRY(Core::System::fchmod(new_shadow_fd, 0600));
#endif #endif
@ -295,9 +299,9 @@ ErrorOr<void> Account::sync()
#endif #endif
} }
TRY(Core::System::rename(new_passwd_name, "/etc/passwd")); TRY(Core::System::rename({ new_passwd_name, new_passwd_name_length }, "/etc/passwd"sv));
#ifndef AK_OS_BSD_GENERIC #ifndef AK_OS_BSD_GENERIC
TRY(Core::System::rename(new_shadow_name, "/etc/shadow")); TRY(Core::System::rename({ new_shadow_name, new_shadow_name_length }, "/etc/shadow"sv));
#endif #endif
return {}; return {};

View file

@ -129,7 +129,7 @@ bool ArgsParser::parse(int argc, char* const* argv, FailureBehavior failure_beha
} }
if (m_perform_autocomplete) { if (m_perform_autocomplete) {
autocomplete(stdout, argv[0], Span<char const* const> { argv + optind, static_cast<size_t>(argc - optind) }); autocomplete(stdout, { argv[0], strlen(argv[0]) }, Span<char const* const> { argv + optind, static_cast<size_t>(argc - optind) });
if (failure_behavior == FailureBehavior::Exit || failure_behavior == FailureBehavior::PrintUsageAndExit) if (failure_behavior == FailureBehavior::Exit || failure_behavior == FailureBehavior::PrintUsageAndExit)
exit(0); exit(0);
return false; return false;
@ -445,7 +445,7 @@ void ArgsParser::add_option(StringView& value, char const* help_string, char con
short_name, short_name,
value_name, value_name,
[&value](char const* s) { [&value](char const* s) {
value = s; value = { s, strlen(s) };
return true; return true;
}, },
hide_mode, hide_mode,
@ -462,7 +462,7 @@ void ArgsParser::add_option(int& value, char const* help_string, char const* lon
short_name, short_name,
value_name, value_name,
[&value](char const* s) { [&value](char const* s) {
auto opt = StringView(s).to_int(); auto opt = StringView { s, strlen(s) }.to_int();
value = opt.value_or(0); value = opt.value_or(0);
return opt.has_value(); return opt.has_value();
}, },
@ -480,7 +480,7 @@ void ArgsParser::add_option(unsigned& value, char const* help_string, char const
short_name, short_name,
value_name, value_name,
[&value](char const* s) { [&value](char const* s) {
auto opt = StringView(s).to_uint(); auto opt = StringView { s, strlen(s) }.to_uint();
value = opt.value_or(0); value = opt.value_or(0);
return opt.has_value(); return opt.has_value();
}, },
@ -533,7 +533,7 @@ void ArgsParser::add_option(Optional<size_t>& value, char const* help_string, ch
short_name, short_name,
value_name, value_name,
[&value](char const* s) { [&value](char const* s) {
value = AK::StringUtils::convert_to_uint<size_t>(s); value = AK::StringUtils::convert_to_uint<size_t>({ s, strlen(s) });
return value.has_value(); return value.has_value();
}, },
hide_mode, hide_mode,
@ -552,7 +552,7 @@ void ArgsParser::add_option(Vector<size_t>& values, char const* help_string, cha
[&values, separator](char const* s) { [&values, separator](char const* s) {
bool parsed_all_values = true; bool parsed_all_values = true;
StringView { s }.for_each_split_view(separator, false, [&](auto value) { StringView { s, strlen(s) }.for_each_split_view(separator, false, [&](auto value) {
if (auto maybe_value = AK::StringUtils::convert_to_uint<size_t>(value); maybe_value.has_value()) if (auto maybe_value = AK::StringUtils::convert_to_uint<size_t>(value); maybe_value.has_value())
values.append(*maybe_value); values.append(*maybe_value);
else else
@ -610,7 +610,7 @@ void ArgsParser::add_positional_argument(StringView& value, char const* help_str
required == Required::Yes ? 1 : 0, required == Required::Yes ? 1 : 0,
1, 1,
[&value](char const* s) { [&value](char const* s) {
value = s; value = { s, strlen(s) };
return true; return true;
} }
}; };
@ -625,7 +625,7 @@ void ArgsParser::add_positional_argument(int& value, char const* help_string, ch
required == Required::Yes ? 1 : 0, required == Required::Yes ? 1 : 0,
1, 1,
[&value](char const* s) { [&value](char const* s) {
auto opt = StringView(s).to_int(); auto opt = StringView { s, strlen(s) }.to_int();
value = opt.value_or(0); value = opt.value_or(0);
return opt.has_value(); return opt.has_value();
} }
@ -641,7 +641,7 @@ void ArgsParser::add_positional_argument(unsigned& value, char const* help_strin
required == Required::Yes ? 1 : 0, required == Required::Yes ? 1 : 0,
1, 1,
[&value](char const* s) { [&value](char const* s) {
auto opt = StringView(s).to_uint(); auto opt = StringView { s, strlen(s) }.to_uint();
value = opt.value_or(0); value = opt.value_or(0);
return opt.has_value(); return opt.has_value();
} }
@ -703,7 +703,7 @@ void ArgsParser::add_positional_argument(Vector<StringView>& values, char const*
required == Required::Yes ? 1 : 0, required == Required::Yes ? 1 : 0,
INT_MAX, INT_MAX,
[&values](char const* s) { [&values](char const* s) {
values.append(s); values.append({ s, strlen(s) });
return true; return true;
} }
}; };
@ -723,7 +723,7 @@ void ArgsParser::autocomplete(FILE* file, StringView program_name, Span<char con
auto completing_option = false; auto completing_option = false;
for (auto& arg : remaining_arguments) { for (auto& arg : remaining_arguments) {
StringView argument { arg }; StringView argument { arg, strlen(arg) };
completing_option = false; completing_option = false;
if (skip_next) { if (skip_next) {
@ -754,7 +754,7 @@ void ArgsParser::autocomplete(FILE* file, StringView program_name, Span<char con
// Look for a long option // Look for a long option
auto option_pattern = argument.substring_view(2); auto option_pattern = argument.substring_view(2);
auto it = m_options.find_if([&](auto& option) { return option.hide_mode != OptionHideMode::None && StringView(option.long_name) == option_pattern; }); auto it = m_options.find_if([&](auto& option) { return option.hide_mode != OptionHideMode::None && StringView { option.long_name, strlen(option.long_name) } == option_pattern; });
if (it.is_end()) if (it.is_end())
continue; continue;
@ -791,7 +791,7 @@ void ArgsParser::autocomplete(FILE* file, StringView program_name, Span<char con
auto write_completion = [&](auto format, auto& option, auto has_invariant, auto... args) { auto write_completion = [&](auto format, auto& option, auto has_invariant, auto... args) {
JsonObject object; JsonObject object;
object.set("completion", String::formatted(format, args...)); object.set("completion", String::formatted(StringView { format, strlen(format) }, args...));
object.set("static_offset", 0); object.set("static_offset", 0);
object.set("invariant_offset", has_invariant ? option_to_complete.length() : 0u); object.set("invariant_offset", has_invariant ? option_to_complete.length() : 0u);
object.set("display_trivia", option.help_string); object.set("display_trivia", option.help_string);
@ -805,7 +805,7 @@ void ArgsParser::autocomplete(FILE* file, StringView program_name, Span<char con
for (auto& option : m_options) { for (auto& option : m_options) {
if (option.hide_mode != OptionHideMode::None) if (option.hide_mode != OptionHideMode::None)
continue; continue;
StringView option_string = option.long_name; StringView option_string { option.long_name, strlen(option.long_name) };
if (option_string.starts_with(option_pattern)) { if (option_string.starts_with(option_pattern)) {
write_completion("--{}", option, true, option_string); write_completion("--{}", option, true, option_string);
} }

View file

@ -250,9 +250,11 @@ String DateTime::to_string(StringView format) const
} }
format_time_zone_offset(true); format_time_zone_offset(true);
break; break;
case 'Z': case 'Z': {
builder.append(tzname[daylight]); auto const* timezone_name = tzname[daylight];
builder.append({ timezone_name, strlen(timezone_name) });
break; break;
}
case '%': case '%':
builder.append('%'); builder.append('%');
break; break;

View file

@ -83,7 +83,7 @@ static String canonicalize_path(String path)
return LexicalPath::canonicalized_path(move(path)); return LexicalPath::canonicalized_path(move(path));
char* cwd = getcwd(nullptr, 0); char* cwd = getcwd(nullptr, 0);
VERIFY(cwd); VERIFY(cwd);
return LexicalPath::join(cwd, move(path)).string(); return LexicalPath::join({ cwd, strlen(cwd) }, move(path)).string();
} }
ErrorOr<bool> FileWatcherBase::add_watch(String path, FileWatcherEvent::Type event_mask) ErrorOr<bool> FileWatcherBase::add_watch(String path, FileWatcherEvent::Type event_mask)

View file

@ -970,7 +970,8 @@ ErrorOr<void> exec(StringView filename, Span<StringView> arguments, SearchInPath
}; };
if (search_in_path == SearchInPath::Yes && !filename.contains('/')) { if (search_in_path == SearchInPath::Yes && !filename.contains('/')) {
StringView path = getenv("PATH"); auto const* path_ptr = getenv("PATH");
StringView path { path_ptr, strlen(path_ptr) };
if (path.is_empty()) if (path.is_empty())
path = "/bin:/usr/bin"; path = "/bin:/usr/bin";
auto parts = path.split_view(':'); auto parts = path.split_view(':');

View file

@ -23,7 +23,7 @@ static void parse_sockets_from_system_server()
return; return;
} }
for (auto& socket : StringView(sockets).split_view(' ')) { for (auto& socket : StringView { sockets, strlen(sockets) }.split_view(' ')) {
auto params = socket.split_view(':'); auto params = socket.split_view(':');
s_overtaken_sockets.set(params[0].to_string(), strtol(params[1].to_string().characters(), nullptr, 10)); s_overtaken_sockets.set(params[0].to_string(), strtol(params[1].to_string().characters(), nullptr, 10));
} }

View file

@ -157,7 +157,8 @@ const JsonObject Reader::process_info() const
} }
if (!process_info_notes_entry) if (!process_info_notes_entry)
return {}; return {};
auto process_info_json_value = JsonValue::from_string(process_info_notes_entry->json_data); auto const* json_data_ptr = process_info_notes_entry->json_data;
auto process_info_json_value = JsonValue::from_string({ json_data_ptr, strlen(json_data_ptr) });
if (process_info_json_value.is_error()) if (process_info_json_value.is_error())
return {}; return {};
if (!process_info_json_value.value().is_object()) if (!process_info_json_value.value().is_object())
@ -256,7 +257,8 @@ HashMap<String, String> Reader::metadata() const
} }
if (!metadata_notes_entry) if (!metadata_notes_entry)
return {}; return {};
auto metadata_json_value = JsonValue::from_string(metadata_notes_entry->json_data); auto const* json_data_ptr = metadata_notes_entry->json_data;
auto metadata_json_value = JsonValue::from_string({ json_data_ptr, strlen(json_data_ptr) });
if (metadata_json_value.is_error()) if (metadata_json_value.is_error())
return {}; return {};
if (!metadata_json_value.value().is_object()) if (!metadata_json_value.value().is_object())

View file

@ -133,12 +133,13 @@ void Reader::for_each_memory_region_info(Func func) const
}; };
ByteReader::load(raw_data.data(), raw_memory_region_info); ByteReader::load(raw_data.data(), raw_memory_region_info);
auto const* region_name_ptr = bit_cast<char const*>(raw_data.offset_pointer(raw_data.size()));
MemoryRegionInfo memory_region_info { MemoryRegionInfo memory_region_info {
raw_memory_region_info.header, raw_memory_region_info.header,
raw_memory_region_info.region_start, raw_memory_region_info.region_start,
raw_memory_region_info.region_end, raw_memory_region_info.region_end,
raw_memory_region_info.program_header_index, raw_memory_region_info.program_header_index,
{ bit_cast<char const*>(raw_data.offset_pointer(raw_data.size())) }, { region_name_ptr, strlen(region_name_ptr) },
}; };
IterationDecision decision = func(memory_region_info); IterationDecision decision = func(memory_region_info);
if (decision == IterationDecision::Break) if (decision == IterationDecision::Break)

View file

@ -45,7 +45,7 @@ char* crypt_r(char const* key, char const* salt, struct crypt_data* data)
data->result[header_len] = '$'; data->result[header_len] = '$';
Crypto::Hash::SHA256 sha; Crypto::Hash::SHA256 sha;
sha.update(key); sha.update(StringView { key, strlen(key) });
sha.update((u8 const*)salt_value, salt_len); sha.update((u8 const*)salt_value, salt_len);
auto digest = sha.digest(); auto digest = sha.digest();

View file

@ -417,7 +417,7 @@ StringView Parser::version() const
StringView Parser::legacy_manufacturer_id() const StringView Parser::legacy_manufacturer_id() const
{ {
return m_legacy_manufacturer_id; return { m_legacy_manufacturer_id, strlen(m_legacy_manufacturer_id) };
} }
#ifndef KERNEL #ifndef KERNEL

View file

@ -487,19 +487,20 @@ static Result<void*, DlErrorMessage> __dlsym(void* handle, char const* symbol_na
__pthread_mutex_lock(&s_loader_lock); __pthread_mutex_lock(&s_loader_lock);
ScopeGuard unlock_guard = [] { __pthread_mutex_unlock(&s_loader_lock); }; ScopeGuard unlock_guard = [] { __pthread_mutex_unlock(&s_loader_lock); };
StringView symbol_name_view { symbol_name, strlen(symbol_name) };
Optional<DynamicObject::SymbolLookupResult> symbol; Optional<DynamicObject::SymbolLookupResult> symbol;
if (handle) { if (handle) {
auto object = static_cast<DynamicObject*>(handle); auto object = static_cast<DynamicObject*>(handle);
symbol = object->lookup_symbol(symbol_name); symbol = object->lookup_symbol(symbol_name_view);
} else { } else {
// When handle is 0 (RTLD_DEFAULT) we should look up the symbol in all global modules // When handle is 0 (RTLD_DEFAULT) we should look up the symbol in all global modules
// https://pubs.opengroup.org/onlinepubs/009604499/functions/dlsym.html // https://pubs.opengroup.org/onlinepubs/009604499/functions/dlsym.html
symbol = DynamicLinker::lookup_global_symbol(symbol_name); symbol = DynamicLinker::lookup_global_symbol(symbol_name_view);
} }
if (!symbol.has_value()) if (!symbol.has_value())
return DlErrorMessage { String::formatted("Symbol {} not found", symbol_name) }; return DlErrorMessage { String::formatted("Symbol {} not found", symbol_name_view) };
if (symbol.value().type == STT_GNU_IFUNC) if (symbol.value().type == STT_GNU_IFUNC)
return (void*)reinterpret_cast<DynamicObject::IfuncResolver>(symbol.value().address.as_ptr())(); return (void*)reinterpret_cast<DynamicObject::IfuncResolver>(symbol.value().address.as_ptr())();
@ -551,7 +552,7 @@ static Result<void, DlErrorMessage> __dladdr(void* addr, Dl_info* info)
static void read_environment_variables() static void read_environment_variables()
{ {
for (char** env = s_envp; *env; ++env) { for (char** env = s_envp; *env; ++env) {
StringView env_string { *env }; StringView env_string { *env, strlen(*env) };
if (env_string == "_LOADER_BREAKPOINT=1"sv) { if (env_string == "_LOADER_BREAKPOINT=1"sv) {
s_do_breakpoint_trap_before_entry = true; s_do_breakpoint_trap_before_entry = true;
} }

View file

@ -336,7 +336,8 @@ auto DynamicObject::HashSection::lookup_gnu_symbol(StringView name, u32 hash_val
StringView DynamicObject::symbol_string_table_string(ElfW(Word) index) const StringView DynamicObject::symbol_string_table_string(ElfW(Word) index) const
{ {
return StringView { (char const*)base_address().offset(m_string_table_offset + index).as_ptr() }; auto const* symbol_string_table_ptr = reinterpret_cast<char const*>(base_address().offset(m_string_table_offset + index).as_ptr());
return StringView { symbol_string_table_ptr, strlen(symbol_string_table_ptr) };
} }
char const* DynamicObject::raw_symbol_string_table_string(ElfW(Word) index) const char const* DynamicObject::raw_symbol_string_table_string(ElfW(Word) index) const

View file

@ -488,8 +488,7 @@ inline void DynamicObject::for_each_needed_library(F func) const
if (entry.tag() != DT_NEEDED) if (entry.tag() != DT_NEEDED)
return; return;
ElfW(Word) offset = entry.val(); ElfW(Word) offset = entry.val();
StringView name { (const char*)(m_base_address.offset(m_string_table_offset).offset(offset)).as_ptr() }; func(symbol_string_table_string(offset));
func(name);
}); });
} }

View file

@ -125,7 +125,7 @@ void Window::show()
Gfx::IntRect launch_origin_rect; Gfx::IntRect launch_origin_rect;
if (auto* launch_origin_rect_string = getenv("__libgui_launch_origin_rect")) { if (auto* launch_origin_rect_string = getenv("__libgui_launch_origin_rect")) {
auto parts = StringView(launch_origin_rect_string).split_view(','); auto parts = StringView { launch_origin_rect_string, strlen(launch_origin_rect_string) }.split_view(',');
if (parts.size() == 4) { if (parts.size() == 4) {
launch_origin_rect = Gfx::IntRect { launch_origin_rect = Gfx::IntRect {
parts[0].to_int().value_or(0), parts[0].to_int().value_or(0),

View file

@ -80,7 +80,7 @@ Optional<Color> Color::from_string(StringView string)
struct ColorAndWebName { struct ColorAndWebName {
constexpr ColorAndWebName(ARGB32 c, char const* n) constexpr ColorAndWebName(ARGB32 c, char const* n)
: color(c) : color(c)
, name(n) , name(n != nullptr ? StringView { n, __builtin_strlen(n) } : StringView {})
{ {
} }
ARGB32 color; ARGB32 color;

View file

@ -12,9 +12,10 @@
namespace Gfx { namespace Gfx {
struct FontStyleMapping { struct FontStyleMapping {
// NOTE: __builtin_strlen required to make this work at compile time.
constexpr FontStyleMapping(int s, char const* n) constexpr FontStyleMapping(int s, char const* n)
: style(s) : style(s)
, name(n) , name(StringView { n, __builtin_strlen(n) })
{ {
} }
int style { 0 }; int style { 0 };

View file

@ -135,7 +135,7 @@ Encoder& Encoder::operator<<(double value)
Encoder& Encoder::operator<<(char const* value) Encoder& Encoder::operator<<(char const* value)
{ {
return *this << StringView(value); return *this << StringView { value, strlen(value) };
} }
Encoder& Encoder::operator<<(StringView value) Encoder& Encoder::operator<<(StringView value)

View file

@ -64,7 +64,8 @@ private:
String ASTNode::class_name() const String ASTNode::class_name() const
{ {
// NOTE: We strip the "JS::" prefix. // NOTE: We strip the "JS::" prefix.
return demangle(typeid(*this).name()).substring(4); auto const* typename_ptr = typeid(*this).name();
return demangle({ typename_ptr, strlen(typename_ptr) }).substring(4);
} }
static void print_indent(int indent) static void print_indent(int indent)

View file

@ -15,12 +15,12 @@ namespace JS {
// U+2028 LINE SEPARATOR // U+2028 LINE SEPARATOR
constexpr char const line_separator_chars[] { (char)0xe2, (char)0x80, (char)0xa8, 0 }; constexpr char const line_separator_chars[] { (char)0xe2, (char)0x80, (char)0xa8, 0 };
constexpr const StringView LINE_SEPARATOR_STRING { line_separator_chars }; constexpr const StringView LINE_SEPARATOR_STRING { line_separator_chars, sizeof(line_separator_chars) - 1 };
constexpr const u32 LINE_SEPARATOR { 0x2028 }; constexpr const u32 LINE_SEPARATOR { 0x2028 };
// U+2029 PARAGRAPH SEPARATOR // U+2029 PARAGRAPH SEPARATOR
constexpr char const paragraph_separator_chars[] { (char)0xe2, (char)0x80, (char)0xa9, 0 }; constexpr char const paragraph_separator_chars[] { (char)0xe2, (char)0x80, (char)0xa9, 0 };
constexpr const StringView PARAGRAPH_SEPARATOR_STRING { paragraph_separator_chars }; constexpr const StringView PARAGRAPH_SEPARATOR_STRING { paragraph_separator_chars, sizeof(paragraph_separator_chars) - 1 };
constexpr const u32 PARAGRAPH_SEPARATOR { 0x2029 }; constexpr const u32 PARAGRAPH_SEPARATOR { 0x2029 };
// U+00A0 NO BREAK SPACE // U+00A0 NO BREAK SPACE

View file

@ -544,7 +544,7 @@ void Editor::initialize()
m_configuration.set(Configuration::NonInteractive); m_configuration.set(Configuration::NonInteractive);
} else { } else {
auto* term = getenv("TERM"); auto* term = getenv("TERM");
if (StringView { term }.starts_with("xterm")) if (term != NULL && StringView { term, strlen(term) }.starts_with("xterm"sv))
m_configuration.set(Configuration::Full); m_configuration.set(Configuration::Full);
else else
m_configuration.set(Configuration::NoEscapeSequences); m_configuration.set(Configuration::NoEscapeSequences);

View file

@ -34,7 +34,7 @@ int main(int argc, char** argv)
Vector<StringView> arguments; Vector<StringView> arguments;
arguments.ensure_capacity(argc); arguments.ensure_capacity(argc);
for (int i = 0; i < argc; ++i) for (int i = 0; i < argc; ++i)
arguments.unchecked_append(argv[i]); arguments.unchecked_append({ argv[i], strlen(argv[i]) });
auto result = serenity_main({ auto result = serenity_main({
.argc = argc, .argc = argc,

View file

@ -91,10 +91,11 @@ int regexec(regex_t const* reg, char const* string, size_t nmatch, regmatch_t pm
} }
RegexResult result; RegexResult result;
StringView string_view { string, strlen(string) };
if (eflags & REG_SEARCH) if (eflags & REG_SEARCH)
result = preg->re->visit([&](auto& re) { return re->search(string, PosixOptions {} | (PosixFlags)eflags); }); result = preg->re->visit([&](auto& re) { return re->search(string_view, PosixOptions {} | (PosixFlags)eflags); });
else else
result = preg->re->visit([&](auto& re) { return re->match(string, PosixOptions {} | (PosixFlags)eflags); }); result = preg->re->visit([&](auto& re) { return re->match(string_view, PosixOptions {} | (PosixFlags)eflags); });
if (result.success) { if (result.success) {
auto capture_groups_count = preg->re->visit([](auto& re) { return re->parser_result.capture_groups_count; }); auto capture_groups_count = preg->re->visit([](auto& re) { return re->parser_result.capture_groups_count; });

View file

@ -31,7 +31,8 @@ static void print_location(SourceLocation const& location)
static bool checked_env_for_deadly = false; static bool checked_env_for_deadly = false;
if (!checked_env_for_deadly) { if (!checked_env_for_deadly) {
checked_env_for_deadly = true; checked_env_for_deadly = true;
StringView options = getenv("UBSAN_OPTIONS"); auto const* options_ptr = getenv("UBSAN_OPTIONS");
auto options = options_ptr != NULL ? StringView { options_ptr, strlen(options_ptr) } : StringView {};
// FIXME: Parse more options and complain about invalid options // FIXME: Parse more options and complain about invalid options
if (!options.is_null()) { if (!options.is_null()) {
if (options.contains("halt_on_error=1")) if (options.contains("halt_on_error=1"))

View file

@ -82,7 +82,7 @@ StringView system_time_zone()
StringView current_time_zone() StringView current_time_zone()
{ {
return canonicalize_time_zone(tzname[0]).value_or("UTC"sv); return canonicalize_time_zone({ tzname[0], __builtin_strlen(tzname[0]) }).value_or("UTC"sv);
} }
ErrorOr<void> change_time_zone([[maybe_unused]] StringView time_zone) ErrorOr<void> change_time_zone([[maybe_unused]] StringView time_zone)

View file

@ -574,7 +574,8 @@ bool Node::is_root_element() const
String Node::class_name() const String Node::class_name() const
{ {
return demangle(typeid(*this).name()); auto const* mangled_name = typeid(*this).name();
return demangle({ mangled_name, strlen(mangled_name) });
} }
String Node::debug_description() const String Node::debug_description() const

View file

@ -214,8 +214,17 @@ public:
MACAddress const& chaddr() const { return *(MACAddress const*)&m_chaddr[0]; } MACAddress const& chaddr() const { return *(MACAddress const*)&m_chaddr[0]; }
void set_chaddr(MACAddress const& mac) { *(MACAddress*)&m_chaddr[0] = mac; } void set_chaddr(MACAddress const& mac) { *(MACAddress*)&m_chaddr[0] = mac; }
StringView sname() const { return { (char const*)&m_sname[0] }; } StringView sname() const
StringView file() const { return { (char const*)&m_file[0] }; } {
char const* sname_ptr = reinterpret_cast<char const*>(&m_sname[0]);
return { sname_ptr, strlen(sname_ptr) };
}
StringView file() const
{
char const* file_ptr = reinterpret_cast<char const*>(&m_file[0]);
return { file_ptr, strlen(file_ptr) };
}
private: private:
NetworkOrdered<u8> m_op; NetworkOrdered<u8> m_op;

View file

@ -35,7 +35,7 @@ int Shell::builtin_dump(int argc, char const** argv)
if (argc != 2) if (argc != 2)
return 1; return 1;
Parser { argv[1] }.parse()->dump(0); Parser { StringView { argv[1], strlen(argv[1]) } }.parse()->dump(0);
return 0; return 0;
} }
@ -124,7 +124,8 @@ int Shell::builtin_bg(int argc, char const** argv)
.name = "job-id", .name = "job-id",
.min_values = 0, .min_values = 0,
.max_values = 1, .max_values = 1,
.accept_value = [&](StringView value) -> bool { .accept_value = [&](auto value_ptr) -> bool {
StringView value { value_ptr, strlen(value_ptr) };
// Check if it's a pid (i.e. literal integer) // Check if it's a pid (i.e. literal integer)
if (auto number = value.to_uint(); number.has_value()) { if (auto number = value.to_uint(); number.has_value()) {
job_id = number.value(); job_id = number.value();
@ -497,7 +498,8 @@ int Shell::builtin_fg(int argc, char const** argv)
.name = "job-id", .name = "job-id",
.min_values = 0, .min_values = 0,
.max_values = 1, .max_values = 1,
.accept_value = [&](StringView value) -> bool { .accept_value = [&](auto const* value_ptr) -> bool {
StringView value { value_ptr, strlen(value_ptr) };
// Check if it's a pid (i.e. literal integer) // Check if it's a pid (i.e. literal integer)
if (auto number = value.to_uint(); number.has_value()) { if (auto number = value.to_uint(); number.has_value()) {
job_id = number.value(); job_id = number.value();
@ -568,7 +570,8 @@ int Shell::builtin_disown(int argc, char const** argv)
.name = "job-id", .name = "job-id",
.min_values = 0, .min_values = 0,
.max_values = INT_MAX, .max_values = INT_MAX,
.accept_value = [&](StringView value) -> bool { .accept_value = [&](auto const* value_ptr) -> bool {
StringView value { value_ptr, strlen(value_ptr) };
// Check if it's a pid (i.e. literal integer) // Check if it's a pid (i.e. literal integer)
if (auto number = value.to_uint(); number.has_value()) { if (auto number = value.to_uint(); number.has_value()) {
job_ids.append(number.value()); job_ids.append(number.value());
@ -721,7 +724,7 @@ int Shell::builtin_pushd(int argc, char const** argv)
if (argc == 2) { if (argc == 2) {
directory_stack.append(cwd.characters()); directory_stack.append(cwd.characters());
if (argv[1][0] == '/') { if (argv[1][0] == '/') {
path_builder.append(argv[1]); path_builder.append({ argv[1], strlen(argv[1]) });
} else { } else {
path_builder.appendff("{}/{}", cwd, argv[1]); path_builder.appendff("{}/{}", cwd, argv[1]);
} }
@ -732,7 +735,7 @@ int Shell::builtin_pushd(int argc, char const** argv)
if (arg[0] != '-') { if (arg[0] != '-') {
if (arg[0] == '/') { if (arg[0] == '/') {
path_builder.append(arg); path_builder.append({ arg, strlen(arg) });
} else } else
path_builder.appendff("{}/{}", cwd, arg); path_builder.appendff("{}/{}", cwd, arg);
} }
@ -969,7 +972,8 @@ int Shell::builtin_wait(int argc, char const** argv)
.name = "job-id", .name = "job-id",
.min_values = 0, .min_values = 0,
.max_values = INT_MAX, .max_values = INT_MAX,
.accept_value = [&](StringView value) -> bool { .accept_value = [&](auto const* value_ptr) -> bool {
StringView value { value_ptr, strlen(value_ptr) };
// Check if it's a pid (i.e. literal integer) // Check if it's a pid (i.e. literal integer)
if (auto number = value.to_uint(); number.has_value()) { if (auto number = value.to_uint(); number.has_value()) {
job_ids.append(number.value()); job_ids.append(number.value());
@ -1071,14 +1075,14 @@ int Shell::builtin_kill(int argc, char const** argv)
{ {
// Simply translate the arguments and pass them to `kill' // Simply translate the arguments and pass them to `kill'
Vector<String> replaced_values; Vector<String> replaced_values;
auto kill_path = find_in_path("kill"); auto kill_path = find_in_path("kill"sv);
if (kill_path.is_empty()) { if (kill_path.is_empty()) {
warnln("kill: `kill' not found in PATH"); warnln("kill: `kill' not found in PATH");
return 126; return 126;
} }
replaced_values.append(kill_path); replaced_values.append(kill_path);
for (auto i = 1; i < argc; ++i) { for (auto i = 1; i < argc; ++i) {
if (auto job_id = resolve_job_spec(argv[i]); job_id.has_value()) { if (auto job_id = resolve_job_spec({ argv[i], strlen(argv[1]) }); job_id.has_value()) {
auto job = find_job(job_id.value()); auto job = find_job(job_id.value());
if (job) { if (job) {
replaced_values.append(String::number(job->pid())); replaced_values.append(String::number(job->pid()));
@ -1240,7 +1244,7 @@ int Shell::builtin_argsparser_parse(int argc, char const** argv)
return false; return false;
} }
option.accept_value = [&, current_variable, treat_arg_as_list, type](auto value) { option.accept_value = [&, current_variable, treat_arg_as_list, type](auto value) {
auto result = try_convert(value, type); auto result = try_convert({ value, strlen(value) }, type);
if (result.has_value()) { if (result.has_value()) {
auto value = result.release_value(); auto value = result.release_value();
if (treat_arg_as_list) if (treat_arg_as_list)
@ -1262,7 +1266,7 @@ int Shell::builtin_argsparser_parse(int argc, char const** argv)
return false; return false;
} }
arg.accept_value = [&, current_variable, treat_arg_as_list, type](auto value) { arg.accept_value = [&, current_variable, treat_arg_as_list, type](auto value) {
auto result = try_convert(value, type); auto result = try_convert({ value, strlen(value) }, type);
if (result.has_value()) { if (result.has_value()) {
auto value = result.release_value(); auto value = result.release_value();
if (treat_arg_as_list) if (treat_arg_as_list)
@ -1345,7 +1349,7 @@ int Shell::builtin_argsparser_parse(int argc, char const** argv)
return false; return false;
} }
StringView ty = name; StringView ty { name, strlen(name) };
if (ty == "bool") { if (ty == "bool") {
if (auto option = current.get_pointer<Core::ArgsParser::Option>()) { if (auto option = current.get_pointer<Core::ArgsParser::Option>()) {
if (option->value_name != nullptr) { if (option->value_name != nullptr) {
@ -1499,7 +1503,7 @@ int Shell::builtin_argsparser_parse(int argc, char const** argv)
return false; return false;
} }
auto number = StringView(value).to_uint(); auto number = StringView { value, strlen(value) }.to_uint();
if (!number.has_value()) { if (!number.has_value()) {
warnln("Invalid value for --min: '{}', expected a non-negative number", value); warnln("Invalid value for --min: '{}', expected a non-negative number", value);
return false; return false;
@ -1527,7 +1531,7 @@ int Shell::builtin_argsparser_parse(int argc, char const** argv)
return false; return false;
} }
auto number = StringView(value).to_uint(); auto number = StringView { value, strlen(value) }.to_uint();
if (!number.has_value()) { if (!number.has_value()) {
warnln("Invalid value for --max: '{}', expected a non-negative number", value); warnln("Invalid value for --max: '{}', expected a non-negative number", value);
return false; return false;

View file

@ -110,7 +110,7 @@ String Shell::prompt() const
builder.append(username); builder.append(username);
break; break;
case 'h': case 'h':
builder.append(hostname); builder.append({ hostname, strlen(hostname) });
break; break;
case 'w': { case 'w': {
String home_path = getenv("HOME"); String home_path = getenv("HOME");
@ -1607,7 +1607,7 @@ Vector<Line::CompletionSuggestion> Shell::complete_variable(StringView name, siz
// Look at the environment. // Look at the environment.
for (auto i = 0; environ[i]; ++i) { for (auto i = 0; environ[i]; ++i) {
auto entry = StringView { environ[i] }; StringView entry { environ[i], strlen(environ[i]) };
if (entry.starts_with(pattern)) { if (entry.starts_with(pattern)) {
auto parts = entry.split_view('='); auto parts = entry.split_view('=');
if (parts.is_empty() || parts.first().is_empty()) if (parts.is_empty() || parts.first().is_empty())
@ -2183,7 +2183,10 @@ Shell::Shell()
// Add the default PATH vars. // Add the default PATH vars.
{ {
StringBuilder path; StringBuilder path;
path.append(getenv("PATH")); auto const* path_env_ptr = getenv("PATH");
if (path_env_ptr != NULL)
path.append({ path_env_ptr, strlen(path_env_ptr) });
if (path.length()) if (path.length())
path.append(":"); path.append(":");
path.append("/usr/local/sbin:/usr/local/bin:/usr/bin:/bin"); path.append("/usr/local/sbin:/usr/local/bin:/usr/bin:/bin");
@ -2476,7 +2479,8 @@ void Shell::timer_event(Core::TimerEvent& event)
if (m_is_subshell) if (m_is_subshell)
return; return;
StringView option = getenv("HISTORY_AUTOSAVE_TIME_MS"); auto const* autosave_env_ptr = getenv("HISTORY_AUTOSAVE_TIME_MS");
auto option = autosave_env_ptr != NULL ? StringView { autosave_env_ptr, strlen(autosave_env_ptr) } : StringView {};
auto time = option.to_uint(); auto time = option.to_uint();
if (!time.has_value() || time.value() == 0) { if (!time.has_value() || time.value() == 0) {

View file

@ -65,12 +65,13 @@ ErrorOr<void> parse_args(Main::Arguments arguments, Vector<String>& files, DuOpt
"time", "time",
0, 0,
"time-type", "time-type",
[&du_option](StringView s) { [&du_option](auto const* option_ptr) {
if (s == "mtime"sv || s == "modification"sv) StringView option { option_ptr, strlen(option_ptr) };
if (option == "mtime"sv || option == "modification"sv)
du_option.time_type = DuOption::TimeType::Modification; du_option.time_type = DuOption::TimeType::Modification;
else if (s == "ctime"sv || s == "status"sv || s == "use"sv) else if (option == "ctime"sv || option == "status"sv || option == "use"sv)
du_option.time_type = DuOption::TimeType::Status; du_option.time_type = DuOption::TimeType::Status;
else if (s == "atime"sv || s == "access"sv) else if (option == "atime"sv || option == "access"sv)
du_option.time_type = DuOption::TimeType::Access; du_option.time_type = DuOption::TimeType::Access;
else else
return false; return false;

View file

@ -31,7 +31,7 @@ template<typename Fmt, typename... Args>
[[noreturn]] void fail(Fmt&& fmt, Args&&... args) [[noreturn]] void fail(Fmt&& fmt, Args&&... args)
{ {
warn("ERROR: \e[31m"); warn("ERROR: \e[31m");
warnln(StringView { fmt }, args...); warnln(StringView { fmt, strlen(fmt) }, args...);
warn("\e[0m"); warn("\e[0m");
exit(2); exit(2);
} }

View file

@ -19,7 +19,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
} }
for (;;) { for (;;) {
char buffer[4096]; char buffer[4096];
auto str = StringView(fgets(buffer, sizeof(buffer), stdin)); fgets(buffer, sizeof(buffer), stdin);
auto str = StringView { buffer, strlen(buffer) };
if (str.contains(arguments.strings[1])) if (str.contains(arguments.strings[1]))
TRY(Core::System::write(1, str.bytes())); TRY(Core::System::write(1, str.bytes()));
if (feof(stdin)) if (feof(stdin))

View file

@ -112,8 +112,8 @@ class TypeCommand final : public Command {
public: public:
TypeCommand(char const* arg) TypeCommand(char const* arg)
{ {
StringView type = arg; StringView type { arg, strlen(arg) };
if (type.length() != 1 || !StringView("bcdlpfs").contains(type[0])) if (type.length() != 1 || !"bcdlpfs"sv.contains(type[0]))
fatal_error("Invalid mode: \033[1m{}", arg); fatal_error("Invalid mode: \033[1m{}", arg);
m_type = type[0]; m_type = type[0];
} }
@ -157,7 +157,7 @@ class LinksCommand final : public StatCommand {
public: public:
LinksCommand(char const* arg) LinksCommand(char const* arg)
{ {
auto number = StringView(arg).to_uint(); auto number = StringView { arg, strlen(arg) }.to_uint();
if (!number.has_value()) if (!number.has_value())
fatal_error("Invalid number: \033[1m{}", arg); fatal_error("Invalid number: \033[1m{}", arg);
m_links = number.value(); m_links = number.value();
@ -180,7 +180,7 @@ public:
m_uid = passwd->pw_uid; m_uid = passwd->pw_uid;
} else { } else {
// Attempt to parse it as decimal UID. // Attempt to parse it as decimal UID.
auto number = StringView(arg).to_uint(); auto number = StringView { arg, strlen(arg) }.to_uint();
if (!number.has_value()) if (!number.has_value())
fatal_error("Invalid user: \033[1m{}", arg); fatal_error("Invalid user: \033[1m{}", arg);
m_uid = number.value(); m_uid = number.value();
@ -204,7 +204,7 @@ public:
m_gid = gr->gr_gid; m_gid = gr->gr_gid;
} else { } else {
// Attempt to parse it as decimal GID. // Attempt to parse it as decimal GID.
auto number = StringView(arg).to_int(); auto number = StringView { arg, strlen(arg) }.to_int();
if (!number.has_value()) if (!number.has_value())
fatal_error("Invalid group: \033[1m{}", arg); fatal_error("Invalid group: \033[1m{}", arg);
m_gid = number.value(); m_gid = number.value();
@ -224,7 +224,7 @@ class SizeCommand final : public StatCommand {
public: public:
SizeCommand(char const* arg) SizeCommand(char const* arg)
{ {
StringView view = arg; StringView view { arg, strlen(arg) };
if (view.ends_with('c')) { if (view.ends_with('c')) {
m_is_bytes = true; m_is_bytes = true;
view = view.substring_view(0, view.length() - 1); view = view.substring_view(0, view.length() - 1);
@ -252,7 +252,7 @@ private:
class NameCommand : public Command { class NameCommand : public Command {
public: public:
NameCommand(char const* pattern, CaseSensitivity case_sensitivity) NameCommand(char const* pattern, CaseSensitivity case_sensitivity)
: m_pattern(pattern) : m_pattern(pattern, strlen(pattern))
, m_case_sensitivity(case_sensitivity) , m_case_sensitivity(case_sensitivity)
{ {
} }
@ -306,7 +306,7 @@ private:
// constness. // constness.
auto argv = const_cast<Vector<char*>&>(m_argv); auto argv = const_cast<Vector<char*>&>(m_argv);
for (auto& arg : argv) { for (auto& arg : argv) {
if (StringView(arg) == "{}") if (StringView { arg, strlen(arg) } == "{}")
arg = const_cast<char*>(file_data.full_path.string().characters()); arg = const_cast<char*>(file_data.full_path.string().characters());
} }
argv.append(nullptr); argv.append(nullptr);
@ -374,11 +374,11 @@ static OwnPtr<Command> parse_simple_command(Vector<char*>& args)
return {}; return {};
char* raw_arg = args.take_first(); char* raw_arg = args.take_first();
StringView arg = raw_arg; StringView arg { raw_arg, strlen(raw_arg) };
if (arg == "(") { if (arg == "(") {
auto command = parse_complex_command(args); auto command = parse_complex_command(args);
if (command && !args.is_empty() && StringView(args.first()) == ")") if (command && !args.is_empty() && StringView { args.first(), strlen(args.first()) } == ")")
return command; return command;
fatal_error("Unmatched \033[1m("); fatal_error("Unmatched \033[1m(");
} else if (arg == "-type") { } else if (arg == "-type") {
@ -438,7 +438,7 @@ static OwnPtr<Command> parse_complex_command(Vector<char*>& args)
while (command && !args.is_empty()) { while (command && !args.is_empty()) {
char* raw_arg = args.take_first(); char* raw_arg = args.take_first();
StringView arg = raw_arg; StringView arg { raw_arg, strlen(raw_arg) };
enum { enum {
And, And,
@ -533,7 +533,7 @@ static void walk_tree(FileData& root_data, Command& command)
continue; continue;
FileData file_data { FileData file_data {
root_data.full_path.append(dirent->d_name), root_data.full_path.append({ dirent->d_name, strlen(dirent->d_name) }),
dirfd, dirfd,
dirent->d_name, dirent->d_name,
(struct stat) {}, (struct stat) {},
@ -561,7 +561,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
while (!args.is_empty()) { while (!args.is_empty()) {
char* raw_arg = args.take_first(); char* raw_arg = args.take_first();
StringView arg = raw_arg; StringView arg { raw_arg, strlen(raw_arg) };
if (arg == "-L") { if (arg == "-L") {
g_follow_symlinks = true; g_follow_symlinks = true;
} else if (!arg.starts_with('-')) { } else if (!arg.starts_with('-')) {

View file

@ -58,9 +58,10 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
// Create a temporary group file // Create a temporary group file
char temp_group[] = "/etc/group.XXXXXX"; char temp_group[] = "/etc/group.XXXXXX";
StringView temp_group_view { temp_group, strlen(temp_group) };
auto unlink_temp_files = [&] { auto unlink_temp_files = [&] {
if (Core::System::unlink(temp_group).is_error()) if (Core::System::unlink(temp_group_view).is_error())
perror("unlink"); perror("unlink");
}; };
@ -92,8 +93,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
return 1; return 1;
} }
TRY(Core::System::chmod(temp_group, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)); TRY(Core::System::chmod(temp_group_view, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH));
TRY(Core::System::rename(temp_group, "/etc/group")); TRY(Core::System::rename(temp_group_view, "/etc/group"sv));
unlink_temp_files_guard.disarm(); unlink_temp_files_guard.disarm();

View file

@ -416,7 +416,7 @@ static int do_file_system_object_long(char const* path)
continue; continue;
StringBuilder builder; StringBuilder builder;
builder.append(path); builder.append({ path, strlen(path) });
builder.append('/'); builder.append('/');
builder.append(metadata.name); builder.append(metadata.name);
metadata.path = builder.to_string(); metadata.path = builder.to_string();
@ -460,7 +460,7 @@ static bool print_names(char const* path, size_t longest_name, Vector<FileMetada
for (size_t i = 0; i < files.size(); ++i) { for (size_t i = 0; i < files.size(); ++i) {
auto& name = files[i].name; auto& name = files[i].name;
StringBuilder builder; StringBuilder builder;
builder.append(path); builder.append({ path, strlen(path) });
builder.append('/'); builder.append('/');
builder.append(name); builder.append(name);
if (!print_filesystem_object_short(builder.to_string().characters(), name.characters(), &nprinted)) if (!print_filesystem_object_short(builder.to_string().characters(), name.characters(), &nprinted))
@ -528,7 +528,7 @@ int do_file_system_object_short(char const* path)
continue; continue;
StringBuilder builder; StringBuilder builder;
builder.append(path); builder.append({ path, strlen(path) });
builder.append('/'); builder.append('/');
builder.append(metadata.name); builder.append(metadata.name);
metadata.path = builder.to_string(); metadata.path = builder.to_string();

View file

@ -73,11 +73,13 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
if (target_directory.is_empty()) { if (target_directory.is_empty()) {
if (!file_template.is_empty()) { // If a custom template is specified we assume the target directory is the current directory if (!file_template.is_empty()) { // If a custom template is specified we assume the target directory is the current directory
target_directory = getcwd(nullptr, 0); // FIXME: Get rid of this minor memory leak.
auto const* cwd_ptr = getcwd(nullptr, 0);
target_directory = StringView { cwd_ptr, strlen(cwd_ptr) };
} else { } else {
LexicalPath template_path(file_template); LexicalPath template_path(file_template);
char const* env_directory = getenv("TMPDIR"); char const* env_directory = getenv("TMPDIR");
target_directory = env_directory && *env_directory ? env_directory : "/tmp"; target_directory = env_directory && *env_directory ? StringView { env_directory, strlen(env_directory) } : "/tmp"sv;
} }
} }

View file

@ -185,7 +185,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
auto addr = from_string.value().to_in_addr_t(); auto addr = from_string.value().to_in_addr_t();
auto* hostent = gethostbyaddr(&addr, sizeof(in_addr), AF_INET); auto* hostent = gethostbyaddr(&addr, sizeof(in_addr), AF_INET);
if (hostent != nullptr) { if (hostent != nullptr) {
auto host_name = StringView(hostent->h_name); auto host_name = StringView { hostent->h_name, strlen(hostent->h_name) };
if (!host_name.is_empty()) if (!host_name.is_empty())
peer_address = host_name; peer_address = host_name;
} }
@ -195,7 +195,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
if (!flag_numeric) { if (!flag_numeric) {
auto service = getservbyport(htons(if_object.get("peer_port").to_u32()), "tcp"); auto service = getservbyport(htons(if_object.get("peer_port").to_u32()), "tcp");
if (service != nullptr) { if (service != nullptr) {
auto s_name = StringView(service->s_name); auto s_name = StringView { service->s_name, strlen(service->s_name) };
if (!s_name.is_empty()) if (!s_name.is_empty())
peer_port = s_name; peer_port = s_name;
} }
@ -207,7 +207,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
auto addr = from_string.value().to_in_addr_t(); auto addr = from_string.value().to_in_addr_t();
auto* hostent = gethostbyaddr(&addr, sizeof(in_addr), AF_INET); auto* hostent = gethostbyaddr(&addr, sizeof(in_addr), AF_INET);
if (hostent != nullptr) { if (hostent != nullptr) {
auto host_name = StringView(hostent->h_name); auto host_name = StringView { hostent->h_name, strlen(hostent->h_name) };
if (!host_name.is_empty()) if (!host_name.is_empty())
local_address = host_name; local_address = host_name;
} }
@ -217,7 +217,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
if (!flag_numeric) { if (!flag_numeric) {
auto service = getservbyport(htons(if_object.get("local_port").to_u32()), "tcp"); auto service = getservbyport(htons(if_object.get("local_port").to_u32()), "tcp");
if (service != nullptr) { if (service != nullptr) {
auto s_name = StringView(service->s_name); auto s_name = StringView { service->s_name, strlen(service->s_name) };
if (!s_name.is_empty()) if (!s_name.is_empty())
local_port = s_name; local_port = s_name;
} }
@ -269,7 +269,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
auto addr = from_string.value().to_in_addr_t(); auto addr = from_string.value().to_in_addr_t();
auto* hostent = gethostbyaddr(&addr, sizeof(in_addr), AF_INET); auto* hostent = gethostbyaddr(&addr, sizeof(in_addr), AF_INET);
if (hostent != nullptr) { if (hostent != nullptr) {
auto host_name = StringView(hostent->h_name); auto host_name = StringView { hostent->h_name, strlen(hostent->h_name) };
if (!host_name.is_empty()) if (!host_name.is_empty())
local_address = host_name; local_address = host_name;
} }
@ -279,7 +279,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
if (!flag_numeric) { if (!flag_numeric) {
auto service = getservbyport(htons(if_object.get("local_port").to_u32()), "udp"); auto service = getservbyport(htons(if_object.get("local_port").to_u32()), "udp");
if (service != nullptr) { if (service != nullptr) {
auto s_name = StringView(service->s_name); auto s_name = StringView { service->s_name, strlen(service->s_name) };
if (!s_name.is_empty()) if (!s_name.is_empty())
local_port = s_name; local_port = s_name;
} }
@ -291,7 +291,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
auto addr = from_string.value().to_in_addr_t(); auto addr = from_string.value().to_in_addr_t();
auto* hostent = gethostbyaddr(&addr, sizeof(in_addr), AF_INET); auto* hostent = gethostbyaddr(&addr, sizeof(in_addr), AF_INET);
if (hostent != nullptr) { if (hostent != nullptr) {
auto host_name = StringView(hostent->h_name); auto host_name = StringView { hostent->h_name, strlen(hostent->h_name) };
if (!host_name.is_empty()) if (!host_name.is_empty())
peer_address = host_name; peer_address = host_name;
} }
@ -301,7 +301,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
if (!flag_numeric) { if (!flag_numeric) {
auto service = getservbyport(htons(if_object.get("peer_port").to_u32()), "udp"); auto service = getservbyport(htons(if_object.get("peer_port").to_u32()), "udp");
if (service != nullptr) { if (service != nullptr) {
auto s_name = StringView(service->s_name); auto s_name = StringView { service->s_name, strlen(service->s_name) };
if (!s_name.is_empty()) if (!s_name.is_empty())
peer_port = s_name; peer_port = s_name;
} }

View file

@ -27,7 +27,7 @@ static void spawn_command(Span<StringView> command, ByteBuffer const& data, char
MUST(Core::System::dup2(pipefd[0], 0)); MUST(Core::System::dup2(pipefd[0], 0));
MUST(Core::System::close(pipefd[0])); MUST(Core::System::close(pipefd[0]));
MUST(Core::System::close(pipefd[1])); MUST(Core::System::close(pipefd[1]));
MUST(Core::System::setenv("CLIPBOARD_STATE", state, true)); MUST(Core::System::setenv("CLIPBOARD_STATE"sv, { state, strlen(state) }, true));
MUST(Core::System::exec(command[0], command, Core::System::SearchInPath::Yes)); MUST(Core::System::exec(command[0], command, Core::System::SearchInPath::Yes));
perror("exec"); perror("exec");
exit(1); exit(1);

View file

@ -63,7 +63,7 @@ ErrorOr<int> serenity_main(Main::Arguments args)
if (!strcmp(omit_pid_value, "%PPID")) { if (!strcmp(omit_pid_value, "%PPID")) {
pid_to_omit = getppid(); pid_to_omit = getppid();
} else { } else {
auto number = StringView(omit_pid_value).to_uint(); auto number = StringView { omit_pid_value, strlen(omit_pid_value) }.to_uint();
if (!number.has_value()) { if (!number.has_value()) {
warnln("Invalid value for -o"); warnln("Invalid value for -o");
args_parser.print_usage(stderr, args.argv[0]); args_parser.print_usage(stderr, args.argv[0]);

View file

@ -49,7 +49,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
Vector<StringView> exec_environment; Vector<StringView> exec_environment;
for (size_t i = 0; environ[i]; ++i) { for (size_t i = 0; environ[i]; ++i) {
StringView env_view { environ[i] }; StringView env_view { environ[i], strlen(environ[i]) };
auto maybe_needle = env_view.find('='); auto maybe_needle = env_view.find('=');
if (!maybe_needle.has_value()) if (!maybe_needle.has_value())

View file

@ -170,7 +170,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
.short_name = 'H', .short_name = 'H',
.value_name = "header-value", .value_name = "header-value",
.accept_value = [&](auto* s) { .accept_value = [&](auto* s) {
StringView header { s }; StringView header { s, strlen(s) };
auto split = header.find(':'); auto split = header.find(':');
if (!split.has_value()) if (!split.has_value())
return false; return false;
@ -316,7 +316,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
request->stream_into(output_stream); request->stream_into(output_stream);
}; };
request = protocol_client->start_request(method, url, request_headers, data ? StringView { data }.bytes() : ReadonlyBytes {}, proxy_data); request = protocol_client->start_request(method, url, request_headers, data ? StringView { data, strlen(data) }.bytes() : ReadonlyBytes {}, proxy_data);
setup_request(); setup_request();
dbgln("started request with id {}", request->id()); dbgln("started request with id {}", request->id());

View file

@ -836,7 +836,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
auto parse_syscalls = [](char const* option, auto& hash_table) { auto parse_syscalls = [](char const* option, auto& hash_table) {
if (option != nullptr) { if (option != nullptr) {
for (auto syscall : StringView(option).split_view(',')) for (auto syscall : StringView { option, strlen(option) }.split_view(','))
hash_table.set(syscall); hash_table.set(syscall);
} }
}; };

View file

@ -295,7 +295,7 @@ Result<void, int> apply_modes(size_t parameter_count, char** raw_parameters, ter
Vector<StringView> parameters; Vector<StringView> parameters;
parameters.ensure_capacity(parameter_count); parameters.ensure_capacity(parameter_count);
for (size_t i = 0; i < parameter_count; ++i) for (size_t i = 0; i < parameter_count; ++i)
parameters.append(StringView(raw_parameters[i])); parameters.append(StringView { raw_parameters[i], strlen(raw_parameters[i]) });
auto parse_baud = [&](size_t idx) -> Optional<speed_t> { auto parse_baud = [&](size_t idx) -> Optional<speed_t> {
auto maybe_numeric_value = parameters[idx].to_uint<uint32_t>(); auto maybe_numeric_value = parameters[idx].to_uint<uint32_t>();

View file

@ -26,7 +26,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
.short_name = 'u', .short_name = 'u',
.value_name = "path", .value_name = "path",
.accept_value = [&](auto* s) { .accept_value = [&](auto* s) {
StringView path { s }; StringView path { s, strlen(s) };
if (path.is_empty()) if (path.is_empty())
return false; return false;
auto maybe_error = Core::System::unveil(path, permissions); auto maybe_error = Core::System::unveil(path, permissions);
@ -55,7 +55,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
.min_values = 0, .min_values = 0,
.max_values = INT_MAX, .max_values = INT_MAX,
.accept_value = [&](auto* s) { .accept_value = [&](auto* s) {
auto maybe_error = Core::System::access(s, X_OK); auto maybe_error = Core::System::access({ s, strlen(s) }, X_OK);
if (maybe_error.is_error()) if (maybe_error.is_error())
warnln("'{}' - fail: {}", s, maybe_error.error()); warnln("'{}' - fail: {}", s, maybe_error.error());
else else

View file

@ -324,7 +324,7 @@ static bool should_treat_expression_as_single_string(StringView arg_after)
static OwnPtr<Condition> parse_simple_expression(char* argv[]) static OwnPtr<Condition> parse_simple_expression(char* argv[])
{ {
StringView arg = argv[optind]; StringView arg { argv[optind], strlen(argv[optind]) };
if (arg.is_null()) { if (arg.is_null()) {
return {}; return {};
} }
@ -332,20 +332,24 @@ static OwnPtr<Condition> parse_simple_expression(char* argv[])
if (arg == "(") { if (arg == "(") {
optind++; optind++;
auto command = parse_complex_expression(argv); auto command = parse_complex_expression(argv);
if (command && argv[optind] && StringView(argv[++optind]) == ")") if (command && argv[optind]) {
return command; auto const* next_option = argv[++optind];
if (StringView { next_option, strlen(next_option) } == ")")
return command;
}
fatal_error("Unmatched \033[1m("); fatal_error("Unmatched \033[1m(");
} }
// Try to read a unary op. // Try to read a unary op.
if (arg.starts_with('-') && arg.length() == 2) { if (arg.starts_with('-') && arg.length() == 2) {
optind++; optind++;
if (should_treat_expression_as_single_string(argv[optind])) { if (should_treat_expression_as_single_string({ argv[optind], strlen(argv[optind]) })) {
--optind; --optind;
return make<StringCompare>(move(arg), "", StringCompare::NotEqual); return make<StringCompare>(move(arg), "", StringCompare::NotEqual);
} }
StringView value = argv[optind]; StringView value { argv[optind], strlen(argv[optind]) };
switch (arg[1]) { switch (arg[1]) {
case 'b': case 'b':
return make<FileIsOfKind>(value, FileIsOfKind::BlockDevice); return make<FileIsOfKind>(value, FileIsOfKind::BlockDevice);
@ -393,42 +397,49 @@ static OwnPtr<Condition> parse_simple_expression(char* argv[])
} }
} }
auto get_next_arg = [&argv]() -> StringView {
auto const* next_arg = argv[++optind];
if (next_arg == NULL)
return StringView {};
return StringView { next_arg, strlen(next_arg) };
};
// Try to read a binary op, this is either a <string> op <string>, <integer> op <integer>, or <file> op <file>. // Try to read a binary op, this is either a <string> op <string>, <integer> op <integer>, or <file> op <file>.
auto lhs = arg; auto lhs = arg;
arg = argv[++optind]; arg = get_next_arg();
if (arg == "=") { if (arg == "=") {
StringView rhs = argv[++optind]; StringView rhs = get_next_arg();
return make<StringCompare>(lhs, rhs, StringCompare::Equal); return make<StringCompare>(lhs, rhs, StringCompare::Equal);
} else if (arg == "!=") { } else if (arg == "!=") {
StringView rhs = argv[++optind]; StringView rhs = get_next_arg();
return make<StringCompare>(lhs, rhs, StringCompare::NotEqual); return make<StringCompare>(lhs, rhs, StringCompare::NotEqual);
} else if (arg == "-eq") { } else if (arg == "-eq") {
StringView rhs = argv[++optind]; StringView rhs = get_next_arg();
return make<NumericCompare>(lhs, rhs, NumericCompare::Equal); return make<NumericCompare>(lhs, rhs, NumericCompare::Equal);
} else if (arg == "-ge") { } else if (arg == "-ge") {
StringView rhs = argv[++optind]; StringView rhs = get_next_arg();
return make<NumericCompare>(lhs, rhs, NumericCompare::GreaterOrEqual); return make<NumericCompare>(lhs, rhs, NumericCompare::GreaterOrEqual);
} else if (arg == "-gt") { } else if (arg == "-gt") {
StringView rhs = argv[++optind]; StringView rhs = get_next_arg();
return make<NumericCompare>(lhs, rhs, NumericCompare::Greater); return make<NumericCompare>(lhs, rhs, NumericCompare::Greater);
} else if (arg == "-le") { } else if (arg == "-le") {
StringView rhs = argv[++optind]; StringView rhs = get_next_arg();
return make<NumericCompare>(lhs, rhs, NumericCompare::LessOrEqual); return make<NumericCompare>(lhs, rhs, NumericCompare::LessOrEqual);
} else if (arg == "-lt") { } else if (arg == "-lt") {
StringView rhs = argv[++optind]; StringView rhs = get_next_arg();
return make<NumericCompare>(lhs, rhs, NumericCompare::Less); return make<NumericCompare>(lhs, rhs, NumericCompare::Less);
} else if (arg == "-ne") { } else if (arg == "-ne") {
StringView rhs = argv[++optind]; StringView rhs = get_next_arg();
return make<NumericCompare>(lhs, rhs, NumericCompare::NotEqual); return make<NumericCompare>(lhs, rhs, NumericCompare::NotEqual);
} else if (arg == "-ef") { } else if (arg == "-ef") {
StringView rhs = argv[++optind]; StringView rhs = get_next_arg();
return make<FileCompare>(lhs, rhs, FileCompare::Same); return make<FileCompare>(lhs, rhs, FileCompare::Same);
} else if (arg == "-nt") { } else if (arg == "-nt") {
StringView rhs = argv[++optind]; StringView rhs = get_next_arg();
return make<FileCompare>(lhs, rhs, FileCompare::ModificationTimestampGreater); return make<FileCompare>(lhs, rhs, FileCompare::ModificationTimestampGreater);
} else if (arg == "-ot") { } else if (arg == "-ot") {
StringView rhs = argv[++optind]; StringView rhs = get_next_arg();
return make<FileCompare>(lhs, rhs, FileCompare::ModificationTimestampLess); return make<FileCompare>(lhs, rhs, FileCompare::ModificationTimestampLess);
} else if (arg == "-o" || arg == "-a") { } else if (arg == "-o" || arg == "-a") {
// '-a' and '-o' are boolean ops, which are part of a complex expression // '-a' and '-o' are boolean ops, which are part of a complex expression
@ -460,7 +471,8 @@ static OwnPtr<Condition> parse_complex_expression(char* argv[])
if (!command && argv[optind]) if (!command && argv[optind])
fatal_error("expected an expression"); fatal_error("expected an expression");
StringView arg = argv[++optind]; auto const* arg_ptr = argv[++optind];
StringView arg { arg_ptr, strlen(arg_ptr) };
enum { enum {
AndOp, AndOp,

View file

@ -144,7 +144,7 @@ static void parse_args(Main::Arguments arguments, TopOption& top_option)
's', 's',
nullptr, nullptr,
[&top_option](char const* s) { [&top_option](char const* s) {
StringView sort_by_option { s }; StringView sort_by_option { s, strlen(s) };
if (sort_by_option == "pid"sv) if (sort_by_option == "pid"sv)
top_option.sort_by = TopOption::SortBy::Pid; top_option.sort_by = TopOption::SortBy::Pid;
else if (sort_by_option == "tid"sv) else if (sort_by_option == "tid"sv)

View file

@ -62,7 +62,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
if (move_home) { if (move_home) {
TRY(Core::System::unveil(target_account.home_directory().characters(), "c")); TRY(Core::System::unveil(target_account.home_directory().characters(), "c"));
TRY(Core::System::unveil(new_home_directory, "wc")); TRY(Core::System::unveil({ new_home_directory, strlen(new_home_directory) }, "wc"));
} }
unveil(nullptr, nullptr); unveil(nullptr, nullptr);

View file

@ -294,7 +294,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
.short_name = 'l', .short_name = 'l',
.value_name = "file", .value_name = "file",
.accept_value = [&](char const* str) { .accept_value = [&](char const* str) {
if (auto v = StringView { str }; !v.is_empty()) { if (auto v = StringView { str, strlen(str) }; !v.is_empty()) {
modules_to_link_in.append(v); modules_to_link_in.append(v);
return true; return true;
} }
@ -308,7 +308,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
.short_name = 0, .short_name = 0,
.value_name = "u64", .value_name = "u64",
.accept_value = [&](char const* str) -> bool { .accept_value = [&](char const* str) -> bool {
if (auto v = StringView { str }.to_uint<u64>(); v.has_value()) { if (auto v = StringView { str, strlen(str) }.to_uint<u64>(); v.has_value()) {
values_to_push.append(v.value()); values_to_push.append(v.value());
return true; return true;
} }

View file

@ -178,7 +178,7 @@ bool read_items(FILE* fp, char entry_separator, Function<Decision(StringView)> c
Decision decision; Decision decision;
do { do {
decision = callback(item); decision = callback({ item, strlen(item) });
if (decision == Stop) { if (decision == Stop) {
free(item); free(item);
return true; return true;