Skip to content

Commit 7421b47

Browse files
authored
Merge pull request #2444 from tarzanek/OpenGrok-2359
sanitize more paths on windows, fixes #2335
2 parents ef9d63d + 807ead8 commit 7421b47

File tree

8 files changed

+83
-35
lines changed

8 files changed

+83
-35
lines changed

opengrok-indexer/src/main/java/org/opengrok/indexer/analysis/AnalyzerGuru.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -523,12 +523,9 @@ public void populateDocument(Document doc, File file, String path,
523523
FileAnalyzer fa, Writer xrefOut) throws IOException,
524524
InterruptedException, ForbiddenSymlinkException {
525525

526-
// Sanitize Windows path delimiters in order not to conflict with Lucene escape character
527-
// and also so the path appears as correctly formed URI in the search results.
528-
path = path.replace("\\", "/");
529-
530526
String date = DateTools.timeToString(file.lastModified(),
531527
DateTools.Resolution.MILLISECOND);
528+
path = Util.fixPathIfWindows(path);
532529
doc.add(new Field(QueryBuilder.U, Util.path2uid(path, date),
533530
string_ft_stored_nanalyzed_norms));
534531
doc.add(new Field(QueryBuilder.FULLPATH, file.getAbsolutePath(),

opengrok-indexer/src/main/java/org/opengrok/indexer/configuration/Project.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.opengrok.indexer.logger.LoggerFactory;
3535
import org.opengrok.indexer.util.ClassUtil;
3636
import org.opengrok.indexer.util.ForbiddenSymlinkException;
37+
import org.opengrok.indexer.web.Util;
3738

3839
/**
3940
* Placeholder for the information that builds up a project
@@ -112,7 +113,7 @@ public Project(String name) {
112113
*/
113114
public Project(String name, String path) {
114115
this.name = name;
115-
this.path = path;
116+
this.path = Util.fixPathIfWindows(path);
116117
completeWithDefaults();
117118
}
118119

@@ -332,7 +333,7 @@ public static Project getProject(String path) {
332333
// Try to match each project path as prefix of the given path.
333334
final RuntimeEnvironment env = RuntimeEnvironment.getInstance();
334335
if (env.hasProjects()) {
335-
final String lpath = path.replace(File.separatorChar, '/');
336+
final String lpath = Util.fixPathIfWindows(path);
336337
for (Project p : env.getProjectList()) {
337338
String projectPath = p.getPath();
338339
if (projectPath == null) {

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,8 @@ public void update(IndexerParallelizer parallelizer)
464464
}
465465
}
466466

467+
dir = Util.fixPathIfWindows(dir);
468+
467469
String startuid = Util.path2uid(dir, "");
468470
reader = DirectoryReader.open(indexDirectory); // open existing index
469471
settings = readAnalysisSettings();
@@ -1100,6 +1102,7 @@ private void indexDown(File dir, String parent, IndexDownArgs args)
11001102
}
11011103

11021104
if (uidIter != null) {
1105+
path = Util.fixPathIfWindows(path);
11031106
String uid = Util.path2uid(path,
11041107
DateTools.timeToString(file.lastModified(),
11051108
DateTools.Resolution.MILLISECOND)); // construct uid for doc

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@
7171
/**
7272
* Creates and updates an inverted source index as well as generates Xref, file
7373
* stats etc., if specified in the options
74+
*
75+
* We shall use / as path delimiter in whole opengrok for uuids and paths
76+
* from Windows systems, the path shall be converted when entering the index or web
77+
* and converted back if needed* to access original file
78+
*
79+
* *Windows already supports opening /var/opengrok as C:\var\opengrok
7480
*/
7581
@SuppressWarnings({"PMD.AvoidPrintStackTrace", "PMD.SystemPrintln"})
7682
public final class Indexer {
@@ -83,6 +89,10 @@ public final class Indexer {
8389
private static final String DIRBASED = "dirbased";
8490
private static final String UIONLY = "uionly";
8591

92+
//whole app uses this separator
93+
public static final char PATH_SEPARATOR ='/';
94+
public static String PATH_SEPARATOR_STRING =Character.toString(PATH_SEPARATOR);
95+
8696
private static final Indexer index = new Indexer();
8797
private static Configuration cfg = null;
8898
private static boolean checkIndexVersion = false;

opengrok-indexer/src/main/java/org/opengrok/indexer/search/context/OGKUnifiedHighlighter.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ private String getRepoFileContent(String repoRelPath, String storedU)
297297
return null;
298298
}
299299

300+
repoRelPath = Util.fixPathIfWindows(repoRelPath);
300301
// Verify that timestamp (U) is unchanged by comparing UID.
301302
String uid = Util.path2uid(repoRelPath,
302303
DateTools.timeToString(repoAbsFile.lastModified(),

opengrok-indexer/src/main/java/org/opengrok/indexer/web/PageConfig.java

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@
7575
import org.suigeneris.jrcs.diff.Diff;
7676
import org.suigeneris.jrcs.diff.DifferentiationFailedException;
7777

78+
import static org.opengrok.indexer.index.Indexer.PATH_SEPARATOR;
79+
import static org.opengrok.indexer.index.Indexer.PATH_SEPARATOR_STRING;
80+
7881
/**
7982
* A simple container to lazy initialize common vars wrt. a single request. It
8083
* MUST NOT be shared between several requests and
@@ -203,7 +206,7 @@ public String getHeaderData() {
203206
*/
204207
public DiffData getDiffData() {
205208
DiffData data = new DiffData();
206-
data.path = getPath().substring(0, path.lastIndexOf('/'));
209+
data.path = getPath().substring(0, path.lastIndexOf(PATH_SEPARATOR));
207210
data.filename = Util.htmlize(getResourceFile().getName());
208211

209212
String srcRoot = getSourceRootPath();
@@ -736,7 +739,7 @@ public String getCrossFilename() {
736739
* option.
737740
*
738741
* @return always an array of 3 fields, whereby field[0] contains the path
739-
* value to use (starts and ends always with a '/'). Field[1] the contains
742+
* value to use (starts and ends always with a {@link org.opengrok.indexer.index.Indexer#PATH_SEPARATOR}). Field[1] the contains
740743
* string to show in the UI. field[2] is set to {@code disabled=""} if the
741744
* current path is the "/" directory, otherwise set to an empty string.
742745
*/
@@ -747,7 +750,7 @@ public String[] getSearchOnlyIn() {
747750
: new String[]{path, "this directory", ""};
748751
}
749752
String[] res = new String[3];
750-
res[0] = path.substring(0, path.lastIndexOf('/') + 1);
753+
res[0] = path.substring(0, path.lastIndexOf(PATH_SEPARATOR) + 1);
751754
res[1] = res[0];
752755
res[2] = "";
753756
return res;
@@ -971,7 +974,7 @@ public String getTitle() {
971974
* @see RuntimeEnvironment#getWebappLAF()
972975
*/
973976
public String getCssDir() {
974-
return req.getContextPath() + '/' + getEnv().getWebappLAF();
977+
return req.getContextPath() + PATH_SEPARATOR + getEnv().getWebappLAF();
975978
}
976979

977980
/**
@@ -1002,7 +1005,7 @@ public IgnoredNames getIgnoredNames() {
10021005

10031006
/**
10041007
* Get the canonical path to root of the source tree. File separators are
1005-
* replaced with a '/'.
1008+
* replaced with a {@link org.opengrok.indexer.index.Indexer#PATH_SEPARATOR}.
10061009
*
10071010
* @return The on disk source root directory.
10081011
* @see RuntimeEnvironment#getSourceRootPath()
@@ -1011,7 +1014,7 @@ public String getSourceRootPath() {
10111014
if (sourceRootPath == null) {
10121015
String srcpath = getEnv().getSourceRootPath();
10131016
if (srcpath != null) {
1014-
sourceRootPath = srcpath.replace(File.separatorChar, '/');
1017+
sourceRootPath = srcpath.replace(File.separatorChar, PATH_SEPARATOR);
10151018
}
10161019
}
10171020
return sourceRootPath;
@@ -1032,7 +1035,7 @@ public Prefix getPrefix() {
10321035

10331036
/**
10341037
* Get the canonical path of the related resource relative to the source
1035-
* root directory (used file separators are all '/'). No check is made,
1038+
* root directory (used file separators are all {@link org.opengrok.indexer.index.Indexer#PATH_SEPARATOR}). No check is made,
10361039
* whether the obtained path is really an accessible resource on disk.
10371040
*
10381041
* @see HttpServletRequest#getPathInfo()
@@ -1041,8 +1044,8 @@ public Prefix getPrefix() {
10411044
*/
10421045
public String getPath() {
10431046
if (path == null) {
1044-
path = Util.getCanonicalPath(req.getPathInfo(), '/');
1045-
if ("/".equals(path)) {
1047+
path = Util.getCanonicalPath(req.getPathInfo(), PATH_SEPARATOR);
1048+
if (PATH_SEPARATOR_STRING.equals(path)) {
10461049
path = "";
10471050
}
10481051
}
@@ -1076,7 +1079,7 @@ public File getResourceFile(String path) {
10761079
* NOTE: If a repository contains hard or symbolic links, the returned file
10771080
* may finally point to a file outside of the source root directory.
10781081
*
1079-
* @return {@code new File("/")} if the related file or directory is not
1082+
* @return {@code new File({@link org.opengrok.indexer.index.Indexer#PATH_SEPARATOR_STRING })} if the related file or directory is not
10801083
* available (can not be find below the source root directory), the readable
10811084
* file or directory otherwise.
10821085
* @see #getSourceRootPath()
@@ -1086,23 +1089,23 @@ public File getResourceFile() {
10861089
if (resourceFile == null) {
10871090
resourceFile = getResourceFile(getPath());
10881091
if (resourceFile == null) {
1089-
resourceFile = new File("/");
1092+
resourceFile = new File(PATH_SEPARATOR_STRING);
10901093
}
10911094
}
10921095
return resourceFile;
10931096
}
10941097

10951098
/**
10961099
* Get the canonical on disk path to the request related file or directory
1097-
* with all file separators replaced by a '/'.
1100+
* with all file separators replaced by a {@link org.opengrok.indexer.index.Indexer#PATH_SEPARATOR}.
10981101
*
1099-
* @return "/" if the evaluated path is invalid or outside the source root
1102+
* @return {@link org.opengrok.indexer.index.Indexer#PATH_SEPARATOR_STRING} if the evaluated path is invalid or outside the source root
11001103
* directory), otherwise the path to the readable file or directory.
11011104
* @see #getResourceFile()
11021105
*/
11031106
public String getResourcePath() {
11041107
if (resourcePath == null) {
1105-
resourcePath = getResourceFile().getPath().replace(File.separatorChar, '/');
1108+
resourcePath = Util.fixPathIfWindows(getResourceFile().getPath());
11061109
}
11071110
return resourcePath;
11081111
}
@@ -1119,7 +1122,7 @@ public String getResourcePath() {
11191122
*/
11201123
public boolean resourceNotAvailable() {
11211124
getIgnoredNames();
1122-
return getResourcePath().equals("/") || ignoredNames.ignore(getPath())
1125+
return getResourcePath().equals(PATH_SEPARATOR_STRING) || ignoredNames.ignore(getPath())
11231126
|| ignoredNames.ignore(resourceFile.getParentFile())
11241127
|| ignoredNames.ignore(resourceFile);
11251128
}
@@ -1137,8 +1140,8 @@ public boolean isDir() {
11371140
}
11381141

11391142
private static String trailingSlash(String path) {
1140-
return path.length() == 0 || path.charAt(path.length() - 1) != '/'
1141-
? "/"
1143+
return path.length() == 0 || path.charAt(path.length() - 1) != PATH_SEPARATOR
1144+
? PATH_SEPARATOR_STRING
11421145
: "";
11431146
}
11441147

@@ -1162,7 +1165,7 @@ private File checkFile(File dir, String name, boolean compressed) {
11621165
private File checkFileResolve(File dir, String name, boolean compressed) {
11631166
File lresourceFile = new File(getSourceRootPath() + getPath(), name);
11641167
if (!lresourceFile.canRead()) {
1165-
lresourceFile = new File("/");
1168+
lresourceFile = new File(PATH_SEPARATOR_STRING);
11661169
}
11671170
File f;
11681171
if (compressed) {

opengrok-indexer/src/main/java/org/opengrok/indexer/web/Util.java

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@
7575
import org.opengrok.indexer.logger.LoggerFactory;
7676
import org.opengrok.indexer.web.messages.MessagesContainer.AcceptedMessage;
7777

78+
import static org.opengrok.indexer.index.Indexer.PATH_SEPARATOR;
79+
7880
/**
7981
* Class for useful functions.
8082
*/
@@ -96,6 +98,13 @@ public final class Util {
9698
private final static Pattern NON_ASCII_ALPHA_NUM = Pattern.compile(
9799
"[^A-Za-z0-9_]");
98100

101+
private static String OS = null;
102+
103+
private static final String anchorLinkStart = "<a href=\"";
104+
private static final String anchorClassStart = "<a class=\"";
105+
private static final String anchorEnd = "</a>";
106+
private static final String closeQuotedTag = "\">";
107+
99108
private Util() {
100109
// private to ensure static
101110
}
@@ -377,7 +386,7 @@ public static String versionParameter() {
377386
}
378387

379388
/**
380-
* Convenience method for {@code breadcrumbPath(urlPrefix, path, '/')}.
389+
* Convenience method for {@code breadcrumbPath(urlPrefix, path, PATH_SEPARATOR)}.
381390
*
382391
* @param urlPrefix prefix to add to each url
383392
* @param path path to crack
@@ -386,14 +395,9 @@ public static String versionParameter() {
386395
* @see #breadcrumbPath(String, String, char)
387396
*/
388397
public static String breadcrumbPath(String urlPrefix, String path) {
389-
return breadcrumbPath(urlPrefix, path, '/');
398+
return breadcrumbPath(urlPrefix, path, PATH_SEPARATOR);
390399
}
391400

392-
private static final String anchorLinkStart = "<a href=\"";
393-
private static final String anchorClassStart = "<a class=\"";
394-
private static final String anchorEnd = "</a>";
395-
private static final String closeQuotedTag = "\">";
396-
397401
/**
398402
* Convenience method for
399403
* {@code breadcrumbPath(urlPrefix, path, sep, "", false)}.
@@ -472,13 +476,13 @@ public static String breadcrumbPath(String urlPrefix, String path,
472476
* (17 + prefix.length() + postfix.length()));
473477
int k = path.indexOf(pnames[0]);
474478
if (path.lastIndexOf(sep, k) != -1) {
475-
pwd.append('/');
479+
pwd.append(PATH_SEPARATOR);
476480
markup.append(sep);
477481
}
478482
for (int i = 0; i < pnames.length; i++) {
479483
pwd.append(URIEncodePath(pnames[i]));
480484
if (isDir || i < pnames.length - 1) {
481-
pwd.append('/');
485+
pwd.append(PATH_SEPARATOR);
482486
}
483487
markup.append(anchorLinkStart).append(prefix).append(pwd)
484488
.append(postfix).append(closeQuotedTag).append(pnames[i])
@@ -855,8 +859,29 @@ public static String path2uid(String path, String date) {
855859
* @return the original path.
856860
*/
857861
public static String uid2url(String uid) {
858-
String url = uid.replace('\u0000', '/');
859-
return url.substring(0, url.lastIndexOf('/')); // remove date from end
862+
String url = uid.replace('\u0000', PATH_SEPARATOR);
863+
return url.substring(0, url.lastIndexOf(PATH_SEPARATOR)); // remove date from end
864+
}
865+
866+
public static String fixPathIfWindows(String path) {
867+
if (Util.isWindows()) {
868+
// Sanitize Windows path delimiters in order not to conflict with Lucene escape character
869+
// and also so the path appears as correctly formed URI in the search results.
870+
return path.replace(File.separatorChar, PATH_SEPARATOR);
871+
}
872+
return path;
873+
}
874+
875+
public static String getOsName() {
876+
if (OS == null) {
877+
OS = System.getProperty("os.name");
878+
}
879+
return OS;
880+
}
881+
882+
public static boolean isWindows() {
883+
String osname = getOsName();
884+
return osname != null ? osname.startsWith("Windows") : false;
860885
}
861886

862887
/**

opengrok-indexer/src/test/java/org/opengrok/indexer/web/UtilTest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,14 @@ public void path2uid() {
155155
Util.path2uid("/etc/passwd", "date"));
156156
}
157157

158+
@Test
159+
public void fixPathIfWindows() {
160+
if (Util.isWindows()) {
161+
assertEquals("/var/opengrok",
162+
Util.fixPathIfWindows("\\var\\opengrok"));
163+
}
164+
}
165+
158166
@Test
159167
public void uid2url() {
160168
assertEquals("/etc/passwd", Util.uid2url(

0 commit comments

Comments
 (0)