Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 44 additions & 27 deletions src/main/java/com/github/_1c_syntax/bsl/mdclasses/MDClasses.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,19 @@
import org.apache.commons.io.FilenameUtils;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.AccessDeniedException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@UtilityClass
@Slf4j
Expand Down Expand Up @@ -161,7 +164,7 @@
if (mdcs.isEmpty()) {
result = Configuration.EMPTY;
} else if (mdcs.size() == 1) {
result = mdcs.get(0);
result = mdcs.getFirst();
} else {
var mdc = mdcs.stream().filter(Configuration.class::isInstance).map(Configuration.class::cast).findFirst();
var cf = mdc.orElse(Configuration.EMPTY);
Expand All @@ -173,10 +176,10 @@
if (cf.isEmpty()) {
if (extensions.isEmpty()) {
// вернем первое значение, т.к. там нет ни конфы, ни расширений
return mdcs.get(0);
return mdcs.getFirst();
} else if (extensions.size() == 1) {
// есть одно расширение, вернем его
return extensions.get(0);
return extensions.getFirst();
}
} else if (extensions.isEmpty()) {
// расширений нет, вернем конфигурацию
Expand Down Expand Up @@ -264,37 +267,51 @@
return result;
}

private List<Path> findFiles(Path sourcePath, Pattern pattern) {

Check failure on line 270 in src/main/java/com/github/_1c_syntax/bsl/mdclasses/MDClasses.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this method to reduce its Cognitive Complexity from 16 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=1c-syntax_mdclasses&issues=AZ8SVJhQeE8Nr9EhfC8A&open=AZ8SVJhQeE8Nr9EhfC8A&pullRequest=625
List<Path> listPath = new ArrayList<>();
var excludeFolders = mdoTypeGroupNames();
excludeFolders.add("Ext");
try (Stream<Path> stream = Files.find(sourcePath, Integer.MAX_VALUE,
(Path path, BasicFileAttributes basicFileAttributes) -> {
if (!basicFileAttributes.isRegularFile()) {
return false;
}
List<Path> listPath = new ArrayList<>();

var parentName = path.getParent().getFileName().toString();
var parentParentName = "";
if (path.getParent().getParent() != null && path.getParent().getParent().getFileName() != null) {
parentParentName = path.getParent().getParent().getFileName().toString();
try {
Files.walkFileTree(sourcePath, new SimpleFileVisitor<>() {

Check warning on line 276 in src/main/java/com/github/_1c_syntax/bsl/mdclasses/MDClasses.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Reduce this anonymous class number of lines from 33 to at most 20, or make it a named class.

See more on https://sonarcloud.io/project/issues?id=1c-syntax_mdclasses&issues=AZ8SVJhQeE8Nr9EhfC7_&open=AZ8SVJhQeE8Nr9EhfC7_&pullRequest=625
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) {
if (exc instanceof AccessDeniedException) {
LOGGER.warn("Skipping directory (access denied): {}", file);
return FileVisitResult.CONTINUE;
}
throw new UncheckedIOException(exc);
}

if (excludeFolders.contains(parentName) || excludeFolders.contains(parentParentName)) {
return false;
}
var fileName = path.getFileName().toString();
var ext = FilenameUtils.getExtension(fileName);
if (!("xml".equals(ext) || "mdo".equals(ext))) {
return false;
}
@Override
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) {
if (!attrs.isRegularFile()) {
return FileVisitResult.CONTINUE;
}

return pattern.matcher(fileName).matches();
}
)) {
listPath = stream.toList();
var parentName = path.getParent().getFileName().toString();
var parentParentName = "";
if (path.getParent().getParent() != null && path.getParent().getParent().getFileName() != null) {
parentParentName = path.getParent().getParent().getFileName().toString();
}
Comment on lines +292 to +296

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

NPE risk when a file resides directly under the filesystem root.

path.getParent().getFileName() returns null when the parent is a root path (e.g. /). Calling .toString() on it then throws NullPointerException. Since this PR specifically targets traversal of / and protected system paths (issue #609), a regular file located directly under / (parent /, getFileName() == null) would crash traversal — defeating the purpose of the fix. Note the grandparent computation at Line 294 already guards against a null getFileName(), but the parent at Line 292 does not.

🐛 Proposed fix to guard the parent name
-          var parentName = path.getParent().getFileName().toString();
-          var parentParentName = "";
-          if (path.getParent().getParent() != null && path.getParent().getParent().getFileName() != null) {
-            parentParentName = path.getParent().getParent().getFileName().toString();
-          }
+          var parent = path.getParent();
+          var parentName = "";
+          if (parent != null && parent.getFileName() != null) {
+            parentName = parent.getFileName().toString();
+          }
+          var parentParentName = "";
+          if (parent != null && parent.getParent() != null && parent.getParent().getFileName() != null) {
+            parentParentName = parent.getParent().getFileName().toString();
+          }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
var parentName = path.getParent().getFileName().toString();
var parentParentName = "";
if (path.getParent().getParent() != null && path.getParent().getParent().getFileName() != null) {
parentParentName = path.getParent().getParent().getFileName().toString();
}
var parent = path.getParent();
var parentName = "";
if (parent != null && parent.getFileName() != null) {
parentName = parent.getFileName().toString();
}
var parentParentName = "";
if (parent != null && parent.getParent() != null && parent.getParent().getFileName() != null) {
parentParentName = parent.getParent().getFileName().toString();
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/com/github/_1c_syntax/bsl/mdclasses/MDClasses.java` around
lines 292 - 296, The parent-name extraction in MDClasses is still unsafe for
files directly under the filesystem root because path.getParent().getFileName()
can be null and then .toString() throws. Update the parentName handling in
MDClasses to mirror the existing parentParentName guard by checking both
getParent() and getFileName() before converting to a string, so traversal over
"/" and other root-level files does not fail.


if (excludeFolders.contains(parentName) || excludeFolders.contains(parentParentName)) {
return FileVisitResult.CONTINUE;
}
var fileName = path.getFileName().toString();
var ext = FilenameUtils.getExtension(fileName);
if (!("xml".equals(ext) || "mdo".equals(ext))) {
return FileVisitResult.CONTINUE;
}

if (pattern.matcher(fileName).matches()) {
listPath.add(path);
}
return FileVisitResult.CONTINUE;
}
});
} catch (IOException e) {
LOGGER.error("Error read files", e);
LOGGER.error("Error reading files", e);
}

return listPath;
Expand Down
Loading