1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 05:57:45 +00:00

AK+Everywhere: Remove the null state of DeprecatedString

This commit removes DeprecatedString's "null" state, and replaces all
its users with one of the following:
- A normal, empty DeprecatedString
- Optional<DeprecatedString>

Note that null states of DeprecatedFlyString/StringView/etc are *not*
affected by this commit. However, DeprecatedString::empty() is now
considered equal to a null StringView.
This commit is contained in:
Ali Mohammad Pur 2023-10-10 15:00:58 +03:30 committed by Ali Mohammad Pur
parent daf6d8173c
commit aeee98b3a1
189 changed files with 597 additions and 652 deletions

View file

@ -162,16 +162,17 @@ ErrorOr<Vector<Account>> Account::all([[maybe_unused]] Read options)
bool Account::authenticate(SecretString const& password) const
{
// If there was no shadow entry for this account, authentication always fails.
if (m_password_hash.is_null())
if (!m_password_hash.has_value())
return false;
// An empty passwd field indicates that no password is required to log in.
if (m_password_hash.is_empty())
if (m_password_hash->is_empty())
return true;
// FIXME: Use crypt_r if it can be built in lagom.
char* hash = crypt(password.characters(), m_password_hash.characters());
return hash != nullptr && AK::timing_safe_compare(hash, m_password_hash.characters(), m_password_hash.length());
auto const bytes = m_password_hash->characters();
char* hash = crypt(password.characters(), bytes);
return hash != nullptr && AK::timing_safe_compare(hash, bytes, m_password_hash->length());
}
ErrorOr<void> Account::login() const
@ -190,24 +191,25 @@ void Account::set_password(SecretString const& password)
void Account::set_password_enabled(bool enabled)
{
if (enabled && m_password_hash != "" && m_password_hash[0] == '!') {
m_password_hash = m_password_hash.substring(1, m_password_hash.length() - 1);
} else if (!enabled && (m_password_hash == "" || m_password_hash[0] != '!')) {
auto flattened_password_hash = m_password_hash.value_or(DeprecatedString::empty());
if (enabled && !flattened_password_hash.is_empty() && flattened_password_hash[0] == '!') {
m_password_hash = flattened_password_hash.substring(1, flattened_password_hash.length() - 1);
} else if (!enabled && (flattened_password_hash.is_empty() || flattened_password_hash[0] != '!')) {
StringBuilder builder;
builder.append('!');
builder.append(m_password_hash);
builder.append(flattened_password_hash);
m_password_hash = builder.to_deprecated_string();
}
}
void Account::delete_password()
{
m_password_hash = "";
m_password_hash = DeprecatedString::empty();
}
Account::Account(passwd const& pwd, spwd const& spwd, Vector<gid_t> extra_gids)
: m_username(pwd.pw_name)
, m_password_hash(spwd.sp_pwdp)
, m_password_hash(spwd.sp_pwdp ? Optional<DeprecatedString>(spwd.sp_pwdp) : OptionalNone {})
, m_uid(pwd.pw_uid)
, m_gid(pwd.pw_gid)
, m_gecos(pwd.pw_gecos)
@ -300,7 +302,7 @@ ErrorOr<DeprecatedString> Account::generate_shadow_file() const
if (p->sp_namp == m_username) {
if (m_deleted)
continue;
builder.appendff("{}:{}", m_username, m_password_hash);
builder.appendff("{}:{}", m_username, m_password_hash.value_or(DeprecatedString::empty()));
} else
builder.appendff("{}:{}", p->sp_namp, p->sp_pwdp);

View file

@ -41,7 +41,7 @@ public:
ErrorOr<void> login() const;
DeprecatedString username() const { return m_username; }
DeprecatedString password_hash() const { return m_password_hash; }
DeprecatedString password_hash() const { return m_password_hash.value_or(DeprecatedString::empty()); }
// Setters only affect in-memory copy of password.
// You must call sync to apply changes.
@ -56,9 +56,9 @@ public:
void set_extra_gids(Vector<gid_t> extra_gids) { m_extra_gids = move(extra_gids); }
void delete_password();
// A null password means that this account was missing from /etc/shadow.
// A nonexistent password means that this account was missing from /etc/shadow.
// It's considered to have a password in that case, and authentication will always fail.
bool has_password() const { return !m_password_hash.is_empty() || m_password_hash.is_null(); }
bool has_password() const { return !m_password_hash.has_value() || !m_password_hash->is_empty(); }
uid_t uid() const { return m_uid; }
gid_t gid() const { return m_gid; }
@ -82,7 +82,7 @@ private:
DeprecatedString m_username;
DeprecatedString m_password_hash;
Optional<DeprecatedString> m_password_hash;
uid_t m_uid { 0 };
gid_t m_gid { 0 };
DeprecatedString m_gecos;

View file

@ -140,11 +140,10 @@ ErrorOr<void> ConfigFile::reparse()
return {};
}
DeprecatedString ConfigFile::read_entry(DeprecatedString const& group, DeprecatedString const& key, DeprecatedString const& default_value) const
Optional<DeprecatedString> ConfigFile::read_entry_optional(const AK::DeprecatedString& group, const AK::DeprecatedString& key) const
{
if (!has_key(group, key)) {
return default_value;
}
if (!has_key(group, key))
return {};
auto it = m_groups.find(group);
auto jt = it->value.find(key);
return jt->value;

View file

@ -42,7 +42,11 @@ public:
size_t num_groups() const { return m_groups.size(); }
DeprecatedString read_entry(DeprecatedString const& group, DeprecatedString const& key, DeprecatedString const& default_value = DeprecatedString()) const;
DeprecatedString read_entry(DeprecatedString const& group, DeprecatedString const& key, DeprecatedString const& default_value = {}) const
{
return read_entry_optional(group, key).value_or(default_value);
}
Optional<DeprecatedString> read_entry_optional(DeprecatedString const& group, DeprecatedString const& key) const;
bool read_bool_entry(DeprecatedString const& group, DeprecatedString const& key, bool default_value = false) const;
template<Integral T = int>
@ -52,9 +56,9 @@ public:
return default_value;
if constexpr (IsSigned<T>)
return read_entry(group, key).to_int<T>().value_or(default_value);
return read_entry(group, key, "").to_int<T>().value_or(default_value);
else
return read_entry(group, key).to_uint<T>().value_or(default_value);
return read_entry(group, key, "").to_uint<T>().value_or(default_value);
}
void write_entry(DeprecatedString const& group, DeprecatedString const& key, DeprecatedString const& value);

