[libc-commits] [libc] [libc] Add struct group header and group line parser (PR #224208)

Jeff Bailey via libc-commits libc-commits at lists.llvm.org
Thu Sep 17 09:51:42 PDT 2026


================
@@ -0,0 +1,199 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation of helper functions and parser for grp.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/grp/grp_utils.h"
+#include "hdr/errno_macros.h"
+#include "hdr/stdint_proxy.h"
+#include "hdr/types/gid_t.h"
+#include "hdr/types/size_t.h"
+#include "hdr/types/struct_group.h"
+#include "src/__support/CPP/span.h"
+#include "src/__support/ctype_utils.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/pwd/dynamic_buffer.h"
+#include "src/__support/pwd/field_tokenizer.h"
+#include "src/__support/pwd/flat_file_db.h"
+#include "src/__support/str_to_integer.h"
+
+#ifndef LIBC_COPT_GROUP_FILE_PATH
+#define LIBC_COPT_GROUP_FILE_PATH "/etc/group"
+#endif
+
+namespace LIBC_NAMESPACE_DECL {
+namespace {
+
+// TODO: Replace with cpp::count when available in
+// src/__support/CPP/algorithm.h.
+size_t count_group_members(cpp::span<const char> line) {
+  size_t max_members = 1;
+  for (char c : line) {
+    if (c == ',')
+      ++max_members;
+  }
+  return max_members;
+}
+
+// Parse fixed fields (name, passwd, gid).
+bool parse_group_fields(cpp::span<char> line, struct group *grp,
+                        cpp::span<char> *members_out) {
+  if (line.empty() || !grp || !members_out)
+    return false;
+
+  pwd::FieldTokenizer tokenizer(line, ':');
+
+  auto name = tokenizer.next_field();
+  if (!name || name->empty() || name->front() == '\0')
+    return false;
+  grp->gr_name = name->data();
+
+  auto passwd = tokenizer.next_field();
+  if (!passwd)
+    return false;
+  grp->gr_passwd = passwd->data();
+
+  auto gid_str = tokenizer.next_field();
+  if (!gid_str || gid_str->empty() || !internal::isdigit(gid_str->front()))
+    return false;
+  auto gid_res = internal::strtointeger<gid_t>(gid_str->data(), 10);
+  if (gid_res.has_error() || gid_res.parsed_len <= 0 ||
+      static_cast<size_t>(gid_res.parsed_len) + 1 != gid_str->size() ||
+      (*gid_str)[gid_res.parsed_len] != '\0')
----------------
kaladron wrote:

In the case of integer underflow - rare, but possible.

https://github.com/llvm/llvm-project/pull/224208


More information about the libc-commits mailing list