1
- import java .io .{ BufferedInputStream , File , FileInputStream }
1
+ import java .io .File
2
2
import java .net .{URL , URLClassLoader }
3
3
import java .nio .file .StandardCopyOption .REPLACE_EXISTING
4
4
import java .nio .file .{FileSystemException , Files , Paths }
5
5
import java .text .DecimalFormat
6
6
import java .util .Date
7
+ import java .util .jar .JarFile
7
8
import java .util .zip .ZipFile
8
9
9
10
import CLI ._
@@ -14,6 +15,7 @@ import org.json4s.{DefaultFormats, Formats}
14
15
15
16
import scala .collection .JavaConverters ._
16
17
import scala .io .{Source , StdIn }
18
+ import scala .util .hashing .MurmurHash3
17
19
18
20
/**
19
21
* Contains all logic to update the local installation of ChatOverflow.
@@ -215,12 +217,13 @@ object Updater {
215
217
// Updater couldn't be updated, because Windows holds file locks on executing files including the updater.
216
218
// Skip update of it, it shouldn't change anyway. We can update it on *nix system in the case we reeeeealy need to.
217
219
// If it has changed and we can't auto-update, we do recommend the user to update the updater manually, but it is to the user to decide.
218
- val currentIs = new BufferedInputStream (new FileInputStream (s " ${conf.directory}/ChatOverflow.jar " ))
219
- val currentHash = Stream .continually(currentIs.read).takeWhile(_ != - 1 ).map(_.toByte).hashCode()
220
- val newIs = new BufferedInputStream (zip.getInputStream(entry))
221
- val newHash = Stream .continually(newIs.read).takeWhile(_ != - 1 ).map(_.toByte).hashCode()
220
+ val currentJar = new JarFile (s " ${conf.directory}/ChatOverflow.jar " )
222
221
223
- if (currentHash != newHash) {
222
+ val tempNewJar = File .createTempFile(" ChatOverflow-Updater" , " " )
223
+ Files .write(tempNewJar.toPath, is.readAllBytes())
224
+ val newJar = new JarFile (tempNewJar)
225
+
226
+ if (hashJar(currentJar) != hashJar(newJar)) {
224
227
println(" The ChatOverflow updater has been updated and we can't update it for you when running on Windows.\n " +
225
228
" It's highly recommended to override the 'ChatOverflow.jar' of your installation with the new version\n " +
226
229
s " that can be found in the zip file at $zipFile. \n ChatOverflow may still work fine with this version, " +
@@ -232,6 +235,8 @@ object Updater {
232
235
is.close()
233
236
})
234
237
238
+ zip.close()
239
+
235
240
// Re-set the executable flag for *nix systems
236
241
new File (conf.directory).listFiles()
237
242
.filter(f => f.isFile && f.getName.startsWith(" ChatOverflow." ))
@@ -244,7 +249,18 @@ object Updater {
244
249
}
245
250
246
251
/**
247
- * Gets the local installed version, e.g. 0.3-prealpha.
252
+ * Hashes contents of the jar and doesn't include any timestamps,
253
+ * because they would be included in a hash of the full jar but doesn't say anything about the content.
254
+ */
255
+ def hashJar (jar : JarFile ): Int = {
256
+ jar.entries().asScala
257
+ .map(entry => jar.getInputStream(entry))
258
+ .map(is => is.readAllBytes())
259
+ .map(arr => MurmurHash3 .arrayHash(arr)).sum
260
+ }
261
+
262
+ /**
263
+ * Gets the local installed version, e.g. 3.0.0-prealpha.
248
264
*
249
265
* @return if successfully the version, otherwise None.
250
266
*/
0 commit comments