View file

@ -189,29 +189,40 @@ static ErrorOr<void> unveil_dynamic_loader()
ErrorOr<void> unveil(StringView path, StringView permissions)
{
auto const parsed_path = TRY(Core::SessionManagement::parse_path_with_sid(path));
if (permissions.contains('x'))
TRY(unveil_dynamic_loader());
Syscall::SC_unveil_params params {
static_cast<int>(UnveilFlags::CurrentProgram),
{ parsed_path.characters(), parsed_path.length() },
{ permissions.characters_without_null_termination(), permissions.length() },
{ nullptr, 0 },
{ nullptr, 0 },
};
DeprecatedString parsed_path;
if (!path.is_null()) {
parsed_path = TRY(Core::SessionManagement::parse_path_with_sid(path));
params.path = { parsed_path.characters(), parsed_path.length() };
params.permissions = { permissions.characters_without_null_termination(), permissions.length() };
}
int rc = syscall(SC_unveil, &params);
HANDLE_SYSCALL_RETURN_VALUE("unveil", rc, {});
}
ErrorOr<void> unveil_after_exec(StringView path, StringView permissions)
{
auto const parsed_path = TRY(Core::SessionManagement::parse_path_with_sid(path));
DeprecatedString parsed_path;
Syscall::SC_unveil_params params {
static_cast<int>(UnveilFlags::AfterExec),
{ parsed_path.characters(), parsed_path.length() },
{ nullptr, 0 },
{ permissions.characters_without_null_termination(), permissions.length() },
};
if (!path.is_null()) {
parsed_path = TRY(Core::SessionManagement::parse_path_with_sid(path));
params.path = { parsed_path.characters(), parsed_path.length() };
}
int rc = syscall(SC_unveil, &params);
HANDLE_SYSCALL_RETURN_VALUE("unveil", rc, {});
}

View file

@ -41,7 +41,7 @@ ErrorOr<NonnullOwnPtr<Core::LocalSocket>> take_over_socket_from_system_server(De
parse_sockets_from_system_server();
int fd;
if (socket_path.is_null()) {
if (socket_path.is_empty()) {
// We want the first (and only) socket.
VERIFY(s_overtaken_sockets.size() == 1);
fd = s_overtaken_sockets.begin()->value;