[Native] Join paths without dynamic strings - #12511
Conversation
There was a problem hiding this comment.
Pull request overview
Replaces dynamic fallback-path construction with bounded, caller-owned storage for CoreCLR/NativeAOT logging.
Changes:
- Adds
Util::join_pathswith separator handling and capacity checks. - Uses fixed stack storage for gref/lref fallback paths.
- Skips and logs paths exceeding buffer capacity.
Show a summary per file
| File | Description |
|---|---|
src/native/clr/runtime-base/logger.cc |
Builds fallback log paths without dynamic strings. |
src/native/clr/include/runtime-base/util.hh |
Adds the bounded path-joining helper. |
Review details
Suppressed comments (4)
src/native/clr/include/runtime-base/util.hh:343
- 💡 Maintainability — The separator behavior here is intentionally different from
path_combine: it strips one leading/only whenfirstalready ends with/, while empty components are copied unchanged. Please document this contract next to the helper, including thatbuffer_sizeincludes space for the terminating NUL, so future callers do not infer a different normalization policy.
bool remove_duplicate_separator = first.ends_with ('/') && second.starts_with ('/');
bool add_separator = !first.empty () && !second.empty () && !first.ends_with ('/') && !second.starts_with ('/');
size_t second_offset = remove_duplicate_separator ? 1uz : 0uz;
src/native/clr/include/runtime-base/util.hh:363
- 💡 Native C++ —
<cstring>guarantees the declaration instd, but this unqualified call relies on implementation-provided global namespace injection. Usestd::memcpyhere to keep the new helper portable.
Rule: Use C++ standard headers and names
memcpy (destination, second.data () + second_offset, second_length);
src/native/clr/include/runtime-base/util.hh:355
- 💡 Native C++ —
<cstring>guarantees the declaration instd, but this unqualified call relies on implementation-provided global namespace injection. Usestd::memcpyhere to keep the new helper portable.
Rule: Use C++ standard headers and names
memcpy (destination, first.data (), first.length ());
src/native/clr/runtime-base/logger.cc:84
- 💡 Error message — When the fallback path is rejected, this is the only diagnostic, but it does not identify the directory or the capacity that was exceeded. Include the relevant lengths and
path_buffer.size()so users can determine which configured path caused reference logging to be skipped.
log_warnf (category, "Unable to open fallback log file: path is too long");
- Files reviewed: 2/2 changed files
- Comments generated: 0
- Review effort level: Lite
|
/review |
|
✅ Android PR Reviewer completed successfully!
|
There was a problem hiding this comment.
The bounded helper is a clear improvement over implicit dynamic path storage, and all 44 CI checks are green. The remaining concern is direct boundary coverage for the new duplicated path primitive before it becomes a broader replacement for path_combine.
Generated by Android PR Reviewer for #12511 · gpt56 · 101.4 AIC · ⌖ 17.1 AIC · ⊞ 25.7K
Comment /review to run again
Add a bounded caller-buffer path join helper and use it for reference log fallback paths, removing one dynamic_local_string use shared by CoreCLR and NativeAOT. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use caller-owned buffers for XDG directories, environment override files, and libmonodroid detection. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Return bytes written including the terminating NUL so callers can use their buffers directly and create string views only when needed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Return -1 on failure and the path length excluding the terminating NUL on success, matching strlen-style length semantics. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The join_paths migrations remove the remaining callers of the local-string file_exists and path_combine helpers, so delete the dead overload family and strings.hh dependency. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use the CLR path capacity constant directly now that XDG paths use caller-owned buffers. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
9dfbdc6 to
b558fd4
Compare
Preserve dynamic_local_string semantics by treating SENSIBLE_PATH_MAX as an inline-storage threshold rather than a path limit. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep exact-size path allocation independent of libc++ and free each temporary after its final consumer. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Calculate the exact path size, use the runtime-specific local buffer below its sensible threshold, and fall back to malloc only for larger paths. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Avoid redeclaring the existing result while retaining cleanup before returning. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
/review |
|
✅ Android PR Reviewer completed successfully!
|
There was a problem hiding this comment.
⚠️ Needs Changes
Findings: 0 errors · 1 warning · 0 suggestions
The exact-size calculation, overflow checks, separator handling, and NUL termination are clear, and the migrated call sites pair their allocations correctly. The new temporary-buffer API should preserve RAII so later early returns cannot leak heap-backed paths. The prior unresolved review feedback requesting focused boundary tests also still applies.
CI is still in progress: 13 of 44 checks have completed successfully, with 30 running and 1 queued; no failures are currently reported.
Generated by Android PR Reviewer for #12511 · gpt56 · 98.8 AIC · ⌖ 8.91 AIC · ⊞ 25.7K
Comment /review to run again
Retry path formatting with exact heap storage only when the sensible stack buffer is insufficient. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Return the selected stack or heap buffer from the path helper and centralize conditional heap cleanup. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Rely on the C guarantee that free accepts null pointers and name stack-backed storage explicitly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use one non-template path helper implementation and make each caller provide its stack capacity. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
/review |
|
✅ Android PR Reviewer completed successfully!
|
Remove heap-buffer out parameters, free only returned heap pointers, and keep the former static XDG path buffer stack-only. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
⚠️ Needs Changes
Findings: 0 errors · 0 warnings · 1 suggestion.
The stack-first/exact-size fallback contract is applied consistently across the migrated call sites, and cleanup covers each exit path. One redundant startup filesystem operation is called out inline. CI is still in progress (2 checks passed, 6 running, 1 queued), so this cannot be considered green yet.
Generated by Android PR Reviewer for #12511 · gpt56 · 97.5 AIC · ⌖ 19.6 AIC · ⊞ 25.7K
Comment /review to run again
Create the fallback logging directory only once before opening the fallback file. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Give the length-returning formatter a distinct name while preserving join_paths as the stack-or-heap pointer API. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Summary
Replace shared CoreCLR/NativeAOT path-building local strings with C buffers while preserving the original distinction between static and dynamic storage.
Changes
malloc()buffer directlystatic_local_stringXDG path stack-onlylibmonodroid.sodetection, and timing output pathsValidation