Skip to content

Commit d7b8200

Browse files
authored
Merge pull request #1989 from idodeclare/bugfix/symlinks2
Bugfix/symlinks2
2 parents 1a0291e + b2db0b7 commit d7b8200

34 files changed

+904
-162
lines changed

src/org/opensolaris/opengrok/analysis/AnalyzerGuru.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@
106106
import org.opensolaris.opengrok.history.HistoryReader;
107107
import org.opensolaris.opengrok.logger.LoggerFactory;
108108
import org.opensolaris.opengrok.search.QueryBuilder;
109+
import org.opensolaris.opengrok.util.ForbiddenSymlinkException;
109110
import org.opensolaris.opengrok.util.IOUtils;
110111
import org.opensolaris.opengrok.web.Util;
111112

@@ -394,10 +395,12 @@ public static FileAnalyzer getAnalyzer(InputStream in, String file) throws IOExc
394395
* @param xrefOut Where to write the xref (possibly {@code null})
395396
* @throws IOException If an exception occurs while collecting the data
396397
* @throws InterruptedException if a timeout occurs
398+
* @throws ForbiddenSymlinkException if symbolic-link checking encounters
399+
* an ineligible link
397400
*/
398401
public void populateDocument(Document doc, File file, String path,
399402
FileAnalyzer fa, Writer xrefOut) throws IOException,
400-
InterruptedException {
403+
InterruptedException, ForbiddenSymlinkException {
401404

402405
String date = DateTools.timeToString(file.lastModified(),
403406
DateTools.Resolution.MILLISECOND);

src/org/opensolaris/opengrok/configuration/Project.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@
2929
import java.util.Locale;
3030
import java.util.Set;
3131
import java.util.TreeSet;
32+
import java.util.logging.Level;
33+
import java.util.logging.Logger;
34+
import org.opensolaris.opengrok.logger.LoggerFactory;
3235
import org.opensolaris.opengrok.util.ClassUtil;
36+
import org.opensolaris.opengrok.util.ForbiddenSymlinkException;
3337

3438
/**
3539
* Placeholder for the information that builds up a project
@@ -38,6 +42,8 @@ public class Project implements Comparable<Project>, Nameable, Serializable {
3842

3943
private static final long serialVersionUID = 1L;
4044

45+
private static final Logger LOGGER = LoggerFactory.getLogger(Project.class);
46+
4147
static {
4248
ClassUtil.remarkTransientFields(Project.class);
4349
}
@@ -316,6 +322,9 @@ public static Project getProject(File file) {
316322
ret = getProject(RuntimeEnvironment.getInstance().getPathRelativeToSourceRoot(file));
317323
} catch (FileNotFoundException e) { // NOPMD
318324
// ignore if not under source root
325+
} catch (ForbiddenSymlinkException e) {
326+
LOGGER.log(Level.FINER, e.getMessage());
327+
// ignore
319328
} catch (IOException e) { // NOPMD
320329
// problem has already been logged, just return null
321330
}

src/org/opensolaris/opengrok/configuration/RuntimeEnvironment.java

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@
100100
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
101101
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
102102
import static org.opensolaris.opengrok.configuration.Configuration.makeXMLStringAsConfiguration;
103+
import org.opensolaris.opengrok.util.ForbiddenSymlinkException;
104+
import org.opensolaris.opengrok.util.PathUtils;
103105

104106
/**
105107
* The RuntimeEnvironment class is used as a placeholder for the current
@@ -135,7 +137,7 @@ public final class RuntimeEnvironment {
135137

136138
private Statistics statistics = new Statistics();
137139

138-
private static IndexTimestamp indexTime = new IndexTimestamp();
140+
private static final IndexTimestamp indexTime = new IndexTimestamp();
139141

140142
/**
141143
* Instance of authorization framework.
@@ -370,11 +372,14 @@ public void setSourceRoot(String sourceRoot) {
370372
* source root.
371373
*
372374
* @param file A file to resolve
373-
* @throws IOException If an IO error occurs
374-
* @throws FileNotFoundException If the file is not relative to source root
375375
* @return Path relative to source root
376+
* @throws IOException If an IO error occurs
377+
* @throws FileNotFoundException if the file is not relative to source root
378+
* @throws ForbiddenSymlinkException if symbolic-link checking encounters
379+
* an ineligible link
376380
*/
377-
public String getPathRelativeToSourceRoot(File file) throws IOException {
381+
public String getPathRelativeToSourceRoot(File file)
382+
throws IOException, ForbiddenSymlinkException {
378383
return getPathRelativeToSourceRoot(file, 0);
379384
}
380385

@@ -385,29 +390,32 @@ public String getPathRelativeToSourceRoot(File file) throws IOException {
385390
*
386391
* @param file A file to resolve
387392
* @param stripCount Number of characters past source root to strip
388-
* @throws IOException If an IO error occurs
389-
* @throws FileNotFoundException If the file is not relative to source root
390393
* @return Path relative to source root
394+
* @throws IOException if an IO error occurs
395+
* @throws FileNotFoundException if the file is not relative to source root
396+
* @throws ForbiddenSymlinkException if symbolic-link checking encounters
397+
* an ineligible link
391398
*/
392-
public String getPathRelativeToSourceRoot(File file, int stripCount) throws IOException {
393-
String canonicalPath = file.getCanonicalPath();
399+
public String getPathRelativeToSourceRoot(File file, int stripCount)
400+
throws IOException, ForbiddenSymlinkException {
394401
String sourceRoot = getSourceRootPath();
395-
396-
if(sourceRoot == null){
402+
if (sourceRoot == null) {
397403
throw new FileNotFoundException("Source Root Not Found");
398404
}
399-
400-
if (canonicalPath.startsWith(sourceRoot)) {
401-
return canonicalPath.substring(sourceRoot.length() + stripCount);
402-
}
403-
for (String allowedSymlink : getAllowedSymlinks()) {
404-
String allowedTarget = new File(allowedSymlink).getCanonicalPath();
405-
if (canonicalPath.startsWith(allowedTarget)) {
406-
return canonicalPath.substring(allowedTarget.length()
407-
+ stripCount);
408-
}
405+
406+
String maybeRelPath = PathUtils.getRelativeToCanonical(file.getPath(),
407+
sourceRoot, getAllowedSymlinks());
408+
File maybeRelFile = new File(maybeRelPath);
409+
if (!maybeRelFile.isAbsolute()) {
410+
// N.b. OpenGrok has a weird convention that
411+
// source-root "relative" paths must start with a '/' as they are
412+
// elsewhere directly appended to env.getSourceRootPath() and also
413+
// stored as such.
414+
maybeRelPath = File.separator + maybeRelPath;
415+
return maybeRelPath.substring(stripCount);
409416
}
410-
throw new FileNotFoundException("Failed to resolve [" + canonicalPath
417+
418+
throw new FileNotFoundException("Failed to resolve [" + file.getPath()
411419
+ "] relative to source root [" + sourceRoot + "]");
412420
}
413421

@@ -1323,9 +1331,13 @@ private void generateProjectRepositoriesMap() throws IOException {
13231331
for (RepositoryInfo r : getRepositories()) {
13241332
Project proj;
13251333
String repoPath;
1326-
1327-
repoPath = getPathRelativeToSourceRoot(
1334+
try {
1335+
repoPath = getPathRelativeToSourceRoot(
13281336
new File(r.getDirectoryName()), 0);
1337+
} catch (ForbiddenSymlinkException e) {
1338+
LOGGER.log(Level.FINER, e.getMessage());
1339+
continue;
1340+
}
13291341

13301342
if ((proj = Project.getProject(repoPath)) != null) {
13311343
List<RepositoryInfo> values = repository_map.get(proj);
@@ -1717,7 +1729,7 @@ public void applyConfig(Message m, boolean reindex) {
17171729
try {
17181730
config = makeXMLStringAsConfiguration(m.getText());
17191731
} catch (IOException ex) {
1720-
LOGGER.log(Level.WARNING, "Configuration decoding failed" + ex);
1732+
LOGGER.log(Level.WARNING, "Configuration decoding failed", ex);
17211733
return;
17221734
}
17231735

src/org/opensolaris/opengrok/configuration/messages/ProjectMessage.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import org.opensolaris.opengrok.history.RepositoryInfo;
4444
import org.opensolaris.opengrok.index.IndexDatabase;
4545
import org.opensolaris.opengrok.logger.LoggerFactory;
46+
import org.opensolaris.opengrok.util.ForbiddenSymlinkException;
4647
import org.opensolaris.opengrok.util.IOUtils;
4748

4849

@@ -200,9 +201,12 @@ protected byte[] applyMessage(RuntimeEnvironment env) throws Exception {
200201
return env.getPathRelativeToSourceRoot(
201202
new File((x).getDirectoryName())
202203
);
204+
} catch (ForbiddenSymlinkException e) {
205+
LOGGER.log(Level.FINER, e.getMessage());
206+
return "";
203207
} catch (IOException e) {
204208
LOGGER.log(Level.INFO,
205-
"cannot remove files for repository " +
209+
"cannot remove files for repository {0}",
206210
x.getDirectoryName());
207211
// Empty output should not cause any harm
208212
// since {@code getReposFromString()} inside

src/org/opensolaris/opengrok/history/BazaarHistoryParser.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import org.opensolaris.opengrok.configuration.RuntimeEnvironment;
4141
import org.opensolaris.opengrok.logger.LoggerFactory;
4242
import org.opensolaris.opengrok.util.Executor;
43+
import org.opensolaris.opengrok.util.ForbiddenSymlinkException;
4344

4445
/**
4546
* Parse a stream of Bazaar log comments.
@@ -168,8 +169,13 @@ public void processStream(InputStream input) throws IOException {
168169
}
169170

170171
File f = new File(myDir, s);
171-
String name = env.getPathRelativeToSourceRoot(f);
172-
entry.addFile(name.intern());
172+
try {
173+
String name = env.getPathRelativeToSourceRoot(f);
174+
entry.addFile(name.intern());
175+
} catch (ForbiddenSymlinkException e) {
176+
LOGGER.log(Level.FINER, e.getMessage());
177+
// ignored
178+
}
173179
}
174180
break;
175181
default:

src/org/opensolaris/opengrok/history/BazaarRepository.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
/*
2121
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
22+
* Portions Copyright (c) 2017, Chris Fraire <[email protected]>.
2223
*/
2324
package org.opensolaris.opengrok.history;
2425

@@ -80,11 +81,7 @@ public BazaarRepository() {
8081
*/
8182
Executor getHistoryLogExecutor(final File file, final String sinceRevision)
8283
throws IOException {
83-
String abs = file.getCanonicalPath();
84-
String filename = "";
85-
if (abs.length() > getDirectoryName().length()) {
86-
filename = abs.substring(getDirectoryName().length() + 1);
87-
}
84+
String filename = getRepoRelativePath(file);
8885

8986
List<String> cmd = new ArrayList<String>();
9087
ensureCommand(CMD_PROPERTY_KEY, CMD_FALLBACK);

src/org/opensolaris/opengrok/history/CVSRepository.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
/*
2121
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
22+
* Portions Copyright (c) 2017, Chris Fraire <[email protected]>.
2223
*/
2324
package org.opensolaris.opengrok.history;
2425

@@ -96,8 +97,8 @@ public boolean isWorking() {
9697
}
9798

9899
@Override
99-
public void setDirectoryName(String directoryName) {
100-
super.setDirectoryName(directoryName);
100+
public void setDirectoryName(File directory) {
101+
super.setDirectoryName(directory);
101102

102103
if (isWorking()) {
103104
File rootFile = new File(getDirectoryName() + File.separatorChar
@@ -195,11 +196,7 @@ String determineBranch() throws IOException {
195196
* @return An Executor ready to be started
196197
*/
197198
Executor getHistoryLogExecutor(final File file) throws IOException {
198-
String abs = file.getCanonicalPath();
199-
String filename = "";
200-
if (abs.length() > getDirectoryName().length()) {
201-
filename = abs.substring(getDirectoryName().length() + 1);
202-
}
199+
String filename = getRepoRelativePath(file);
203200

204201
List<String> cmd = new ArrayList<>();
205202
ensureCommand(CMD_PROPERTY_KEY, CMD_FALLBACK);

src/org/opensolaris/opengrok/history/ClearCaseRepository.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
/*
2121
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
22+
* Portions Copyright (c) 2017, Chris Fraire <[email protected]>.
2223
*/
2324
package org.opensolaris.opengrok.history;
2425

@@ -93,11 +94,7 @@ public void setVerbose(boolean verbose) {
9394
* @return An Executor ready to be started
9495
*/
9596
Executor getHistoryLogExecutor(final File file) throws IOException {
96-
String abs = file.getCanonicalPath();
97-
String filename = "";
98-
if (abs.length() > getDirectoryName().length()) {
99-
filename = abs.substring(getDirectoryName().length() + 1);
100-
}
97+
String filename = getRepoRelativePath(file);
10198

10299
List<String> cmd = new ArrayList<>();
103100
ensureCommand(CMD_PROPERTY_KEY, CMD_FALLBACK);

0 commit comments

Comments
 (0)