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;
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)
free(demangled_name);
return string;

View file

@ -92,7 +92,7 @@ public:
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")

View file

@ -89,11 +89,11 @@ public:
TRY(begin_item(key));
if constexpr (IsLegacyBuilder<Builder>) {
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('"'));
} else {
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('"'));
}
return {};

View file

@ -15,8 +15,8 @@ namespace AK {
class SourceLocation {
public:
[[nodiscard]] constexpr StringView function_name() const { return StringView(m_function); }
[[nodiscard]] constexpr StringView filename() const { return StringView(m_file); }
[[nodiscard]] constexpr StringView function_name() const { return { m_function, __builtin_strlen(m_function) }; }
[[nodiscard]] constexpr StringView filename() const { return { m_file, __builtin_strlen(m_file) }; }
[[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())

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];
*reinterpret_cast<u32*>(interface_signature_buffer) = hypervisor_interface.eax();
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());

View file

@ -41,7 +41,7 @@ CommandLine const& kernel_command_line()
UNMAP_AFTER_INIT void CommandLine::initialize()
{
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());
// Validate the modes the user passed in.
(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);
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)
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
// 8-N-1 57600 baud. this is particularly useful for debugging the boot
// 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);
}
}

View file

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

View file

@ -31,7 +31,7 @@ static StringView test_default_arg(SourceLocation const& loc = SourceLocation::c
TEST_CASE(default_arg_scenario)
{
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);
}

View file

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

View file

