Skip to content

Commit 5054bfa

Browse files
committed
Allow symlinks that are children canonically of already-accepted external symlinks
Also some logging levels new in this branch to FINEST.
1 parent 1c3bcdb commit 5054bfa

File tree

1 file changed

+77
-29
lines changed

1 file changed

+77
-29
lines changed

opengrok-indexer/src/main/java/org/opengrok/indexer/index/IndexDatabase.java

Lines changed: 77 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@
3939
import java.util.ArrayList;
4040
import java.util.Arrays;
4141
import java.util.Comparator;
42-
import java.util.HashMap;
4342
import java.util.HashSet;
4443
import java.util.List;
4544
import java.util.Map;
4645
import java.util.Set;
46+
import java.util.TreeMap;
4747
import java.util.concurrent.CopyOnWriteArrayList;
4848
import java.util.concurrent.CountDownLatch;
4949
import java.util.concurrent.ExecutionException;
@@ -124,7 +124,15 @@ public class IndexDatabase {
124124
private final Object INSTANCE_LOCK = new Object();
125125

126126
/** Key is canonical path; Value is the first accepted, absolute path. */
127-
private final Map<String, String> acceptedNonlocalSymlinks = new HashMap<>();
127+
private final Map<String, String> acceptedNonlocalSymlinks = new TreeMap<>((o1, o2) -> {
128+
// DESC by length.
129+
int cmp = Integer.compare(o2.length(), o1.length());
130+
if (cmp != 0) {
131+
return cmp;
132+
}
133+
// ASC by String value.
134+
return o1.compareTo(o2);
135+
});
128136

129137
private Project project;
130138
private FSDirectory indexDirectory;
@@ -957,44 +965,84 @@ private boolean acceptSymlink(Path absolute, File canonical, AcceptSymlinkRet re
957965
new Object[] {canonical1, absolute1});
958966
}
959967
return true;
960-
} else {
961-
/*
962-
* Do not accept symlinks to local directories, because the
963-
* canonical target will be indexed on its own -- but
964-
* relativize() a path to be returned in ret so that
965-
* a symlink can be replicated in xref/.
966-
*/
967-
ret.localRelPath = absolute.getParent().relativize(
968-
canonical.toPath()).toString();
969-
return false;
970968
}
969+
970+
/*
971+
* Do not accept symlinks to local directories, because the
972+
* canonical target will be indexed on its own -- but relativize()
973+
* a path to be returned in ret so that a symlink can be replicated
974+
* in xref/.
975+
*/
976+
ret.localRelPath = absolute.getParent().relativize(
977+
canonical.toPath()).toString();
978+
return false;
971979
}
972980

981+
/*
982+
* No need to synchronize access to acceptedNonlocalSymlinks, as
983+
* indexDown() runs on one thread.
984+
*/
985+
973986
String absolute0;
974-
// No need to synchronize, as indexDown() runs on one thread.
975987
if ((absolute0 = acceptedNonlocalSymlinks.get(canonical1)) != null) {
976988
if (absolute1.equals(absolute0)) {
977989
return true;
978-
} else if (!isCanonicalDir) {
979-
if (LOGGER.isLoggable(Level.FINE)) {
980-
LOGGER.log(Level.FINE, "External file {0} has symlink from {1} after first {2}",
990+
}
991+
if (!isCanonicalDir) {
992+
if (LOGGER.isLoggable(Level.FINEST)) {
993+
LOGGER.log(Level.FINEST,
994+
"External file {0} has symlink from {1} after first {2}",
981995
new Object[] {canonical1, absolute1, absolute0});
982996
}
983997
return true;
984-
} else {
998+
}
999+
1000+
/*
1001+
* Do not accept symlinks to external directories already accepted
1002+
* as linked elsewhere, because the canonical target will be
1003+
* indexed already -- but relativize() a path to be returned in ret
1004+
* so that this second symlink can be redone as a local
1005+
* (non-external) symlink in xref/.
1006+
*/
1007+
ret.localRelPath = absolute.getParent().relativize(
1008+
Paths.get(absolute0)).toString();
1009+
1010+
if (LOGGER.isLoggable(Level.FINEST)) {
1011+
LOGGER.log(Level.FINEST, "External dir {0} has symlink from {1} after first {2}",
1012+
new Object[] {canonical1, absolute1, absolute0});
1013+
}
1014+
return false;
1015+
}
1016+
1017+
/*
1018+
* Iterate through acceptedNonlocalSymlinks, which is sorted so that
1019+
* longer canonical entries come first, to see if the new link is a
1020+
* child canonically.
1021+
*/
1022+
for (String canonicalPrev : acceptedNonlocalSymlinks.keySet()) {
1023+
if (canonical1.startsWith(canonicalPrev + File.separator)) {
1024+
String absolutePrev = acceptedNonlocalSymlinks.get(canonicalPrev);
1025+
if (!isCanonicalDir) {
1026+
if (LOGGER.isLoggable(Level.FINEST)) {
1027+
LOGGER.log(Level.FINEST,
1028+
"External file {0} has symlink from {1} under previous {2}",
1029+
new Object[] {canonical1, absolute1, absolutePrev});
1030+
}
1031+
return true;
1032+
}
1033+
9851034
/*
986-
* Do not accept symlinks to external directories already
987-
* accepted as linked elsewhere, because the canonical target
988-
* will be indexed already -- but relativize() a path to be
989-
* returned in ret so that this second symlink can be redone as
990-
* a local (non-external) symlink in xref/.
1035+
* See above about redoing a sourceRoot symlink as a local
1036+
* (non-external) symlink in xref/.
9911037
*/
992-
ret.localRelPath = absolute.getParent().relativize(
993-
Paths.get(absolute0)).toString();
1038+
Path abs0 = Paths.get(absolutePrev, canonical1.substring(
1039+
canonicalPrev.length() + 1));
1040+
ret.localRelPath = absolute.getParent().relativize(abs0).toString();
9941041

995-
if (LOGGER.isLoggable(Level.FINE)) {
996-
LOGGER.log(Level.FINE, "External dir {0} has symlink from {1} after first {2}",
997-
new Object[] {canonical1, absolute1, absolute0});
1042+
if (LOGGER.isLoggable(Level.FINEST)) {
1043+
LOGGER.log(Level.FINEST,
1044+
"External dir {0} has symlink from {1} under previous {2}",
1045+
new Object[] {canonical1, absolute1, absolutePrev});
9981046
}
9991047
return false;
10001048
}
@@ -1005,8 +1053,8 @@ private boolean acceptSymlink(Path absolute, File canonical, AcceptSymlinkRet re
10051053
Set<String> canonicalRoots = env.getCanonicalRoots();
10061054
for (String canonicalRoot : canonicalRoots) {
10071055
if (canonical1.startsWith(canonicalRoot)) {
1008-
if (LOGGER.isLoggable(Level.FINE)) {
1009-
LOGGER.log(Level.FINE, "Allowed symlink {0} per canonical root {1}",
1056+
if (LOGGER.isLoggable(Level.FINEST)) {
1057+
LOGGER.log(Level.FINEST, "Allowed symlink {0} per canonical root {1}",
10101058
new Object[] {absolute1, canonical1});
10111059
}
10121060
acceptedNonlocalSymlinks.put(canonical1, absolute1);

0 commit comments

Comments
 (0)