Skip to content

Commit

Permalink
Test rejecting invalid charsets by JSON writer
Browse files Browse the repository at this point in the history
  • Loading branch information
pmwmedia committed Dec 20, 2021
1 parent 09bfd09 commit 57a450b
Show file tree
Hide file tree
Showing 5 changed files with 204 additions and 1 deletion.
4 changes: 3 additions & 1 deletion configuration/checkstyle-rules.xml
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,9 @@

<!-- Size Violations -->

<module name=" AnonInnerLength " />
<module name=" AnonInnerLength">
<property name="max" value="25" />
</module>
<module name="MethodLength">
<property name="max" value="200" />
</module>
Expand Down
97 changes: 97 additions & 0 deletions tinylog-impl/src/test/java/org/tinylog/util/CustomTestCharset.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* Copyright 2021 Martin Winandy
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/

package org.tinylog.util;

import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;

/**
* Custom charset that can read and write all ASCII characters. One defined character will be doubled to two bytes
* instead of one for testing different lengths for characters.
*/
public class CustomTestCharset extends Charset {

private final char longCharacter;

/**
* @param longCharacter This character will take two bytes instead of one
*/
public CustomTestCharset(final char longCharacter) {
super(String.format("CUSTOM-TEST-CHARSET-%02X", (short) longCharacter), new String[0]);
this.longCharacter = longCharacter;
}

@Override
public boolean contains(final Charset charset) {
return false;
}

@Override
public CharsetDecoder newDecoder() {
return new CharsetDecoder(this, 1, 2) {
@Override
protected CoderResult decodeLoop(final ByteBuffer in, final CharBuffer out) {
while (in.hasRemaining()) {
if (!out.hasRemaining()) {
return CoderResult.OVERFLOW;
}

byte character = in.get();

if (character == longCharacter) {
if (in.hasRemaining()) {
character = in.get();
} else {
in.position(in.position() - 1);
return CoderResult.UNDERFLOW;
}
}

out.put((char) character);
}

return CoderResult.UNDERFLOW;
}
};
}

@Override
public CharsetEncoder newEncoder() {
return new CharsetEncoder(this, 1, 2) {
@Override
protected CoderResult encodeLoop(final CharBuffer in, final ByteBuffer out) {
while (in.hasRemaining()) {
char character = in.get();
int length = character == longCharacter ? 2 : 1;

if (out.remaining() < length) {
in.position(in.position() - 1);
return CoderResult.OVERFLOW;
}

for (int i = 0; i < length; ++i) {
out.put((byte) character);
}
}

return CoderResult.UNDERFLOW;
}
};
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright 2021 Martin Winandy
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/

package org.tinylog.util;

import java.nio.charset.Charset;
import java.nio.charset.spi.CharsetProvider;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.tinylog.writers.JsonWriterTest;

/**
* Service factory for {@link CustomTestCharset}.
*/
public class CustomTestCharsetProvider extends CharsetProvider {

/**
* All required charsets for {@link JsonWriterTest.IllegalCharsetTest}.
*/
public static final List<Charset> CHARSETS = Stream.of('\n', '\r', ' ', '\t', ',', '[', ']')
.map(CustomTestCharset::new)
.collect(Collectors.toList());

/** */
public CustomTestCharsetProvider() {
}

@Override
public Iterator<Charset> charsets() {
return CHARSETS.iterator();
}

@Override
public Charset charsetForName(final String charsetName) {
return CHARSETS.stream()
.filter(charset -> Objects.equals(charsetName, charset.name()))
.findFirst()
.orElse(null);
}

}
48 changes: 48 additions & 0 deletions tinylog-impl/src/test/java/org/tinylog/writers/JsonWriterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import org.junit.Rule;
import org.junit.Test;
Expand All @@ -33,6 +34,7 @@
import org.tinylog.core.LogEntryValue;
import org.tinylog.core.TinylogLoggingProviderTest.LogEntryValues;
import org.tinylog.rules.SystemStreamCollector;
import org.tinylog.util.CustomTestCharsetProvider;
import org.tinylog.util.FileSystem;
import org.tinylog.util.LogEntryBuilder;

Expand Down Expand Up @@ -444,4 +446,50 @@ public void handlesInvalidCharset() throws IOException {

}

/**
* Tests for illegal charset validation.
*/
@RunWith(Parameterized.class)
public static class IllegalCharsetTest {

/**
* Redirects and collects system output streams.
*/
@Rule
public final SystemStreamCollector systemStream = new SystemStreamCollector(true);

private final Charset charset;

/**
* @param charset The illegal charset to validate
*/
public IllegalCharsetTest(final Charset charset) {
this.charset = charset;
}

/**
* Returns illegal charsets that should be tested.
*
* @return Each object array contains a single charset
*/
@Parameterized.Parameters(name = "{0}")
public static Collection<Object[]> getSizes() {
return CustomTestCharsetProvider.CHARSETS.stream()
.map(charset -> new Object[] {charset})
.collect(Collectors.toList());
}

@Test
public void validateCharset() throws IOException {
Map<String, String> properties = new HashMap<>();
properties.put("file", FileSystem.createTemporaryFile());
properties.put("charset", charset.name());

assertThatCode(() -> new JsonWriter(properties))
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining(charset.name());
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
org.tinylog.util.CustomTestCharsetProvider

0 comments on commit 57a450b

Please sign in to comment.