Skip to content

Commit

Permalink
Update RegressionTest to hash alternate views instead of base64 conve…
Browse files Browse the repository at this point in the history
…rting. (#625)
  • Loading branch information
jdcove2 authored Nov 29, 2023
1 parent a812cb0 commit ea3cdce
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 14 deletions.
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

0 comments on commit ea3cdce

Please sign in to comment.