@ -51,33 +51,33 @@ TEST_CASE(decode_utf8)
TEST_CASE(validate_invalid_ut8)
{
size_t valid_bytes;
char invalid_utf8_1[] = { 42, 35, (char)182, 9, 0 };
Utf8View utf8_1 { StringView { invalid_utf8_1 } };
char invalid_utf8_1[] = { 42, 35, (char)182, 9 };
Utf8View utf8_1 { StringView { invalid_utf8_1, 4 } };
EXPECT(!utf8_1.validate(valid_bytes));
EXPECT(valid_bytes == 2);
char invalid_utf8_2[] = { 42, 35, (char)208, (char)208, 0 };
Utf8View utf8_2 { StringView { invalid_utf8_2 } };
char invalid_utf8_2[] = { 42, 35, (char)208, (char)208 };
Utf8View utf8_2 { StringView { invalid_utf8_2, 4 } };
EXPECT(!utf8_2.validate(valid_bytes));
EXPECT(valid_bytes == 2);
char invalid_utf8_3[] = { (char)208, 0 };
Utf8View utf8_3 { StringView { invalid_utf8_3 } };
char invalid_utf8_3[] = { (char)208 };
Utf8View utf8_3 { StringView { invalid_utf8_3, 1 } };
EXPECT(!utf8_3.validate(valid_bytes));
EXPECT(valid_bytes == 0);
char invalid_utf8_4[] = { (char)208, 35, 0 };
Utf8View utf8_4 { StringView { invalid_utf8_4 } };
char invalid_utf8_4[] = { (char)208, 35 };
Utf8View utf8_4 { StringView { invalid_utf8_4, 2 } };
EXPECT(!utf8_4.validate(valid_bytes));
EXPECT(valid_bytes == 0);
char invalid_utf8_5[] = { (char)0xf4, (char)0x8f, (char)0xbf, (char)0xc0, 0 }; // U+110000
Utf8View utf8_5 { StringView { invalid_utf8_5 } };
char invalid_utf8_5[] = { (char)0xf4, (char)0x8f, (char)0xbf, (char)0xc0 }; // U+110000
Utf8View utf8_5 { StringView { invalid_utf8_5, 4 } };
EXPECT(!utf8_5.validate(valid_bytes));
EXPECT(valid_bytes == 0);
char invalid_utf8_6[] = { (char)0xf4, (char)0xa1, (char)0xb0, (char)0xbd, 0 }; // U+121c3d
Utf8View utf8_6 { StringView { invalid_utf8_6 } };
char invalid_utf8_6[] = { (char)0xf4, (char)0xa1, (char)0xb0, (char)0xbd }; // U+121c3d
Utf8View utf8_6 { StringView { invalid_utf8_6, 4 } };
EXPECT(!utf8_6.validate(valid_bytes));
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
{
char raw_data[] = { 'a', 'b', (char)0xA0, 'd', 0 };
Utf8View view { StringView { raw_data } };
char raw_data[] = { 'a', 'b', (char)0xA0, 'd' };
Utf8View view { StringView { raw_data, 4 } };
u32 expected_characters[] = { 'a', 'b', 0xFFFD, 'd' };
String expected_underlying_bytes[] = { "a", "b", "\xA0", "d" };
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
{
char raw_data[] = { 'a', 'b', (char)0xC0, 'd', 'e', 0 };
Utf8View view { StringView { raw_data } };
char raw_data[] = { 'a', 'b', (char)0xC0, 'd', 'e' };
Utf8View view { StringView { raw_data, 5 } };
u32 expected_characters[] = { 'a', 'b', 0xFFFD, 'd', 'e' };
String expected_underlying_bytes[] = { "a", "b", "\xC0", "d", "e" };
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
{
char raw_data[] = { 'a', 'b', (char)0x90, 'd', 0 };
Utf8View view { StringView { raw_data } };
char raw_data[] = { 'a', 'b', (char)0x90, 'd' };
Utf8View view { StringView { raw_data, 4 } };
u32 expected_characters[] = { 'a', 'b', 0xFFFD, 'd' };
String expected_underlying_bytes[] = { "a", "b", "\x90", "d" };
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
{
char raw_data[] = { 'a', 'b', 'c', (char)0x90, 0 };
Utf8View view { StringView { raw_data } };
char raw_data[] = { 'a', 'b', 'c', (char)0x90 };
Utf8View view { StringView { raw_data, 4 } };
u32 expected_characters[] = { 'a', 'b', 'c', 0xFFFD };
String expected_underlying_bytes[] = { "a", "b", "c", "\x90" };
size_t expected_size = sizeof(expected_characters) / sizeof(expected_characters[0]);

View file

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

View file

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

View file

@ -17,7 +17,7 @@
using namespace Help;
static String parse_input(char const* input)
static String parse_input(StringView input)
{
AK::URL url(input);
if (url.is_valid())
@ -50,9 +50,10 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
.name = "section",
.min_values = 0,
.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 (auto number = StringView(input).to_int(); number.has_value()) {
if (auto number = input.to_int(); number.has_value()) {
section = number.value();
return true;
}
@ -66,7 +67,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
.name = "page",
.min_values = 0,
.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.is_empty())
return false;

View file

@ -259,7 +259,8 @@ static void analyze(RefPtr<Tree> tree, SpaceAnalyzer::TreeMapWidget& treemapwidg
if (!first) {
builder.append(", ");
}
builder.append(strerror(key));
auto const* error = strerror(key);
builder.append({ error, strlen(error) });
builder.append(" (");
int value = error_accumulator.get(key).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);
if (!result) {
int error_number = errno;
auto const* error = strerror(error_number);
StringBuilder sb;
sb.append("Unable to save file. Error: ");
sb.append(strerror(error_number));
sb.append({ error, strlen(error) });
return sb.to_string();
}

View file

@ -121,7 +121,11 @@ static void notify_make_not_available()
static void update_path_environment_variable()
{
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())
path.append(":");
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); }
unsigned checksum() const { return get_field_as_integral(m_checksum); }
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 version() const { return get_field_as_string_view(m_version); }
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;
return 1;
} else if (af == AF_INET6) {
auto addr = IPv6Address::from_string(src);
auto addr = IPv6Address::from_string({ src, strlen(src) });
if (!addr.has_value()) {
errno = EINVAL;
return 0;

View file

@ -214,11 +214,11 @@ int OptionParser::handle_short_option()
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++) {
auto& option = m_long_options[index];
StringView name = option.name;
StringView name { option.name, strlen(option.name) };
if (!arg.starts_with(name))
continue;
@ -347,12 +347,12 @@ bool OptionParser::find_next_option()
int getopt(int argc, char* const* argv, char const* short_options)
{
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();
}
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();
}

View file

@ -16,7 +16,8 @@ int getsubopt(char** option_array, char* const* tokens, char** option_value)
if (**option_array == '\0')
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(',');
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) {
auto token_stringview = StringView(tokens[count]);
auto const* token = tokens[count];
StringView token_stringview { token, strlen(token) };
if (!option_string.starts_with(token_stringview))
continue;
if (tokens[count][value_start - *option_array] != '\0')

View file

@ -93,7 +93,7 @@ hostent* gethostbyname(char const* name)
{
h_errno = 0;
auto ipv4_address = IPv4Address::from_string(name);
auto ipv4_address = IPv4Address::from_string({ name, strlen(name) });
if (ipv4_address.has_value()) {
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)
{
GenericLexer format_lexer { format };
GenericLexer input_lexer { input };
GenericLexer format_lexer { { format, strlen(format) } };
GenericLexer input_lexer { { input, strlen(input) } };
int elements_matched = 0;

View file

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

View file

@ -114,7 +114,7 @@ int __attribute__((weak)) tgetnum(char const* id)
static Vector<char> s_tgoto_buffer;
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.ensure_capacity(cap_str.length());

View file

@ -377,7 +377,7 @@ void tzset()
StringView time_zone;
if (char* tz = getenv("TZ"); tz != nullptr)
time_zone = tz;
time_zone = { tz, strlen(tz) };
else
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)
{
StringView username { pwd.pw_name };
StringView username { pwd.pw_name, strlen(pwd.pw_name) };
Vector<gid_t> extra_gids;
setgrent();
for (auto* group = getgrent(); group; group = getgrent()) {
@ -78,7 +78,7 @@ ErrorOr<Account> Account::self([[maybe_unused]] Read options)
spwd spwd = {};
#ifndef AK_OS_BSD_GENERIC
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())
return Error::from_string_literal("No shadow entry for user"sv);
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)
{
auto pwd = TRY(Core::System::getpwnam(username));
auto pwd = TRY(Core::System::getpwnam({ username, strlen(username) }));
if (!pwd.has_value())
return Error::from_string_literal("No such user"sv);
spwd spwd = {};
#ifndef AK_OS_BSD_GENERIC
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())
return Error::from_string_literal("No shadow entry for user"sv);
spwd = maybe_spwd.release_value();
@ -115,7 +115,7 @@ ErrorOr<Account> Account::from_uid(uid_t uid, [[maybe_unused]] Read options)
spwd spwd = {};
#ifndef AK_OS_BSD_GENERIC
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())
return Error::from_string_literal("No shadow entry for user"sv);
spwd = maybe_spwd.release_value();
@ -270,18 +270,22 @@ ErrorOr<void> Account::sync()
auto new_shadow_file_content = TRY(generate_shadow_file());
#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";
size_t new_passwd_name_length = strlen(new_passwd_name);
#ifndef AK_OS_BSD_GENERIC
char new_shadow_name[] = "/etc/shadow.XXXXXX";
size_t new_shadow_name_length = strlen(new_shadow_name);
#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); };
TRY(Core::System::fchmod(new_passwd_fd, 0644));
#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); };
TRY(Core::System::fchmod(new_shadow_fd, 0600));
#endif
@ -295,9 +299,9 @@ ErrorOr<void> Account::sync()
#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
TRY(Core::System::rename(new_shadow_name, "/etc/shadow"));
TRY(Core::System::rename({ new_shadow_name, new_shadow_name_length }, "/etc/shadow"sv));
#endif
return {};

View file

@ -129,7 +129,7 @@ bool ArgsParser::parse(int argc, char* const* argv, FailureBehavior failure_beha
}
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)
exit(0);
return false;
@ -445,7 +445,7 @@ void ArgsParser::add_option(StringView& value, char const* help_string, char con
short_name,
value_name,
[&value](char const* s) {
value = s;
value = { s, strlen(s) };
return true;
},
hide_mode,
@ -462,7 +462,7 @@ void ArgsParser::add_option(int& value, char const* help_string, char const* lon
short_name,
value_name,
[&value](char const* s) {
auto opt = StringView(s).to_int();
auto opt = StringView { s, strlen(s) }.to_int();
value = opt.value_or(0);
return opt.has_value();
},
@ -480,7 +480,7 @@ void ArgsParser::add_option(unsigned& value, char const* help_string, char const
short_name,
value_name,
[&value](char const* s) {
auto opt = StringView(s).to_uint();
auto opt = StringView { s, strlen(s) }.to_uint();
value = opt.value_or(0);
return opt.has_value();
},
@ -533,7 +533,7 @@ void ArgsParser::add_option(Optional<size_t>& value, char const* help_string, ch
short_name,
value_name,
[&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();
},
hide_mode,
@ -552,7 +552,7 @@ void ArgsParser::add_option(Vector<size_t>& values, char const* help_string, cha
[&values, separator](char const* s) {
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())
values.append(*maybe_value);
else
@ -610,7 +610,7 @@ void ArgsParser::add_positional_argument(StringView& value, char const* help_str
required == Required::Yes ? 1 : 0,
1,
[&value](char const* s) {
value = s;
value = { s, strlen(s) };
return true;
}
};
@ -625,7 +625,7 @@ void ArgsParser::add_positional_argument(int& value, char const* help_string, ch
required == Required::Yes ? 1 : 0,
1,
[&value](char const* s) {
auto opt = StringView(s).to_int();
auto opt = StringView { s, strlen(s) }.to_int();
value = opt.value_or(0);
return opt.has_value();
}
@ -641,7 +641,7 @@ void ArgsParser::add_positional_argument(unsigned& value, char const* help_strin
required == Required::Yes ? 1 : 0,
1,
[&value](char const* s) {
auto opt = StringView(s).to_uint();
auto opt = StringView { s, strlen(s) }.to_uint();
value = opt.value_or(0);
return opt.has_value();
}
@ -703,7 +703,7 @@ void ArgsParser::add_positional_argument(Vector<StringView>& values, char const*
required == Required::Yes ? 1 : 0,
INT_MAX,
[&values](char const* s) {
values.append(s);
values.append({ s, strlen(s) });
return true;
}
};
@ -723,7 +723,7 @@ void ArgsParser::autocomplete(FILE* file, StringView program_name, Span<char con
auto completing_option = false;
for (auto& arg : remaining_arguments) {
StringView argument { arg };
StringView argument { arg, strlen(arg) };
completing_option = false;
if (skip_next) {
@ -754,7 +754,7 @@ void ArgsParser::autocomplete(FILE* file, StringView program_name, Span<char con
// Look for a long option
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())
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) {
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("invariant_offset", has_invariant ? option_to_complete.length() : 0u);
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) {
if (option.hide_mode != OptionHideMode::None)
continue;
StringView option_string = option.long_name;
StringView option_string { option.long_name, strlen(option.long_name) };
if (option_string.starts_with(option_pattern)) {
write_completion("--{}", option, true, option_string);
}

View file

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

View file

@ -83,7 +83,7 @@ static String canonicalize_path(String path)
return LexicalPath::canonicalized_path(move(path));
char* cwd = getcwd(nullptr, 0);
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)

View file

@ -970,7 +970,8 @@ ErrorOr<void> exec(StringView filename, Span<StringView> arguments, SearchInPath
};
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())
path = "/bin:/usr/bin";
auto parts = path.split_view(':');

View file

@ -23,7 +23,7 @@ static void parse_sockets_from_system_server()
return;
}
for (auto& socket : StringView(sockets).split_view(' ')) {
for (auto& socket : StringView { sockets, strlen(sockets) }.split_view(' ')) {
auto params = socket.split_view(':');
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)
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())
return {};
if (!process_info_json_value.value().is_object())
@ -256,7 +257,8 @@ HashMap<String, String> Reader::metadata() const
}
if (!metadata_notes_entry)
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())
return {};
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);
auto const* region_name_ptr = bit_cast<char const*>(raw_data.offset_pointer(raw_data.size()));
MemoryRegionInfo memory_region_info {
raw_memory_region_info.header,
raw_memory_region_info.region_start,
raw_memory_region_info.region_end,
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);
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] = '$';
Crypto::Hash::SHA256 sha;
sha.update(key);
sha.update(StringView { key, strlen(key) });
sha.update((u8 const*)salt_value, salt_len);
auto digest = sha.digest();

View file

@ -417,7 +417,7 @@ StringView Parser::version() const
StringView Parser::legacy_manufacturer_id() const
{
return m_legacy_manufacturer_id;
return { m_legacy_manufacturer_id, strlen(m_legacy_manufacturer_id) };
}
#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);
ScopeGuard unlock_guard = [] { __pthread_mutex_unlock(&s_loader_lock); };
StringView symbol_name_view { symbol_name, strlen(symbol_name) };
Optional<DynamicObject::SymbolLookupResult> symbol;
if (handle) {
auto object = static_cast<DynamicObject*>(handle);
symbol = object->lookup_symbol(symbol_name);
symbol = object->lookup_symbol(symbol_name_view);
} else {
// 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
symbol = DynamicLinker::lookup_global_symbol(symbol_name);
symbol = DynamicLinker::lookup_global_symbol(symbol_name_view);
}
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)
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()
{
for (char** env = s_envp; *env; ++env) {
StringView env_string { *env };
StringView env_string { *env, strlen(*env) };
if (env_string == "_LOADER_BREAKPOINT=1"sv) {
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
{
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

View file

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

View file

@ -125,7 +125,7 @@ void Window::show()
Gfx::IntRect 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) {
launch_origin_rect = Gfx::IntRect {
parts[0].to_int().value_or(0),

View file

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

View file

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

View file

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

View file

@ -64,7 +64,8 @@ private:
String ASTNode::class_name() const
{
// 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)

View file

@ -15,12 +15,12 @@ namespace JS {
// U+2028 LINE SEPARATOR
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 };
// U+2029 PARAGRAPH SEPARATOR
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 };
// U+00A0 NO BREAK SPACE

View file

@ -544,7 +544,7 @@ void Editor::initialize()
m_configuration.set(Configuration::NonInteractive);
} else {
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);
else
m_configuration.set(Configuration::NoEscapeSequences);

View file

@ -34,7 +34,7 @@ int main(int argc, char** argv)
Vector<StringView> arguments;
arguments.ensure_capacity(argc);
for (int i = 0; i < argc; ++i)
arguments.unchecked_append(argv[i]);
arguments.unchecked_append({ argv[i], strlen(argv[i]) });
auto result = serenity_main({
.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;
StringView string_view { string, strlen(string) };
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
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) {
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;
if (!checked_env_for_deadly) {
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
if (!options.is_null()) {
if (options.contains("halt_on_error=1"))

View file

@ -82,7 +82,7 @@ StringView system_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)

View file

@ -574,7 +574,8 @@ bool Node::is_root_element() 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

View file

@ -214,8 +214,17 @@ public:
MACAddress const& chaddr() const { return *(MACAddress const*)&m_chaddr[0]; }
void set_chaddr(MACAddress const& mac) { *(MACAddress*)&m_chaddr[0] = mac; }
StringView sname() const { return { (char const*)&m_sname[0] }; }
StringView file() const { return { (char const*)&m_file[0] }; }
StringView sname() const
{
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:
NetworkOrdered<u8> m_op;

View file

@ -35,7 +35,7 @@ int Shell::builtin_dump(int argc, char const** argv)
if (argc != 2)
return 1;
Parser { argv[1] }.parse()->dump(0);
Parser { StringView { argv[1], strlen(argv[1]) } }.parse()->dump(0);
return 0;
}
@ -124,7 +124,8 @@ int Shell::builtin_bg(int argc, char const** argv)
.name = "job-id",
.min_values = 0,
.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)
if (auto number = value.to_uint(); number.has_value()) {
job_id = number.value();
@ -497,7 +498,8 @@ int Shell::builtin_fg(int argc, char const** argv)
.name = "job-id",
.min_values = 0,
.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)
if (auto number = value.to_uint(); number.has_value()) {
job_id = number.value();
@ -568,7 +570,8 @@ int Shell::builtin_disown(int argc, char const** argv)
.name = "job-id",
.min_values = 0,
.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)
if (auto number = value.to_uint(); number.has_value()) {
job_ids.append(number.value());
@ -721,7 +724,7 @@ int Shell::builtin_pushd(int argc, char const** argv)
if (argc == 2) {
directory_stack.append(cwd.characters());
if (argv[1][0] == '/') {
path_builder.append(argv[1]);
path_builder.append({ argv[1], strlen(argv[1]) });
} else {
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] == '/') {
path_builder.append(arg);
path_builder.append({ arg, strlen(arg) });
} else
path_builder.appendff("{}/{}", cwd, arg);
}
@ -969,7 +972,8 @@ int Shell::builtin_wait(int argc, char const** argv)
.name = "job-id",
.min_values = 0,
.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)
if (auto number = value.to_uint(); number.has_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'
Vector<String> replaced_values;
auto kill_path = find_in_path("kill");
auto kill_path = find_in_path("kill"sv);
if (kill_path.is_empty()) {
warnln("kill: `kill' not found in PATH");
return 126;
}
replaced_values.append(kill_path);
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());
if (job) {
replaced_values.append(String::number(job->pid()));
@ -1240,7 +1244,7 @@ int Shell::builtin_argsparser_parse(int argc, char const** argv)
return false;
}
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()) {
auto value = result.release_value();
if (treat_arg_as_list)
@ -1262,7 +1266,7 @@ int Shell::builtin_argsparser_parse(int argc, char const** argv)
return false;
}
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()) {
auto value = result.release_value();
if (treat_arg_as_list)
@ -1345,7 +1349,7 @@ int Shell::builtin_argsparser_parse(int argc, char const** argv)
return false;
}
StringView ty = name;
StringView ty { name, strlen(name) };
if (ty == "bool") {
if (auto option = current.get_pointer<Core::ArgsParser::Option>()) {
if (option->value_name != nullptr) {
@ -1499,7 +1503,7 @@ int Shell::builtin_argsparser_parse(int argc, char const** argv)
return false;
}
auto number = StringView(value).to_uint();
auto number = StringView { value, strlen(value) }.to_uint();
if (!number.has_value()) {
warnln("Invalid value for --min: '{}', expected a non-negative number", value);
return false;
@ -1527,7 +1531,7 @@ int Shell::builtin_argsparser_parse(int argc, char const** argv)
return false;
}
auto number = StringView(value).to_uint();
auto number = StringView { value, strlen(value) }.to_uint();
if (!number.has_value()) {
warnln("Invalid value for --max: '{}', expected a non-negative number", value);
return false;

View file

@ -110,7 +110,7 @@ String Shell::prompt() const
builder.append(username);
break;
case 'h':
builder.append(hostname);
builder.append({ hostname, strlen(hostname) });
break;
case 'w': {
String home_path = getenv("HOME");
@ -1607,7 +1607,7 @@ Vector<Line::CompletionSuggestion> Shell::complete_variable(StringView name, siz
// Look at the environment.
for (auto i = 0; environ[i]; ++i) {
auto entry = StringView { environ[i] };
StringView entry { environ[i], strlen(environ[i]) };
if (entry.starts_with(pattern)) {
auto parts = entry.split_view('=');
if (parts.is_empty() || parts.first().is_empty())
@ -2183,7 +2183,10 @@ Shell::Shell()
// Add the default PATH vars.
{
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())
path.append(":");
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)
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();
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",
0,
"time-type",
[&du_option](StringView s) {
if (s == "mtime"sv || s == "modification"sv)
[&du_option](auto const* option_ptr) {
StringView option { option_ptr, strlen(option_ptr) };
if (option == "mtime"sv || option == "modification"sv)
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;
else if (s == "atime"sv || s == "access"sv)
else if (option == "atime"sv || option == "access"sv)
du_option.time_type = DuOption::TimeType::Access;
else
return false;

View file

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

View file

@ -19,7 +19,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
}
for (;;) {
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]))
TRY(Core::System::write(1, str.bytes()));
if (feof(stdin))

View file

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

View file

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

View file

@ -416,7 +416,7 @@ static int do_file_system_object_long(char const* path)
continue;
StringBuilder builder;
builder.append(path);
builder.append({ path, strlen(path) });
builder.append('/');
builder.append(metadata.name);
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) {
auto& name = files[i].name;
StringBuilder builder;
builder.append(path);
builder.append({ path, strlen(path) });
builder.append('/');
builder.append(name);
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;
StringBuilder builder;
builder.append(path);
builder.append({ path, strlen(path) });
builder.append('/');
builder.append(metadata.name);
metadata.path = builder.to_string();

View file

@ -73,11 +73,13 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
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
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 {
LexicalPath template_path(file_template);
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* hostent = gethostbyaddr(&addr, sizeof(in_addr), AF_INET);
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())
peer_address = host_name;
}
@ -195,7 +195,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
if (!flag_numeric) {
auto service = getservbyport(htons(if_object.get("peer_port").to_u32()), "tcp");
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())
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* hostent = gethostbyaddr(&addr, sizeof(in_addr), AF_INET);
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())
local_address = host_name;
}
@ -217,7 +217,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
if (!flag_numeric) {
auto service = getservbyport(htons(if_object.get("local_port").to_u32()), "tcp");
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())
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* hostent = gethostbyaddr(&addr, sizeof(in_addr), AF_INET);
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())
local_address = host_name;
}
@ -279,7 +279,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
if (!flag_numeric) {
auto service = getservbyport(htons(if_object.get("local_port").to_u32()), "udp");
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())
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* hostent = gethostbyaddr(&addr, sizeof(in_addr), AF_INET);
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())
peer_address = host_name;
}
@ -301,7 +301,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
if (!flag_numeric) {
auto service = getservbyport(htons(if_object.get("peer_port").to_u32()), "udp");
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())
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::close(pipefd[0]));
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));
perror("exec");
exit(1);

View file

@ -63,7 +63,7 @@ ErrorOr<int> serenity_main(Main::Arguments args)
if (!strcmp(omit_pid_value, "%PPID")) {
pid_to_omit = getppid();
} 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()) {
warnln("Invalid value for -o");
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;
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('=');
if (!maybe_needle.has_value())

View file

@ -170,7 +170,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
.short_name = 'H',
.value_name = "header-value",
.accept_value = [&](auto* s) {
StringView header { s };
StringView header { s, strlen(s) };
auto split = header.find(':');
if (!split.has_value())
return false;
@ -316,7 +316,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
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();
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) {
if (option != nullptr) {
for (auto syscall : StringView(option).split_view(','))
for (auto syscall : StringView { option, strlen(option) }.split_view(','))
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;
parameters.ensure_capacity(parameter_count);
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 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',
.value_name = "path",
.accept_value = [&](auto* s) {
StringView path { s };
StringView path { s, strlen(s) };
if (path.is_empty())
return false;
auto maybe_error = Core::System::unveil(path, permissions);
@ -55,7 +55,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
.min_values = 0,
.max_values = INT_MAX,
.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())
warnln("'{}' - fail: {}", s, maybe_error.error());
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[])
{
StringView arg = argv[optind];
StringView arg { argv[optind], strlen(argv[optind]) };
if (arg.is_null()) {
return {};
}
@ -332,20 +332,24 @@ static OwnPtr<Condition> parse_simple_expression(char* argv[])
if (arg == "(") {
optind++;
auto command = parse_complex_expression(argv);
if (command && argv[optind] && StringView(argv[++optind]) == ")")
return command;
if (command && argv[optind]) {
auto const* next_option = argv[++optind];
if (StringView { next_option, strlen(next_option) } == ")")
return command;
}
fatal_error("Unmatched \033[1m(");
}
// Try to read a unary op.
if (arg.starts_with('-') && arg.length() == 2) {
optind++;
if (should_treat_expression_as_single_string(argv[optind])) {
if (should_treat_expression_as_single_string({ argv[optind], strlen(argv[optind]) })) {
--optind;
return make<StringCompare>(move(arg), "", StringCompare::NotEqual);
}
StringView value = argv[optind];
StringView value { argv[optind], strlen(argv[optind]) };
switch (arg[1]) {
case 'b':
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>.
auto lhs = arg;
arg = argv[++optind];
arg = get_next_arg();
if (arg == "=") {
StringView rhs = argv[++optind];
StringView rhs = get_next_arg();
return make<StringCompare>(lhs, rhs, StringCompare::Equal);
} else if (arg == "!=") {
StringView rhs = argv[++optind];
StringView rhs = get_next_arg();
return make<StringCompare>(lhs, rhs, StringCompare::NotEqual);
} else if (arg == "-eq") {
StringView rhs = argv[++optind];
StringView rhs = get_next_arg();
return make<NumericCompare>(lhs, rhs, NumericCompare::Equal);
} else if (arg == "-ge") {
StringView rhs = argv[++optind];
StringView rhs = get_next_arg();
return make<NumericCompare>(lhs, rhs, NumericCompare::GreaterOrEqual);
} else if (arg == "-gt") {
StringView rhs = argv[++optind];
StringView rhs = get_next_arg();
return make<NumericCompare>(lhs, rhs, NumericCompare::Greater);
} else if (arg == "-le") {
StringView rhs = argv[++optind];
StringView rhs = get_next_arg();
return make<NumericCompare>(lhs, rhs, NumericCompare::LessOrEqual);
} else if (arg == "-lt") {
StringView rhs = argv[++optind];
StringView rhs = get_next_arg();
return make<NumericCompare>(lhs, rhs, NumericCompare::Less);
} else if (arg == "-ne") {
StringView rhs = argv[++optind];
StringView rhs = get_next_arg();
return make<NumericCompare>(lhs, rhs, NumericCompare::NotEqual);
} else if (arg == "-ef") {
StringView rhs = argv[++optind];
StringView rhs = get_next_arg();
return make<FileCompare>(lhs, rhs, FileCompare::Same);
} else if (arg == "-nt") {
StringView rhs = argv[++optind];
StringView rhs = get_next_arg();
return make<FileCompare>(lhs, rhs, FileCompare::ModificationTimestampGreater);
} else if (arg == "-ot") {
StringView rhs = argv[++optind];
StringView rhs = get_next_arg();
return make<FileCompare>(lhs, rhs, FileCompare::ModificationTimestampLess);
} else if (arg == "-o" || arg == "-a") {
// '-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])
fatal_error("expected an expression");
StringView arg = argv[++optind];
auto const* arg_ptr = argv[++optind];
StringView arg { arg_ptr, strlen(arg_ptr) };
enum {
AndOp,

View file

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

View file

@ -62,7 +62,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
if (move_home) {
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);

View file

@ -294,7 +294,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
.short_name = 'l',
.value_name = "file",
.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);
return true;
}
@ -308,7 +308,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
.short_name = 0,
.value_name = "u64",
.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());
return true;
}

View file

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