Skip to content

Commit 3d76d92

Browse files
committed
Revise APIs to throw new ForbiddenSymlinkException
1 parent 38b9d2d commit 3d76d92

14 files changed

+175
-67
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import java.util.Set;
3131
import java.util.TreeSet;
3232
import org.opensolaris.opengrok.util.ClassUtil;
33+
import org.opensolaris.opengrok.util.ForbiddenSymlinkException;
3334

3435
/**
3536
* Placeholder for the information that builds up a project
@@ -316,7 +317,7 @@ public static Project getProject(File file) {
316317
ret = getProject(RuntimeEnvironment.getInstance().getPathRelativeToSourceRoot(file));
317318
} catch (FileNotFoundException e) { // NOPMD
318319
// ignore if not under source root
319-
} catch (IOException e) { // NOPMD
320+
} catch (IOException|ForbiddenSymlinkException e) { // NOPMD
320321
// problem has already been logged, just return null
321322
}
322323
return ret;

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

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
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;
103104
import org.opensolaris.opengrok.util.PathUtils;
104105

105106
/**
@@ -371,11 +372,14 @@ public void setSourceRoot(String sourceRoot) {
371372
* source root.
372373
*
373374
* @param file A file to resolve
374-
* @throws IOException If an IO error occurs
375-
* @throws FileNotFoundException If the file is not relative to source root
376375
* @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
377380
*/
378-
public String getPathRelativeToSourceRoot(File file) throws IOException {
381+
public String getPathRelativeToSourceRoot(File file)
382+
throws IOException, ForbiddenSymlinkException {
379383
return getPathRelativeToSourceRoot(file, 0);
380384
}
381385

@@ -386,11 +390,14 @@ public String getPathRelativeToSourceRoot(File file) throws IOException {
386390
*
387391
* @param file A file to resolve
388392
* @param stripCount Number of characters past source root to strip
389-
* @throws IOException If an IO error occurs
390-
* @throws FileNotFoundException If the file is not relative to source root
391393
* @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
392398
*/
393-
public String getPathRelativeToSourceRoot(File file, int stripCount) throws IOException {
399+
public String getPathRelativeToSourceRoot(File file, int stripCount)
400+
throws IOException, ForbiddenSymlinkException {
394401
String sourceRoot = getSourceRootPath();
395402
if (sourceRoot == null) {
396403
throw new FileNotFoundException("Source Root Not Found");
@@ -1324,9 +1331,12 @@ private void generateProjectRepositoriesMap() throws IOException {
13241331
for (RepositoryInfo r : getRepositories()) {
13251332
Project proj;
13261333
String repoPath;
1327-
1328-
repoPath = getPathRelativeToSourceRoot(
1334+
try {
1335+
repoPath = getPathRelativeToSourceRoot(
13291336
new File(r.getDirectoryName()), 0);
1337+
} catch (ForbiddenSymlinkException e) {
1338+
continue;
1339+
}
13301340

13311341
if ((proj = Project.getProject(repoPath)) != null) {
13321342
List<RepositoryInfo> values = repository_map.get(proj);

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

Lines changed: 2 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,7 +201,7 @@ protected byte[] applyMessage(RuntimeEnvironment env) throws Exception {
200201
return env.getPathRelativeToSourceRoot(
201202
new File((x).getDirectoryName())
202203
);
203-
} catch (IOException e) {
204+
} catch (IOException|ForbiddenSymlinkException e) {
204205
LOGGER.log(Level.INFO,
205206
"cannot remove files for repository " +
206207
x.getDirectoryName());

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

Lines changed: 7 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,12 @@ 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+
// ignored (and already logged by PathUtils)
177+
}
173178
}
174179
break;
175180
default:

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

Lines changed: 52 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
import java.util.zip.GZIPOutputStream;
5555
import org.opensolaris.opengrok.configuration.RuntimeEnvironment;
5656
import org.opensolaris.opengrok.logger.LoggerFactory;
57+
import org.opensolaris.opengrok.util.ForbiddenSymlinkException;
5758
import org.opensolaris.opengrok.util.IOUtils;
5859

5960
/*
@@ -146,8 +147,14 @@ private boolean isRenamedFile(String filename,
146147
RuntimeEnvironment env,
147148
Repository repository, History history) throws IOException {
148149

149-
String repodir = env.getPathRelativeToSourceRoot(
150-
new File(repository.getDirectoryName()));
150+
String repodir;
151+
try {
152+
repodir = env.getPathRelativeToSourceRoot(
153+
new File(repository.getDirectoryName()));
154+
} catch (ForbiddenSymlinkException e) {
155+
// already logged by PathUtils
156+
return false;
157+
}
151158
String shortestfile = filename.substring(repodir.length() + 1);
152159

153160
return (history.isRenamed(shortestfile));
@@ -203,7 +210,7 @@ private static File getCachedFile(File file) throws HistoryException {
203210
sb.append(DIRECTORY_FILE_PREFIX);
204211
}
205212
sb.append(".gz");
206-
} catch (IOException e) {
213+
} catch (IOException|ForbiddenSymlinkException e) {
207214
throw new HistoryException("Failed to get path relative to " +
208215
"source root for " + file, e);
209216
}
@@ -364,17 +371,17 @@ private void storeFile(History histNew, File file, Repository repo)
364371
}
365372

366373
private void finishStore(Repository repository, String latestRev) {
367-
File file = new File(getRepositoryHistDataDirname(repository));
368-
// If the history was not created for some reason (e.g. temporary
369-
// failure), do not create the CachedRevision file as this would
370-
// create confusion (once it starts working again).
371-
if (file.isDirectory()) {
374+
String histDir = getRepositoryHistDataDirname(repository);
375+
if (histDir == null || !(new File(histDir)).isDirectory()) {
376+
LOGGER.log(Level.WARNING,
377+
"Could not store history for repo {0}",
378+
repository.getDirectoryName());
379+
} else {
372380
storeLatestCachedRevision(repository, latestRev);
381+
LOGGER.log(Level.FINE,
382+
"Done storing history for repo {0}",
383+
repository.getDirectoryName());
373384
}
374-
375-
LOGGER.log(Level.FINE,
376-
"Done storing history for repo {0}",
377-
new Object[] {repository.getDirectoryName()});
378385
}
379386

380387
/**
@@ -620,11 +627,11 @@ public boolean hasCacheForDirectory(File directory, Repository repository)
620627
}
621628
RuntimeEnvironment env = RuntimeEnvironment.getInstance();
622629
File dir = env.getDataRootFile();
623-
dir = new File(dir, this.historyCacheDirName);
630+
dir = new File(dir, FileHistoryCache.historyCacheDirName);
624631
try {
625632
dir = new File(dir, env.getPathRelativeToSourceRoot(
626633
new File(repos.getDirectoryName())));
627-
} catch (IOException e) {
634+
} catch (IOException|ForbiddenSymlinkException e) {
628635
throw new HistoryException("Could not resolve " +
629636
repos.getDirectoryName()+" relative to source root", e);
630637
}
@@ -647,6 +654,9 @@ public String getRepositoryHistDataDirname(Repository repository) {
647654
LOGGER.log(Level.WARNING, "Could not resolve " +
648655
repository.getDirectoryName()+" relative to source root", ex);
649656
return null;
657+
} catch (ForbiddenSymlinkException ex) {
658+
LOGGER.log(Level.FINE, "forbidden symbolic link", ex);
659+
return null;
650660
}
651661

652662
return env.getDataRootPath() + File.separatorChar
@@ -655,8 +665,9 @@ public String getRepositoryHistDataDirname(Repository repository) {
655665
}
656666

657667
private String getRepositoryCachedRevPath(Repository repository) {
658-
return getRepositoryHistDataDirname(repository)
659-
+ File.separatorChar + latestRevFileName;
668+
String histDir = getRepositoryHistDataDirname(repository);
669+
if (histDir == null) return null;
670+
return histDir + File.separatorChar + latestRevFileName;
660671
}
661672

662673
/**
@@ -690,8 +701,15 @@ public String getLatestCachedRevision(Repository repository) {
690701
String rev = null;
691702
BufferedReader input;
692703

704+
String revPath = getRepositoryCachedRevPath(repository);
705+
if (revPath == null) {
706+
LOGGER.log(Level.WARNING, "no rev path for {0}",
707+
repository.getDirectoryName());
708+
return null;
709+
}
710+
693711
try {
694-
input = new BufferedReader(new FileReader(getRepositoryCachedRevPath(repository)));
712+
input = new BufferedReader(new FileReader(revPath));
695713
try {
696714
rev = input.readLine();
697715
} catch (java.io.IOException e) {
@@ -705,8 +723,8 @@ public String getLatestCachedRevision(Repository repository) {
705723
}
706724
}
707725
} catch (java.io.FileNotFoundException e) {
708-
LOGGER.log(Level.FINE, "not loading latest cached revision file from {0}",
709-
getRepositoryCachedRevPath(repository));
726+
LOGGER.log(Level.FINE,
727+
"not loading latest cached revision file from {0}", revPath);
710728
return null;
711729
}
712730

@@ -724,16 +742,22 @@ public Map<String, Date> getLastModifiedTimes(
724742

725743
@Override
726744
public void clear(Repository repository) {
727-
// remove the file cached last revision (done separately in case
728-
// it gets ever moved outside of the hierarchy)
729-
File cachedRevFile = new File(getRepositoryCachedRevPath(repository));
730-
cachedRevFile.delete();
745+
String revPath = getRepositoryCachedRevPath(repository);
746+
if (revPath != null) {
747+
// remove the file cached last revision (done separately in case
748+
// it gets ever moved outside of the hierarchy)
749+
File cachedRevFile = new File(revPath);
750+
cachedRevFile.delete();
751+
}
731752

732-
// Remove all files which constitute the history cache.
733-
try {
734-
IOUtils.removeRecursive(Paths.get(getRepositoryHistDataDirname(repository)));
735-
} catch (IOException ex) {
736-
LOGGER.log(Level.SEVERE, null, ex);
753+
String histDir = getRepositoryHistDataDirname(repository);
754+
if (histDir != null) {
755+
// Remove all files which constitute the history cache.
756+
try {
757+
IOUtils.removeRecursive(Paths.get(histDir));
758+
} catch (IOException ex) {
759+
LOGGER.log(Level.SEVERE, "tried removeRecursive()", ex);
760+
}
737761
}
738762
}
739763

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import org.opensolaris.opengrok.configuration.RuntimeEnvironment;
4040
import org.opensolaris.opengrok.logger.LoggerFactory;
4141
import org.opensolaris.opengrok.util.Executor;
42+
import org.opensolaris.opengrok.util.ForbiddenSymlinkException;
4243
import org.opensolaris.opengrok.util.StringUtils;
4344

4445
/**
@@ -131,7 +132,8 @@ private void process(BufferedReader in) throws IOException {
131132
File f = new File(myDir, s);
132133
String path = env.getPathRelativeToSourceRoot(f);
133134
entry.addFile(path.intern());
134-
} catch (FileNotFoundException e) { //NOPMD
135+
} catch (FileNotFoundException|
136+
ForbiddenSymlinkException e) { //NOPMD
135137
// If the file is not located under the source root,
136138
// ignore it (bug #11664).
137139
}

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

Lines changed: 3 additions & 1 deletion
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 mercurial log comments.
@@ -143,7 +144,8 @@ public void processStream(InputStream input) throws IOException {
143144
try {
144145
String path = env.getPathRelativeToSourceRoot(f);
145146
entry.addFile(path.intern());
146-
} catch (FileNotFoundException e) { // NOPMD
147+
} catch (FileNotFoundException|
148+
ForbiddenSymlinkException e) { // NOPMD
147149
// If the file is not located under the source root,
148150
// ignore it (bug #11664).
149151
}

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

Lines changed: 3 additions & 1 deletion
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
* Class used to parse the history log from Monotone
@@ -168,7 +169,8 @@ public void processStream(InputStream input) throws IOException {
168169
String path = env.getPathRelativeToSourceRoot(
169170
file);
170171
entry.addFile(path.intern());
171-
} catch (FileNotFoundException e) { // NOPMD
172+
} catch (FileNotFoundException|
173+
ForbiddenSymlinkException e) { // NOPMD
172174
// If the file is not located under the source root, ignore it
173175
}
174176
}

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,16 @@ History parse(File file, SubversionRepository repos, String sinceRevision,
154154
RuntimeEnvironment.getInstance().getSourceRootPath().length(),
155155
repos.getDateFormat());
156156

157-
Executor executor = repos.getHistoryLogExecutor(file, sinceRevision,
158-
numEntries);
159-
int status = executor.exec(true, this);
157+
Executor executor;
158+
try {
159+
executor = repos.getHistoryLogExecutor(file, sinceRevision,
160+
numEntries);
161+
} catch (IOException e) {
162+
throw new HistoryException("Failed to get history for: \"" +
163+
file.getAbsolutePath() + "\"", e);
164+
}
160165

166+
int status = executor.exec(true, this);
161167
if (status != 0) {
162168
throw new HistoryException("Failed to get history for: \"" +
163169
file.getAbsolutePath() + "\" Exit code: " + status);

src/org/opensolaris/opengrok/index/IndexDatabase.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
import org.opensolaris.opengrok.history.HistoryGuru;
8787
import org.opensolaris.opengrok.logger.LoggerFactory;
8888
import org.opensolaris.opengrok.search.QueryBuilder;
89+
import org.opensolaris.opengrok.util.ForbiddenSymlinkException;
8990
import org.opensolaris.opengrok.util.IOUtils;
9091
import org.opensolaris.opengrok.util.ObjectPool;
9192
import org.opensolaris.opengrok.web.Util;
@@ -1321,7 +1322,13 @@ public static IndexReader getIndexReader(String path) {
13211322
public static Definitions getDefinitions(File file)
13221323
throws IOException, ParseException, ClassNotFoundException {
13231324
RuntimeEnvironment env = RuntimeEnvironment.getInstance();
1324-
String path = env.getPathRelativeToSourceRoot(file);
1325+
String path;
1326+
try {
1327+
path = env.getPathRelativeToSourceRoot(file);
1328+
} catch (ForbiddenSymlinkException e) {
1329+
// (already logged by PathUtils)
1330+
return null;
1331+
}
13251332
//sanitize windows path delimiters
13261333
//in order not to conflict with Lucene escape character
13271334
path=path.replace("\\", "/");

0 commit comments

Comments
 (0)