Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
burningtnt committed Nov 17, 2024
1 parent 9edfe29 commit 63d50ae
Show file tree
Hide file tree
Showing 5 changed files with 193 additions and 13 deletions.
17 changes: 13 additions & 4 deletions HMCL/src/main/java/org/jackhuang/hmcl/game/LogExporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
import org.jackhuang.hmcl.util.io.Zipper;
import org.jackhuang.hmcl.util.platform.OperatingSystem;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.io.*;
import java.lang.management.ManagementFactory;
import java.nio.charset.StandardCharsets;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
Expand Down Expand Up @@ -94,8 +94,17 @@ private static void processLogs(Path directory, String fileExtension, String log
FileTime time = Files.readAttributes(file, BasicFileAttributes.class).lastModifiedTime();
if (time.toMillis() >= processStartTime) {
try {
String crashLog = Logger.filterForbiddenToken(FileUtils.readText(file, OperatingSystem.NATIVE_CHARSET));
zipper.putTextFile(crashLog, file.getFileName().toString());
if (Files.size(file) >= 1024 * 1024 * 5) {
try (
Reader reader = Files.newBufferedReader(file, OperatingSystem.NATIVE_CHARSET);
Writer writer = new BufferedWriter(new OutputStreamWriter(zipper.putStream(file.getFileName().toString()), StandardCharsets.UTF_8))
) {
Logger.filterForbiddenToken(reader, writer);
}
} else {
String crashLog = Logger.filterForbiddenToken(FileUtils.readText(file, OperatingSystem.NATIVE_CHARSET));
zipper.putTextFile(crashLog, file.getFileName().toString());
}
} catch (IOException e) {
LOG.warning("Failed to read log file: " + file, e);
}
Expand Down
44 changes: 40 additions & 4 deletions HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/Zipper.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,9 @@
package org.jackhuang.hmcl.util.io;

import org.jackhuang.hmcl.util.function.ExceptionalPredicate;
import org.jetbrains.annotations.NotNull;

import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
Expand Down Expand Up @@ -149,6 +147,44 @@ public void putFile(Path file, String path) throws IOException {
}
}

public OutputStream putStream(String path) throws IOException {
zos.putNextEntry(new ZipEntry(normalize(path)));

return new OutputStream() {
private volatile boolean closed;

private void ensureOpen() throws IOException {
if (closed) {
throw new IOException("Stream closed");
}
}

@Override
public void write(byte @NotNull [] b) throws IOException {
ensureOpen();
zos.write(b);
}

@Override
public void write(byte @NotNull [] b, int off, int len) throws IOException {
ensureOpen();
zos.write(b, off, len);
}

@Override
public void close() throws IOException {
closed = true;
zos.closeEntry();
}

@Override
public void write(int b) throws IOException {
ensureOpen();
zos.write(b);
}
};
}

public void putStream(InputStream in, String path) throws IOException {
zos.putNextEntry(new ZipEntry(normalize(path)));
IOUtils.copyTo(in, zos, buffer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
import org.tukaani.xz.XZOutputStream;

import java.io.*;
import java.nio.file.*;
import java.nio.file.DirectoryStream;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
Expand All @@ -25,7 +28,7 @@
public final class Logger {
public static final Logger LOG = new Logger();

private static volatile String[] accessTokens = new String[0];
static volatile String[] accessTokens = new String[0];

public static synchronized void registerAccessToken(String token) {
final String[] oldAccessTokens = accessTokens;
Expand All @@ -37,11 +40,12 @@ public static synchronized void registerAccessToken(String token) {
}

public static String filterForbiddenToken(String message) {
for (String token : accessTokens)
message = message.replace(token, "<access token>");
return message;
return TokenFence.filter(accessTokens, message);
}

public static void filterForbiddenToken(Reader reader, Writer out) throws IOException {
TokenFence.filter(accessTokens, reader, out);
}

static final String CLASS_NAME = Logger.class.getName();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package org.jackhuang.hmcl.util.logging;

import java.io.IOException;
import java.io.Reader;
import java.io.Writer;

final class TokenFence {
private TokenFence() {
}

public static String filter(String[] accessTokens, String message) {
for (String token : accessTokens)
message = message.replace(token, "<access token>");
return message;
}

public static void filter(String[] accessTokens, Reader reader, Writer out) throws IOException {
char[] buffer = new char[1024];
for (String token : accessTokens) {
if (token.length() > buffer.length) {
buffer = new char[token.length() + 16];
}
filter(token, reader, out, buffer);
}
}

private static void filter(String token, Reader reader, Writer out, char[] buffer) throws IOException {
char first = token.charAt(0);
int start = 0, length;
while ((length = reader.read(buffer, start, buffer.length - start)) != -1) {
int fi = TokenFence.indexOf(buffer, 0, length - token.length(), first);
if (fi == -1 || !TokenFence.isToken(buffer, fi, token)) {
int fi2 = TokenFence.indexOf(buffer, length - token.length(), buffer.length, first);
if (fi2 == -1) {
out.write(buffer, 0, length);
start = 0;
} else {
out.write(buffer, 0, fi2);
System.arraycopy(buffer, fi2, buffer, 0, length - fi2);
start = length - fi2;
}
} else {
out.write(buffer, 0, fi);
out.write("<access token>");
System.arraycopy(buffer, fi + token.length(), buffer, 0, token.length());
start = 0;
}
}
}


private static int indexOf(char[] buffer, int start, int length, char target) {
for (int i = start; i < length; i++) {
if (buffer[i] == target) {
return i;
}
}

return -1;
}

private static boolean isToken(char[] buffer, int start, String token) {
for (int i = 1; i < token.length(); i++) {
if (buffer[start + i] != token.charAt(i)) {
return false;
}
}

return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Hello Minecraft! Launcher
* Copyright (C) 2020 huangyuhui <[email protected]> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.jackhuang.hmcl.util.logger;

import org.jackhuang.hmcl.util.logging.Logger;
import org.junit.jupiter.api.Test;

import java.io.*;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;

public class LoggerTest {
private static final String TOKEN = "the_token";

@Test
public void checkTokenFence() throws IOException {
test("001122334455the_token667788", TOKEN);

{
char[] data = new char[1050];
TOKEN.getChars(0, TOKEN.length(), data, 1020);
test(data, TOKEN);
}
}

private void test(String data, String token) throws IOException {
test0(new StringReader(data), token);
}

private void test(char[] data, String token) throws IOException {
test0(new CharArrayReader(data), token);
}

private void test0(Reader reader, String token) throws IOException {
Logger.registerAccessToken(token);

try (StringWriter writer = new StringWriter()) {
Logger.filterForbiddenToken(reader, writer);

assertEquals(writer.getBuffer().indexOf(token), -1);
assertNotEquals(writer.getBuffer().indexOf("<access token>"), -1);
}
}
}

0 comments on commit 63d50ae

Please sign in to comment.