HPCC-35234 Ensure XRef handles trailing extensions correctly#21051
HPCC-35234 Ensure XRef handles trailing extensions correctly#21051jackdelv wants to merge 1 commit intohpcc-systems:candidate-10.0.xfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR aims to improve how XRef/DFS constructs and interprets part filenames when there are “extra” trailing extensions in masks (e.g., additional suffixes beyond the base/part naming).
Changes:
- Avoid appending
::when there is no current scope while building XRef scope prefixes. - Extend
constructPartFilenameto preserve “trailing” extensions frompmaskwhenlnameis already provided.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| dali/sasha/saxref.cpp | Adjusts scope prefix construction to avoid adding :: when scope is empty. |
| dali/base/dadfs.cpp | Adds logic to detect and append trailing extensions from pmask onto generated physical part names. |
| else if (!isEmptyString(pmask)) | ||
| { | ||
| // pmask may contain trailing extensions that aren't in lname | ||
| const char *ext = strchr(pmask, '.'); |
There was a problem hiding this comment.
strchr(pmask, '.') searches the entire string, so if pmask includes a directory path containing dots (e.g. /var/lib/hpcc/v1.2/data/file._$P$), ext will point into the directory portion, and tailExt may become incorrect (or misleadingly non-null). This can result in appending the wrong substring to fullname, producing malformed filenames. Consider finding dots only in the basename portion of pmask (after the last path separator), or use an existing path/filename utility in the codebase to locate extensions reliably.
| const char *ext = strchr(pmask, '.'); | |
| // Only consider dots in the basename portion (after the last path separator) | |
| const char *filePart = pmask; | |
| const char *lastSlash = strrchr(pmask, '/'); | |
| const char *lastBackslash = strrchr(pmask, '\\'); | |
| if (lastSlash || lastBackslash) | |
| { | |
| const char *lastSep = lastSlash; | |
| if (!lastSep || (lastBackslash && lastBackslash > lastSep)) | |
| lastSep = lastBackslash; | |
| filePart = lastSep + 1; | |
| } | |
| const char *ext = strchr(filePart, '.'); |
There was a problem hiding this comment.
pmask comes from cFileDesc::getNameMask and will only ever contain the file name.
| assertex(ext); // pmask should have at least one extension for the part mask | ||
| tailExt = strchr(ext+1, '.'); |
There was a problem hiding this comment.
The new assertex(ext) introduces a hard failure for any caller that passes a non-empty pmask without a . character (even if such masks were previously tolerated). Since this is a filename-construction helper, it’s safer to treat “no extension found” as “no trailing extension to append” (i.e., skip appending) rather than asserting and potentially aborting in production.
| assertex(ext); // pmask should have at least one extension for the part mask | |
| tailExt = strchr(ext+1, '.'); | |
| if (ext) | |
| tailExt = strchr(ext+1, '.'); |
There was a problem hiding this comment.
It may not be the best to error on this, but it should always be the case that the pmask have at least one extension. Otherwise it would not have been able to deduce the part mask and this file would not make it here. It would be treated as an external file.
|
Jira Issue: https://hpccsystems.atlassian.net//browse/HPCC-35234 Jirabot Action Result: |
Type of change:
Checklist:
Smoketest:
Testing: