Skip to content

Commit 8df1aed

Browse files
committed
Check gradle-wrapper.jar
Signed-off-by: Snjezana Peco <snjezana.peco@redhat.com>
1 parent f5d4616 commit 8df1aed

File tree

13 files changed

+174
-3
lines changed

13 files changed

+174
-3
lines changed

org.eclipse.jdt.ls.core/META-INF/MANIFEST.MF

+3-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ Export-Package: org.eclipse.jdt.ls.core.internal;x-friends:="org.eclipse.jdt.ls.
3737
org.eclipse.jdt.ls.core.internal.commands;x-friends:="org.eclipse.jdt.ls.tests",
3838
org.eclipse.jdt.ls.core.internal.contentassist;x-friends:="org.eclipse.jdt.ls.tests",
3939
org.eclipse.jdt.ls.core.internal.corext.codemanipulation;x-friends:="org.eclipse.jdt.ls.tests",
40-
org.eclipse.jdt.ls.core.internal.corext.template.java;x-friends:="org.eclipse.jdt.ls.tests",
4140
org.eclipse.jdt.ls.core.internal.corext.dom;x-internal:=true,
4241
org.eclipse.jdt.ls.core.internal.corext.refactoring;x-internal:=true,
4342
org.eclipse.jdt.ls.core.internal.corext.refactoring.changes;x-internal:=true,
@@ -46,6 +45,7 @@ Export-Package: org.eclipse.jdt.ls.core.internal;x-friends:="org.eclipse.jdt.ls.
4645
org.eclipse.jdt.ls.core.internal.corext.refactoring.reorg;x-internal:=true,
4746
org.eclipse.jdt.ls.core.internal.corext.refactoring.tagging;x-internal:=true,
4847
org.eclipse.jdt.ls.core.internal.corext.refactoring.util;x-internal:=true,
48+
org.eclipse.jdt.ls.core.internal.corext.template.java;x-friends:="org.eclipse.jdt.ls.tests",
4949
org.eclipse.jdt.ls.core.internal.corext.util;x-internal:=true,
5050
org.eclipse.jdt.ls.core.internal.corrections;x-internal:=true,
5151
org.eclipse.jdt.ls.core.internal.corrections.proposals;x-internal:=true,
@@ -56,9 +56,10 @@ Export-Package: org.eclipse.jdt.ls.core.internal;x-friends:="org.eclipse.jdt.ls.
5656
org.eclipse.jdt.ls.core.internal.lsp;x-friends:="org.eclipse.jdt.ls.tests",
5757
org.eclipse.jdt.ls.core.internal.managers;x-friends:="org.eclipse.jdt.ls.tests,org.eclipse.jdt.ls.tests.syntaxserver",
5858
org.eclipse.jdt.ls.core.internal.preferences;x-friends:="org.eclipse.jdt.ls.tests,org.eclipse.jdt.ls.tests.syntaxserver",
59+
org.eclipse.jdt.ls.core.internal.semantictokens;x-friends:="org.eclipse.jdt.ls.tests",
5960
org.eclipse.jdt.ls.core.internal.syntaxserver;x-friends:="org.eclipse.jdt.ls.tests.syntaxserver",
6061
org.eclipse.jdt.ls.core.internal.text.correction;x-friends:="org.eclipse.jdt.ls.tests",
61-
org.eclipse.jdt.ls.core.internal.semantictokens;x-friends:="org.eclipse.jdt.ls.tests"
62+
org.eclipse.jdt.ls.internal.gradle.checksums;x-friends:="org.eclipse.jdt.ls.tests"
6263
Bundle-ClassPath: lib/jsoup-1.9.2.jar,
6364
lib/remark-1.2.0.jar,
6465
.

org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/GradleProjectImporter.java

+15-1
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@
1414

1515
import java.io.File;
1616
import java.io.FilenameFilter;
17+
import java.io.IOException;
1718
import java.nio.file.Files;
1819
import java.nio.file.Path;
20+
import java.security.NoSuchAlgorithmException;
1921
import java.util.ArrayList;
2022
import java.util.Collection;
2123
import java.util.List;
@@ -39,6 +41,7 @@
3941
import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin;
4042
import org.eclipse.jdt.ls.core.internal.ProjectUtils;
4143
import org.eclipse.jdt.ls.core.internal.preferences.PreferenceManager;
44+
import org.eclipse.jdt.ls.internal.gradle.checksums.WrapperValidator;
4245

4346
/**
4447
* @author Fred Bricon
@@ -105,7 +108,18 @@ private void importDir(Path rootFolder, IProgressMonitor monitor) {
105108

106109
public static GradleDistribution getGradleDistribution(Path rootFolder) {
107110
if (JavaLanguageServerPlugin.getPreferencesManager() != null && JavaLanguageServerPlugin.getPreferencesManager().getPreferences().isGradleWrapperEnabled() && Files.exists(rootFolder.resolve("gradlew"))) {
108-
return GradleDistribution.fromBuild();
111+
WrapperValidator validator = new WrapperValidator();
112+
try {
113+
String result = validator.checkWrapper(rootFolder.toFile().getAbsolutePath());
114+
if (result == null) {
115+
WrapperGradleDistribution gradleDistribution = GradleDistribution.fromBuild();
116+
return gradleDistribution;
117+
} else {
118+
JavaLanguageServerPlugin.logInfo(result);
119+
}
120+
} catch (NoSuchAlgorithmException | IOException e) {
121+
JavaLanguageServerPlugin.logException(e.getMessage(), e);
122+
}
109123
}
110124
if (JavaLanguageServerPlugin.getPreferencesManager() != null && JavaLanguageServerPlugin.getPreferencesManager().getPreferences().getGradleVersion() != null) {
111125
List<GradleVersion> versions = CorePlugin.publishedGradleVersions().getVersions();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2020 Red Hat Inc. and others.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License 2.0
5+
* which accompanies this distribution, and is available at
6+
* https://www.eclipse.org/legal/epl-2.0/
7+
*
8+
* SPDX-License-Identifier: EPL-2.0
9+
*
10+
* Contributors:
11+
* Red Hat Inc. - initial API and implementation
12+
*******************************************************************************/
13+
package org.eclipse.jdt.ls.internal.gradle.checksums;
14+
15+
import java.io.File;
16+
import java.io.FileInputStream;
17+
import java.io.IOException;
18+
import java.security.DigestInputStream;
19+
import java.security.MessageDigest;
20+
import java.security.NoSuchAlgorithmException;
21+
22+
public class HashProvider {
23+
24+
private final String algorithm;
25+
26+
public HashProvider() {
27+
this("SHA-256");
28+
}
29+
30+
public HashProvider(String algorithm) {
31+
this.algorithm = algorithm;
32+
}
33+
34+
public String getChecksum(File file) throws IOException, NoSuchAlgorithmException {
35+
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
36+
try (DigestInputStream dis = new DigestInputStream(new FileInputStream(file), messageDigest)) {
37+
byte[] bytes = new byte[32768];
38+
while (dis.read(bytes) != -1) {
39+
;
40+
}
41+
messageDigest = dis.getMessageDigest();
42+
}
43+
StringBuilder result = new StringBuilder();
44+
for (byte b : messageDigest.digest()) {
45+
result.append(String.format("%02x", b));
46+
}
47+
return result.toString();
48+
}
49+
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2020 Red Hat Inc. and others.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License 2.0
5+
* which accompanies this distribution, and is available at
6+
* https://www.eclipse.org/legal/epl-2.0/
7+
*
8+
* SPDX-License-Identifier: EPL-2.0
9+
*
10+
* Contributors:
11+
* Red Hat Inc. - initial API and implementation
12+
*******************************************************************************/
13+
package org.eclipse.jdt.ls.internal.gradle.checksums;
14+
15+
import java.io.BufferedReader;
16+
import java.io.FileInputStream;
17+
import java.io.IOException;
18+
import java.io.InputStream;
19+
import java.io.InputStreamReader;
20+
import java.net.URL;
21+
import java.net.URLConnection;
22+
import java.nio.file.Path;
23+
import java.nio.file.Paths;
24+
import java.security.NoSuchAlgorithmException;
25+
import java.util.Properties;
26+
import java.util.concurrent.TimeUnit;
27+
28+
import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin;
29+
30+
import com.google.common.cache.Cache;
31+
import com.google.common.cache.CacheBuilder;
32+
33+
public class WrapperValidator {
34+
35+
private static final String DISTRIBUTION_URL = "distributionUrl";
36+
private static final String GRADLE_WRAPPER_PROPERTIES = "gradle/wrapper/gradle-wrapper.properties";
37+
private static final String GRADLE_WRAPPER_JAR = "gradle/wrapper/gradle-wrapper.jar";
38+
private final boolean DISABLED = Boolean.getBoolean("gradle.wrapper.check.disabled");
39+
private HashProvider hashProvider;
40+
protected static Cache<String, String> downloadRequestsCache = CacheBuilder.newBuilder().maximumSize(100).expireAfterWrite(1, TimeUnit.HOURS).build();
41+
42+
43+
public WrapperValidator() {
44+
this(new HashProvider());
45+
}
46+
47+
public WrapperValidator(HashProvider hashProvider) {
48+
this.hashProvider = hashProvider;
49+
}
50+
51+
public String checkWrapper(String baseDir) throws IOException, NoSuchAlgorithmException {
52+
if (DISABLED) {
53+
return null;
54+
}
55+
Path wrapperJar = Paths.get(baseDir, GRADLE_WRAPPER_JAR);
56+
if (!wrapperJar.toFile().exists()) {
57+
return wrapperJar.toString() + " doesn't exist.";
58+
}
59+
Path wrapperProperties = Paths.get(baseDir, GRADLE_WRAPPER_PROPERTIES);
60+
if (!wrapperProperties.toFile().exists()) {
61+
return wrapperProperties.toString() + " doesn't exist.";
62+
}
63+
try (InputStream is = new FileInputStream(wrapperProperties.toFile())) {
64+
Properties props = new Properties();
65+
props.load(is);
66+
String distributionUrl = props.getProperty(DISTRIBUTION_URL);
67+
if (distributionUrl == null) {
68+
return "Invalid the distributionUrl property";
69+
}
70+
String sha256Url = distributionUrl.replace("-bin.zip","").replace("-all.zip", "") + "-wrapper.jar.sha256";
71+
String checksum = hashProvider.getChecksum(wrapperJar.toFile());
72+
String remoteChecksum = downloadRequestsCache.getIfPresent(sha256Url);
73+
if (remoteChecksum == null) {
74+
URL url = new URL(sha256Url);
75+
BufferedReader in = null;
76+
try {
77+
URLConnection urlConnection = url.openConnection();
78+
in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
79+
remoteChecksum = in.readLine();
80+
downloadRequestsCache.put(sha256Url, remoteChecksum);
81+
} catch (IOException e) {
82+
JavaLanguageServerPlugin.logException("sha256url='" + sha256Url + "'. You can try to add '-Dgradle.wrapper.check.disabled=true' to 'java.jdt.ls.vmargs'", e);
83+
} finally {
84+
if (in != null) {
85+
in.close();
86+
}
87+
}
88+
}
89+
if (remoteChecksum != null && remoteChecksum.equals(checksum)) {
90+
return null;
91+
} else {
92+
return "Invalid wrapper checksum: local=" + checksum + ",remote=" + remoteChecksum;
93+
}
94+
}
95+
}
96+
97+
}

org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/managers/GradleProjectImporterTest.java

+9
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import org.eclipse.jdt.ls.core.internal.WorkspaceHelper;
5151
import org.eclipse.jdt.ls.core.internal.managers.ProjectsManager.CHANGE_TYPE;
5252
import org.eclipse.jdt.ls.core.internal.preferences.Preferences.FeatureStatus;
53+
import org.eclipse.jdt.ls.internal.gradle.checksums.WrapperValidator;
5354
import org.junit.After;
5455
import org.junit.Test;
5556
import org.junit.runner.RunWith;
@@ -158,6 +159,14 @@ public void testDisableGradleWrapper() throws Exception {
158159
}
159160
}
160161

162+
@Test
163+
public void testGradleWrapper() throws Exception {
164+
File file = new File(getSourceProjectDirectory(), "gradle/simple-gradle");
165+
assertTrue(file.isDirectory());
166+
String result = new WrapperValidator().checkWrapper(file.getAbsolutePath());
167+
assertNull(result);
168+
}
169+
161170
@Test
162171
public void testGradleUserHome() throws Exception {
163172
String gradleUserHomePreference = JavaLanguageServerPlugin.getPreferencesManager().getPreferences().getGradleUserHome();

0 commit comments

Comments
 (0)