Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update RegressionTest to hash alternate views instead of base64 converting. #625

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 69 additions & 14 deletions src/main/java/emissary/core/IBaseDataObjectXmlCodecs.java
Original file line number Diff line number Diff line change
Expand Up @@ -475,9 +475,9 @@ public void encode(final List<SeekableByteChannelFactory> values, final Element
* An implementation of an XML element encoder for SeekableByteChannel's that produces a SHA256 hash value.
*/
public static final ElementEncoder<SeekableByteChannelFactory> SHA256_SEEKABLE_BYTE_CHANNEL_FACTORY_ENCODER =
new HashSeekableByteChannelFactoryEncoder();
new Sha256SeekableByteChannelFactoryEncoder();

private static class HashSeekableByteChannelFactoryEncoder implements ElementEncoder<SeekableByteChannelFactory> {
private static class Sha256SeekableByteChannelFactoryEncoder implements ElementEncoder<SeekableByteChannelFactory> {
@Override
public void encode(final List<SeekableByteChannelFactory> values, final Element parentElement, final String childElementName) {
for (final SeekableByteChannelFactory value : values) {
Expand Down Expand Up @@ -571,7 +571,7 @@ private static class BooleanEncoder implements ElementEncoder<Boolean> {
@Override
public void encode(final List<Boolean> values, final Element parentElement, final String childElementName) {
for (final boolean value : values) {
if ((Boolean) PRIMITVE_NAME_DEFAULT_MAP.get(childElementName) != value) {
if (!((Boolean) PRIMITVE_NAME_DEFAULT_MAP.get(childElementName)).equals(value)) {
parentElement.addContent(AbstractJDOMUtil.simpleElement(childElementName, value));
}
}
Expand Down Expand Up @@ -620,6 +620,23 @@ public void encode(final List<Map<String, byte[]>> values, final Element parentE
}
}

public static final ElementEncoder<Map<String, byte[]>> SHA256_STRING_BYTE_ARRAY_ENCODER = new Sha256StringByteArrayEncoder();

private static class Sha256StringByteArrayEncoder implements ElementEncoder<Map<String, byte[]>> {
@Override
public void encode(final List<Map<String, byte[]>> values, final Element parentElement, final String childElementName) {
for (final Map<String, byte[]> value : values) {
for (final Entry<String, byte[]> view : value.entrySet()) {
final Element metaElement = new Element(IbdoXmlElementNames.VIEW);

parentElement.addContent(metaElement);
metaElement.addContent(preserve(protectedElement(IbdoXmlElementNames.NAME, view.getKey())));
metaElement.addContent(preserve(protectedElementSha256(IbdoXmlElementNames.VALUE, view.getValue())));
}
}
}
}

/**
* The default set of XML element decoders.
*/
Expand Down Expand Up @@ -652,7 +669,7 @@ public void encode(final List<Map<String, byte[]>> values, final Element parentE
DEFAULT_BYTE_ARRAY_ENCODER,
DEFAULT_INTEGER_ENCODER,
SHA256_SEEKABLE_BYTE_CHANNEL_FACTORY_ENCODER,
DEFAULT_STRING_BYTE_ARRAY_ENCODER,
SHA256_STRING_BYTE_ARRAY_ENCODER,
DEFAULT_STRING_ENCODER,
DEFAULT_STRING_OBJECT_ENCODER);

Expand All @@ -675,26 +692,39 @@ public static byte[] extractBytes(final String encoding, final String elementVal
return elementValue.getBytes(StandardCharsets.UTF_8);
}

private static Element preserve(final Element element) {
/**
* Adds preservation attributes to an XML element.
*
* @param element to add preservation attributes to.
* @return the element passed in with the preservation elements added.
*/
public static Element preserve(final Element element) {
element.setAttribute("space", "preserve", XML_NAMESPACE);

return element;
}

private static Element protectedElement(final String name, final String string) {
/**
* Creates a protected XML string element.
*
* @param name of the XML element
* @param string value of the XML element
* @return the protected XML element.
*/
public static Element protectedElement(final String name, final String string) {
return protectedElementBase64(name, string.getBytes(StandardCharsets.UTF_8));
}

/**
* Creates a 'protected' element which can be encoded with base64 if it contains unsafe characters
* Creates a 'protected' element which can be encoded with base64 if it contains non-printable characters
*
* See method source for specific definition of 'unsafe'.
* See method source for specific definition of 'non-printable'.
*
* @param name of the element
* @param bytes to wrap, if they contain unsafe characters
* @param bytes to wrap, if they contain non-printable characters
* @return the created element
*/
private static Element protectedElementBase64(final String name, final byte[] bytes) {
public static Element protectedElementBase64(final String name, final byte[] bytes) {
final Element element = new Element(name);

if (ByteUtil.hasNonPrintableValues(bytes)) {
Expand All @@ -711,14 +741,39 @@ private static Element protectedElementBase64(final String name, final byte[] by
return element;
}

/**
* Creates a 'protected' element which can be hashed with sha256 if it contains non-printable characters
*
* See method source for specific definition of 'non-printable'.
*
* @param name of the element
* @param bytes to wrap, if they contain non-printable characters.
* @return the created element
*/
public static Element protectedElementSha256(final String name, final byte[] bytes) {
final Element element = new Element(name);

if (ByteUtil.hasNonPrintableValues(bytes)) {
element.setAttribute(IBaseDataObjectXmlCodecs.ENCODING_ATTRIBUTE_NAME, IBaseDataObjectXmlCodecs.SHA256);
element.addContent(ByteUtil.sha256Bytes(bytes));
} else {
element.addContent(new String(bytes, StandardCharsets.ISO_8859_1));
}

return element;
}

/**
* Gets the requested method object from the IBaseDataObject class.
*
* @throws SecurityException
* @throws NoSuchMethodException
* @param methodName name of the ibdo method
* @param parameterTypes list of ibdo method parameter types
* @throws SecurityException if a security manager is present and encounters a problem.
* @throws NoSuchMethodException if a matching method is not found
* @return the ibdo method object
*/
private static Method getIbdoMethod(final String name, final Class<?>... parameterTypes)
public static Method getIbdoMethod(final String methodName, final Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
return IBaseDataObject.class.getDeclaredMethod(name, parameterTypes);
return IBaseDataObject.class.getDeclaredMethod(methodName, parameterTypes);
}
}
6 changes: 6 additions & 0 deletions src/test/java/emissary/core/IBaseDataObjectXmlHelperTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map.Entry;
import java.util.Random;
import java.util.TreeMap;

import static emissary.core.IBaseDataObjectXmlCodecs.DEFAULT_ELEMENT_DECODERS;
import static emissary.core.IBaseDataObjectXmlCodecs.DEFAULT_ELEMENT_ENCODERS;
Expand Down Expand Up @@ -151,6 +153,10 @@ void testBase64Conversion() throws Exception {

expectedIbdo.setData(ByteUtil.sha256Bytes(bytes).getBytes(StandardCharsets.ISO_8859_1));

for (Entry<String, byte[]> entry : new TreeMap<>(expectedIbdo.getAlternateViews()).entrySet()) {
expectedIbdo.addAlternateView(entry.getKey(), ByteUtil.sha256Bytes(entry.getValue()).getBytes(StandardCharsets.ISO_8859_1));
}

final String sha256Diff = PlaceComparisonHelper.checkDifferences(expectedIbdo, sha256ActualIbdo, expectedChildren,
actualChildren, "testSha256Conversion", DiffCheckConfiguration.onlyCheckData());

Expand Down
6 changes: 6 additions & 0 deletions src/test/java/emissary/test/core/junit5/RegressionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map.Entry;
import java.util.TreeMap;

import static org.junit.jupiter.api.Assertions.fail;

Expand Down Expand Up @@ -143,6 +145,10 @@ protected void checkAnswersPreHook(final Document answers, final IBaseDataObject
return;
}

for (Entry<String, byte[]> entry : new TreeMap<>(payload.getAlternateViews()).entrySet()) {
payload.addAlternateView(entry.getKey(), ByteUtil.sha256Bytes(entry.getValue()).getBytes(StandardCharsets.ISO_8859_1));
}

if (payload.data() != null && ByteUtil.hasNonPrintableValues(payload.data())) {
final String hash = ByteUtil.sha256Bytes(payload.data());

Expand Down