mirror of
https://codeberg.org/PGPainless/sop-java.git
synced 2024-11-22 07:12:04 +01:00
Implement detection of non-UTF8 passwords
This commit is contained in:
parent
3e1502ff2a
commit
8877bae675
4 changed files with 80 additions and 8 deletions
|
@ -10,9 +10,9 @@ import java.io.FileInputStream;
|
|||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import sop.exception.SOPGPException;
|
||||
import sop.util.UTF8Util;
|
||||
|
||||
public class FileUtil {
|
||||
|
||||
|
@ -106,7 +106,7 @@ public class FileUtil {
|
|||
while ((read = inputStream.read(buf)) != -1) {
|
||||
byteOut.write(buf, 0, read);
|
||||
}
|
||||
return new String(byteOut.toByteArray(), Charset.forName("UTF8"));
|
||||
return UTF8Util.decodeUTF8(byteOut.toByteArray());
|
||||
} finally {
|
||||
inputStream.close();
|
||||
}
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
|
||||
package sop.exception;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public abstract class SOPGPException extends RuntimeException {
|
||||
|
||||
public SOPGPException() {
|
||||
|
@ -134,10 +132,6 @@ public abstract class SOPGPException extends RuntimeException {
|
|||
super();
|
||||
}
|
||||
|
||||
public PasswordNotHumanReadable(String message, IOException e) {
|
||||
super(message, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getExitCode() {
|
||||
return EXIT_CODE;
|
||||
|
|
39
sop-java/src/main/java/sop/util/UTF8Util.java
Normal file
39
sop-java/src/main/java/sop/util/UTF8Util.java
Normal file
|
@ -0,0 +1,39 @@
|
|||
// SPDX-FileCopyrightText: 2022 Paul Schaub <vanitasvitae@fsfe.org>
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package sop.util;
|
||||
|
||||
import sop.exception.SOPGPException;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.charset.CharacterCodingException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.CodingErrorAction;
|
||||
|
||||
public class UTF8Util {
|
||||
|
||||
private static final CharsetDecoder UTF8Decoder = Charset.forName("UTF8")
|
||||
.newDecoder()
|
||||
.onUnmappableCharacter(CodingErrorAction.REPORT)
|
||||
.onMalformedInput(CodingErrorAction.REPORT);
|
||||
|
||||
/**
|
||||
* Detect non-valid UTF8 data.
|
||||
*
|
||||
* @see <a href="https://stackoverflow.com/a/1471193">ante on StackOverflow</a>
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
public static String decodeUTF8(byte[] data) {
|
||||
ByteBuffer byteBuffer = ByteBuffer.wrap(data);
|
||||
try {
|
||||
CharBuffer charBuffer = UTF8Decoder.decode(byteBuffer);
|
||||
return charBuffer.toString();
|
||||
} catch (CharacterCodingException e) {
|
||||
throw new SOPGPException.PasswordNotHumanReadable();
|
||||
}
|
||||
}
|
||||
}
|
39
sop-java/src/test/java/sop/util/UTF8UtilTest.java
Normal file
39
sop-java/src/test/java/sop/util/UTF8UtilTest.java
Normal file
|
@ -0,0 +1,39 @@
|
|||
// SPDX-FileCopyrightText: 2022 Paul Schaub <vanitasvitae@fsfe.org>
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package sop.util;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import sop.exception.SOPGPException;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
public class UTF8UtilTest {
|
||||
|
||||
@Test
|
||||
public void testValidUtf8Decoding() {
|
||||
String utf8String = "Hello, World\n";
|
||||
String decoded = UTF8Util.decodeUTF8(utf8String.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
assertEquals(utf8String, decoded);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test detection of non-uft8 data.
|
||||
* @see <a href="https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt">
|
||||
* Markus Kuhn's UTF8 decoder capability and stress test file</a>
|
||||
*/
|
||||
@Test
|
||||
public void testInvalidUtf8StringThrows() {
|
||||
assertThrows(SOPGPException.PasswordNotHumanReadable.class,
|
||||
() -> UTF8Util.decodeUTF8(new byte[] {(byte) 0xa0, (byte) 0xa1}));
|
||||
assertThrows(SOPGPException.PasswordNotHumanReadable.class,
|
||||
() -> UTF8Util.decodeUTF8(new byte[] {(byte) 0xc0, (byte) 0xaf}));
|
||||
assertThrows(SOPGPException.PasswordNotHumanReadable.class,
|
||||
() -> UTF8Util.decodeUTF8(new byte[] {(byte) 0x80, (byte) 0xbf}));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue