[libc-commits] [libc] [libc][stdlib] Avoid scanning values during environment lookup (PR #228633)
Jeff Bailey via libc-commits
libc-commits at lists.llvm.org
Mon Oct 5 05:04:41 PDT 2026
================
@@ -82,10 +82,33 @@ cpp::optional<size_t> EnvironmentManager::find_var(cpp::string_view name) {
if (!env_array)
return cpp::nullopt;
- for (size_t i = 0; i < count; i++) {
- cpp::string_view current(env_array[i]);
- if (current.starts_with(name) && current.size() > name.size() &&
- current[name.size()] == '=')
+ // Compare entries directly: constructing a string_view from the entry's C
+ // string would scan the entire value to determine the entry's length, even
+ // when the name does not match.
+ // Empty names, supported by putenv, match entries starting with '='.
+ const char first = name.empty() ? '=' : name.front();
+
+ // Reject a leading null so matching an empty entry cannot advance past its
+ // terminator when the comparison resumes at index 1.
+ if (first == '\0')
+ return cpp::nullopt;
+ const size_t start = name.empty() ? 0 : 1;
+
+ for (size_t i = 0; i < count; ++i) {
+ const char *entry = env_array[i];
+ // Reject entries with a different first character before comparing the
+ // rest.
+ if (entry[0] != first)
+ continue;
+
+ size_t j = start;
+ // Bound the comparison by the name's length and stop at a mismatch or null
+ // terminator, so shorter entries cannot cause an out-of-bounds read.
+ while (j < name.size() && entry[j] != '\0' && entry[j] == name[j])
----------------
kaladron wrote:
If you use inline_strncmp, I think both of the new checks you added above are also not needed, since it has the optimisations built into it.
https://github.com/llvm/llvm-project/pull/228633
More information about the libc-commits
mailing list