|
| 1 | +diff --git a/extide/gradle/src/org/netbeans/modules/gradle/ProjectTrust.java b/extide/gradle/src/org/netbeans/modules/gradle/ProjectTrust.java |
| 2 | +index 1d7ad89a8714..216291f86fd4 100644 |
| 3 | +--- a/extide/gradle/src/org/netbeans/modules/gradle/ProjectTrust.java |
| 4 | ++++ b/extide/gradle/src/org/netbeans/modules/gradle/ProjectTrust.java |
| 5 | +@@ -25,10 +25,10 @@ |
| 6 | + import java.security.InvalidKeyException; |
| 7 | + import java.security.Key; |
| 8 | + import java.security.NoSuchAlgorithmException; |
| 9 | ++import java.security.SecureRandom; |
| 10 | + import java.util.Collections; |
| 11 | + import java.util.HashSet; |
| 12 | + import java.util.List; |
| 13 | +-import java.util.Random; |
| 14 | + import java.util.Set; |
| 15 | + import java.util.logging.Level; |
| 16 | + import java.util.logging.Logger; |
| 17 | +@@ -69,7 +69,7 @@ public class ProjectTrust { |
| 18 | + byte[] buf = prefs.getByteArray(KEY_SALT, null); |
| 19 | + if (buf == null) { |
| 20 | + buf = new byte[16]; |
| 21 | +- new Random().nextBytes(buf); |
| 22 | ++ new SecureRandom().nextBytes(buf); |
| 23 | + prefs.putByteArray(KEY_SALT, buf); |
| 24 | + } |
| 25 | + salt = buf; |
| 26 | +@@ -134,7 +134,7 @@ public void trustProject(Project project, boolean permanently) { |
| 27 | + if (permanently && !isTrustedPermanently(project)) { |
| 28 | + Path trustFile = getProjectTrustFile(project); |
| 29 | + byte[] rnd = new byte[16]; |
| 30 | +- new Random().nextBytes(rnd); |
| 31 | ++ new SecureRandom().nextBytes(rnd); |
| 32 | + String projectId = toHex(rnd); |
| 33 | + projectTrust.put(pathId, projectId); |
| 34 | + try { |
| 35 | +diff --git a/ide/projectapi/arch.xml b/ide/projectapi/arch.xml |
| 36 | +index e91502b7570b..81349ae3f7d0 100644 |
| 37 | +--- a/ide/projectapi/arch.xml |
| 38 | ++++ b/ide/projectapi/arch.xml |
| 39 | +@@ -509,8 +509,9 @@ Nothing. |
| 40 | + <p> |
| 41 | + <api name="project.limitScanRoot" category="friend" group="systemproperty" type="export"> |
| 42 | + <p> |
| 43 | +- If defined, limits search for a parent project to a certain subtree. The property defines <b>absolute path</b> of a folder |
| 44 | +- where upwards search for a project in parent folders is terminated. Queries outside of the root will not find any project. |
| 45 | ++ If defined, limits search for a parent project to a certain subtree. The property defines the <b>absolute path</b> of a folder |
| 46 | ++ where upwards search for a project in parent folders is terminated. Queries outside the root will not find any project. |
| 47 | ++ Multiple folders may be specified when delimited with OS-specific path separators (':' on *nix, ';' on Windows). |
| 48 | + Currently used for tests so the tested runtime does not escape the workdir. |
| 49 | + </p> |
| 50 | + </api> |
| 51 | +diff --git a/ide/projectapi/src/org/netbeans/modules/projectapi/SimpleFileOwnerQueryImplementation.java b/ide/projectapi/src/org/netbeans/modules/projectapi/SimpleFileOwnerQueryImplementation.java |
| 52 | +index 05b887129a52..bf4b435f4dbf 100644 |
| 53 | +--- a/ide/projectapi/src/org/netbeans/modules/projectapi/SimpleFileOwnerQueryImplementation.java |
| 54 | ++++ b/ide/projectapi/src/org/netbeans/modules/projectapi/SimpleFileOwnerQueryImplementation.java |
| 55 | +@@ -19,6 +19,7 @@ |
| 56 | + |
| 57 | + package org.netbeans.modules.projectapi; |
| 58 | + |
| 59 | ++import java.io.File; |
| 60 | + import java.io.IOException; |
| 61 | + import java.lang.ref.Reference; |
| 62 | + import java.lang.ref.WeakReference; |
| 63 | +@@ -27,10 +28,9 @@ |
| 64 | + import java.net.URISyntaxException; |
| 65 | + import java.net.URL; |
| 66 | + import java.util.ArrayList; |
| 67 | +-import java.util.Arrays; |
| 68 | + import java.util.Collections; |
| 69 | + import java.util.HashMap; |
| 70 | +-import java.util.HashSet; |
| 71 | ++import java.util.LinkedHashSet; |
| 72 | + import java.util.List; |
| 73 | + import java.util.Map; |
| 74 | + import java.util.Set; |
| 75 | +@@ -45,6 +45,7 @@ |
| 76 | + import org.netbeans.api.project.ProjectManager; |
| 77 | + import org.netbeans.spi.project.FileOwnerQueryImplementation; |
| 78 | + import org.openide.filesystems.FileObject; |
| 79 | ++import org.openide.filesystems.FileUtil; |
| 80 | + import org.openide.filesystems.URLMapper; |
| 81 | + import org.openide.util.BaseUtilities; |
| 82 | + import org.openide.util.NbPreferences; |
| 83 | +@@ -59,21 +60,19 @@ public class SimpleFileOwnerQueryImplementation implements FileOwnerQueryImpleme |
| 84 | + private static final Logger LOG = Logger.getLogger(SimpleFileOwnerQueryImplementation.class.getName()); |
| 85 | + private static final URI UNOWNED_URI = URI.create("http:unowned"); |
| 86 | + private static final Set<String> forbiddenFolders; |
| 87 | +- private static final String projectScanRoot; |
| 88 | ++ private static final Set<String> projectScanRoots; |
| 89 | + |
| 90 | + static { |
| 91 | +- Set<String> files = new HashSet<String>(); |
| 92 | +- String root = null; |
| 93 | ++ Set<String> folders = null; |
| 94 | ++ Set<String> roots = null; |
| 95 | + try { |
| 96 | +- root = System.getProperty("project.limitScanRoot"); // NOI18N |
| 97 | +- String forbidden = System.getProperty("project.forbiddenFolders", System.getProperty("versioning.forbiddenFolders", "")); //NOI18N |
| 98 | +- files.addAll(Arrays.asList(forbidden.split("\\;"))); //NOI18N |
| 99 | +- files.remove(""); //NOI18N |
| 100 | ++ roots = separatePaths(System.getProperty("project.limitScanRoot"), File.pathSeparator); //NOI18N |
| 101 | ++ folders = separatePaths(System.getProperty("project.forbiddenFolders", System.getProperty("versioning.forbiddenFolders")), ";"); //NOI18N |
| 102 | + } catch (Exception e) { |
| 103 | + LOG.log(Level.INFO, e.getMessage(), e); |
| 104 | + } |
| 105 | +- forbiddenFolders = files; |
| 106 | +- projectScanRoot = root; |
| 107 | ++ forbiddenFolders = folders == null ? Collections.emptySet() : folders; |
| 108 | ++ projectScanRoots = roots; |
| 109 | + } |
| 110 | + |
| 111 | + /** Do nothing */ |
| 112 | +@@ -113,7 +112,7 @@ public Project getOwner(FileObject f) { |
| 113 | + |
| 114 | + deserialize(); |
| 115 | + while (f != null) { |
| 116 | +- if (projectScanRoot != null && !f.getPath().startsWith(projectScanRoot)) { |
| 117 | ++ if (projectScanRoots != null && projectScanRoots.stream().noneMatch(f.getPath()::startsWith)) { |
| 118 | + break; |
| 119 | + } |
| 120 | + boolean folder = f.isFolder(); |
| 121 | +@@ -137,8 +136,8 @@ public Project getOwner(FileObject f) { |
| 122 | + } |
| 123 | + folders.add(f); |
| 124 | + if (!forbiddenFolders.contains(f.getPath()) && |
| 125 | +- !hasRoot(externalOwners.keySet(), f, folder, furi) && |
| 126 | +- !hasRoot(deserializedExternalOwners.keySet(), f, folder, furi)) { |
| 127 | ++ !hasRoot(externalOwners.keySet(), f, true, furi) && |
| 128 | ++ !hasRoot(deserializedExternalOwners.keySet(), f, true, furi)) { |
| 129 | + Project p; |
| 130 | + try { |
| 131 | + p = ProjectManager.getDefault().findProject(f); |
| 132 | +@@ -414,6 +413,40 @@ private static URI goUp(URI u) { |
| 133 | + assert u.toString().startsWith(nue.toString()) : "not a parent: " + nue + " of " + u; |
| 134 | + return nue; |
| 135 | + } |
| 136 | ++ |
| 137 | ++ private static Set<String> separatePaths(String joinedPaths, String pathSeparator) { |
| 138 | ++ if (joinedPaths == null || joinedPaths.isEmpty()) |
| 139 | ++ return null; |
| 140 | ++ |
| 141 | ++ Set<String> paths = null; |
| 142 | ++ for (String split : joinedPaths.split(pathSeparator)) { |
| 143 | ++ if ((split = split.trim()).isEmpty()) continue; |
| 144 | ++ |
| 145 | ++ // Ensure that variations in terms of ".." or "." or windows drive-letter case differences are removed. |
| 146 | ++ // File.getCanonicalFile() will additionally resolve symlinks, which is not required. |
| 147 | ++ File file = FileUtil.normalizeFile(new File(split)); |
| 148 | ++ |
| 149 | ++ // Store FileObject.getPath(); because getOwner() compares these with FileObject.getPath() strings. |
| 150 | ++ // This has some peculiarities as compared to File.getAbsolutePath(); such as return "" for File("/"). |
| 151 | ++ FileObject fileObject = FileUtil.toFileObject(file); |
| 152 | ++ // This conversion may get rid of non-existent paths. |
| 153 | ++ if (fileObject == null) continue; |
| 154 | ++ |
| 155 | ++ String path = fileObject.getPath(); |
| 156 | ++ if (path == null || path.isEmpty()) continue; |
| 157 | ++ |
| 158 | ++ if (paths == null) { |
| 159 | ++ paths = Collections.singleton(path); // more performant in usage when only a single element is present. |
| 160 | ++ } else { |
| 161 | ++ if (paths.size() == 1) { |
| 162 | ++ paths = new LinkedHashSet<>(paths); // more performant in iteration |
| 163 | ++ } |
| 164 | ++ paths.add(path); |
| 165 | ++ } |
| 166 | ++ } |
| 167 | ++ return paths; |
| 168 | ++ } |
| 169 | ++ |
| 170 | + private static final boolean WINDOWS = BaseUtilities.isWindows(); |
| 171 | + |
| 172 | + } |
| 173 | +diff --git a/platform/o.n.bootstrap/src/org/netbeans/CLIHandler.java b/platform/o.n.bootstrap/src/org/netbeans/CLIHandler.java |
| 174 | +index 633ee72340de..3140aba8eafa 100644 |
| 175 | +--- a/platform/o.n.bootstrap/src/org/netbeans/CLIHandler.java |
| 176 | ++++ b/platform/o.n.bootstrap/src/org/netbeans/CLIHandler.java |
| 177 | +@@ -45,7 +45,6 @@ |
| 178 | + import java.util.Collection; |
| 179 | + import java.util.Collections; |
| 180 | + import java.util.List; |
| 181 | +-import java.util.Random; |
| 182 | + import java.util.logging.Level; |
| 183 | + import java.util.logging.Logger; |
| 184 | + import org.openide.util.RequestProcessor; |
| 185 | +@@ -580,7 +579,7 @@ static Status initialize( |
| 186 | + enterState(10, block); |
| 187 | + |
| 188 | + final byte[] arr = new byte[KEY_LENGTH]; |
| 189 | +- new Random().nextBytes(arr); |
| 190 | ++ new SecureRandom().nextBytes(arr); |
| 191 | + |
| 192 | + |
| 193 | + final RandomAccessFile os = raf; |
0 commit comments