diff --git a/.gitignore b/.gitignore index e0f94da2..69fb61ad 100644 --- a/.gitignore +++ b/.gitignore @@ -9,9 +9,13 @@ nbproject/ nbactions.xml.project nbactions.xml -# IntelliJ -.idea/ +### IntelliJ IDEA ### +.idea/* +!.idea/inspectionProfiles +!.idea/runConfigurations +*.iws *.iml +*.ipr # VS Code .vscode/ diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 00000000..0ad4972f --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,323 @@ + + + + \ No newline at end of file diff --git a/src/main/java/de/rub/nds/modifiablevariable/FileConfigurationException.java b/src/main/java/de/rub/nds/modifiablevariable/FileConfigurationException.java index e1d0f700..fbc01d75 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/FileConfigurationException.java +++ b/src/main/java/de/rub/nds/modifiablevariable/FileConfigurationException.java @@ -9,7 +9,9 @@ public class FileConfigurationException extends RuntimeException { - public FileConfigurationException() {} + public FileConfigurationException() { + super(); + } public FileConfigurationException(Exception ex) { super(ex); diff --git a/src/main/java/de/rub/nds/modifiablevariable/ModifiableVariable.java b/src/main/java/de/rub/nds/modifiablevariable/ModifiableVariable.java index fe196ed1..d9ad5aea 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/ModifiableVariable.java +++ b/src/main/java/de/rub/nds/modifiablevariable/ModifiableVariable.java @@ -7,52 +7,25 @@ */ package de.rub.nds.modifiablevariable; -import de.rub.nds.modifiablevariable.biginteger.BigIntegerAddModification; -import de.rub.nds.modifiablevariable.biginteger.BigIntegerExplicitValueModification; -import de.rub.nds.modifiablevariable.biginteger.BigIntegerInteractiveModification; -import de.rub.nds.modifiablevariable.biginteger.BigIntegerMultiplyModification; -import de.rub.nds.modifiablevariable.biginteger.BigIntegerShiftLeftModification; -import de.rub.nds.modifiablevariable.biginteger.BigIntegerShiftRightModification; -import de.rub.nds.modifiablevariable.biginteger.BigIntegerSubtractModification; -import de.rub.nds.modifiablevariable.biginteger.BigIntegerXorModification; +import de.rub.nds.modifiablevariable.biginteger.*; import de.rub.nds.modifiablevariable.bool.BooleanExplicitValueModification; import de.rub.nds.modifiablevariable.bool.BooleanToggleModification; -import de.rub.nds.modifiablevariable.bytearray.ByteArrayDeleteModification; -import de.rub.nds.modifiablevariable.bytearray.ByteArrayDuplicateModification; -import de.rub.nds.modifiablevariable.bytearray.ByteArrayExplicitValueModification; -import de.rub.nds.modifiablevariable.bytearray.ByteArrayInsertModification; -import de.rub.nds.modifiablevariable.bytearray.ByteArrayShuffleModification; -import de.rub.nds.modifiablevariable.bytearray.ByteArrayXorModification; -import de.rub.nds.modifiablevariable.integer.IntegerAddModification; -import de.rub.nds.modifiablevariable.integer.IntegerExplicitValueModification; -import de.rub.nds.modifiablevariable.integer.IntegerShiftLeftModification; -import de.rub.nds.modifiablevariable.integer.IntegerShiftRightModification; -import de.rub.nds.modifiablevariable.integer.IntegerSubtractModification; -import de.rub.nds.modifiablevariable.integer.IntegerXorModification; -import de.rub.nds.modifiablevariable.longint.LongAddModification; -import de.rub.nds.modifiablevariable.longint.LongExplicitValueModification; -import de.rub.nds.modifiablevariable.longint.LongSubtractModification; -import de.rub.nds.modifiablevariable.longint.LongXorModification; -import de.rub.nds.modifiablevariable.singlebyte.ByteAddModification; -import de.rub.nds.modifiablevariable.singlebyte.ByteExplicitValueModification; -import de.rub.nds.modifiablevariable.singlebyte.ByteSubtractModification; -import de.rub.nds.modifiablevariable.singlebyte.ByteXorModification; -import de.rub.nds.modifiablevariable.string.StringAppendValueModification; -import de.rub.nds.modifiablevariable.string.StringExplicitValueModification; -import de.rub.nds.modifiablevariable.string.StringPrependValueModification; -import jakarta.xml.bind.annotation.XmlAccessType; -import jakarta.xml.bind.annotation.XmlAccessorType; -import jakarta.xml.bind.annotation.XmlElement; -import jakarta.xml.bind.annotation.XmlElements; -import jakarta.xml.bind.annotation.XmlRootElement; -import jakarta.xml.bind.annotation.XmlTransient; +import de.rub.nds.modifiablevariable.bytearray.*; +import de.rub.nds.modifiablevariable.integer.*; +import de.rub.nds.modifiablevariable.longint.*; +import de.rub.nds.modifiablevariable.path.*; +import de.rub.nds.modifiablevariable.singlebyte.*; +import de.rub.nds.modifiablevariable.string.*; +import jakarta.xml.bind.annotation.*; import java.io.Serializable; +import java.util.LinkedList; import java.util.Objects; +import java.util.stream.Collectors; /** * The base abstract class for modifiable variables, including the getValue function.The class needs - * to be defined transient to allow propOrder definition in subclasses, see: - * http://blog.bdoughan.com/2011/06/ignoring-inheritance-with-xmltransient.html + * to be defined transient to allow propOrder definition in subclasses, see: ... * * @param */ @@ -61,130 +34,262 @@ @XmlAccessorType(XmlAccessType.FIELD) public abstract class ModifiableVariable implements Serializable { - @XmlElements( - value = { - @XmlElement( - type = BigIntegerXorModification.class, - name = "BigIntegerXorModification"), - @XmlElement( - type = BigIntegerSubtractModification.class, - name = "BigIntegerSubtractModification"), - @XmlElement( - type = BigIntegerShiftRightModification.class, - name = "BigIntegerShiftRightModification"), - @XmlElement( - type = BigIntegerShiftLeftModification.class, - name = "BigIntegerShiftLeftModification"), - @XmlElement( - type = BigIntegerExplicitValueModification.class, - name = "BigIntegerExplicitValueModification"), - @XmlElement( - type = BigIntegerAddModification.class, - name = "BigIntegerAddModification"), - @XmlElement( - type = BigIntegerInteractiveModification.class, - name = "BigIntegerInteractiveModification"), - @XmlElement( - type = BigIntegerMultiplyModification.class, - name = "BigIntegerMultiplyModification"), - @XmlElement( - type = BooleanToggleModification.class, - name = "BooleanToggleModification"), - @XmlElement( - type = BooleanExplicitValueModification.class, - name = "BooleanExplicitValueModification"), - @XmlElement( - type = ByteArrayXorModification.class, - name = "ByteArrayXorModification"), - @XmlElement( - type = ByteArrayShuffleModification.class, - name = "ByteArrayShuffleModification"), - @XmlElement( - type = ByteArrayInsertModification.class, - name = "ByteArrayInsertModification"), - @XmlElement( - type = ByteArrayExplicitValueModification.class, - name = "ByteArrayExplicitValueModification"), - @XmlElement( - type = ByteArrayDuplicateModification.class, - name = "ByteArrayDuplicateModification"), - @XmlElement( - type = ByteArrayDeleteModification.class, - name = "ByteArrayDeleteModification"), - @XmlElement(type = IntegerXorModification.class, name = "IntegerXorModification"), - @XmlElement( - type = IntegerSubtractModification.class, - name = "IntegerSubtractModification"), - @XmlElement( - type = IntegerShiftRightModification.class, - name = "IntegerShiftRightModification"), - @XmlElement( - type = IntegerShiftLeftModification.class, - name = "IntegerShiftLeftModification"), - @XmlElement( - type = IntegerExplicitValueModification.class, - name = "IntegerExplicitValueModification"), - @XmlElement(type = IntegerAddModification.class, name = "IntegerAddModification"), - @XmlElement(type = LongXorModification.class, name = "LongXorModification"), - @XmlElement( - type = LongSubtractModification.class, - name = "LongSubtractModification"), - @XmlElement( - type = LongExplicitValueModification.class, - name = "LongExplicitValueModification"), - @XmlElement(type = LongAddModification.class, name = "LongAddModification"), - @XmlElement(type = ByteXorModification.class, name = "ByteXorModification"), - @XmlElement( - type = ByteSubtractModification.class, - name = "ByteSubtractModification"), - @XmlElement(type = ByteAddModification.class, name = "ByteAddModification"), - @XmlElement( - type = ByteExplicitValueModification.class, - name = "ByteExplicitValueModification"), - @XmlElement( - type = StringPrependValueModification.class, - name = "StringPrependValueModification"), - @XmlElement( - type = StringAppendValueModification.class, - name = "StringAppendValueModification"), - @XmlElement( - type = StringExplicitValueModification.class, - name = "StringExplicitValueModification") - }) - private VariableModification modification = null; + @XmlElementWrapper + @XmlElements({ + @XmlElement(type = BigIntegerXorModification.class, name = "BigIntegerXorModification"), + @XmlElement( + type = BigIntegerSubtractModification.class, + name = "BigIntegerSubtractModification"), + @XmlElement( + type = BigIntegerShiftRightModification.class, + name = "BigIntegerShiftRightModification"), + @XmlElement( + type = BigIntegerShiftLeftModification.class, + name = "BigIntegerShiftLeftModification"), + @XmlElement( + type = BigIntegerExplicitValueFromFileModification.class, + name = "BigIntegerExplicitValueFromFileModification"), + @XmlElement( + type = BigIntegerExplicitValueModification.class, + name = "BigIntegerExplicitValueModification"), + @XmlElement(type = BigIntegerAddModification.class, name = "BigIntegerAddModification"), + @XmlElement( + type = BigIntegerInteractiveModification.class, + name = "BigIntegerInteractiveModification"), + @XmlElement( + type = BigIntegerMultiplyModification.class, + name = "BigIntegerMultiplyModification"), + @XmlElement( + type = BigIntegerAppendValueModification.class, + name = "BigIntegerAppendValueModification"), + @XmlElement( + type = BigIntegerInsertValueModification.class, + name = "BigIntegerInsertValueModification"), + @XmlElement( + type = BigIntegerPrependValueModification.class, + name = "BigIntegerPrependValueModification"), + @XmlElement(type = BooleanToggleModification.class, name = "BooleanToggleModification"), + @XmlElement( + type = BooleanExplicitValueModification.class, + name = "BooleanExplicitValueModification"), + @XmlElement(type = ByteArrayXorModification.class, name = "ByteArrayXorModification"), + @XmlElement( + type = ByteArrayShuffleModification.class, + name = "ByteArrayShuffleModification"), + @XmlElement( + type = ByteArrayAppendValueModification.class, + name = "ByteArrayAppendValueModification"), + @XmlElement( + type = ByteArrayInsertValueModification.class, + name = "ByteArrayInsertValueModification"), + @XmlElement( + type = ByteArrayPrependValueModification.class, + name = "ByteArrayPrependValueModification"), + @XmlElement( + type = ByteArrayExplicitValueFromFileModification.class, + name = "ByteArrayExplicitValueFromFileModification"), + @XmlElement( + type = ByteArrayExplicitValueModification.class, + name = "ByteArrayExplicitValueModification"), + @XmlElement( + type = ByteArrayDuplicateModification.class, + name = "ByteArrayDuplicateModification"), + @XmlElement(type = ByteArrayDeleteModification.class, name = "ByteArrayDeleteModification"), + @XmlElement( + type = IntegerSwapEndianModification.class, + name = "IntegerSwapEndianModification"), + @XmlElement(type = IntegerXorModification.class, name = "IntegerXorModification"), + @XmlElement(type = IntegerSubtractModification.class, name = "IntegerSubtractModification"), + @XmlElement(type = IntegerMultiplyModification.class, name = "IntegerMultiplyModification"), + @XmlElement( + type = IntegerShiftRightModification.class, + name = "IntegerShiftRightModification"), + @XmlElement( + type = IntegerShiftLeftModification.class, + name = "IntegerShiftLeftModification"), + @XmlElement( + type = IntegerExplicitValueFromFileModification.class, + name = "IntegerExplicitValueFromFileModification"), + @XmlElement( + type = IntegerExplicitValueModification.class, + name = "IntegerExplicitValueModification"), + @XmlElement(type = IntegerAddModification.class, name = "IntegerAddModification"), + @XmlElement( + type = IntegerAppendValueModification.class, + name = "IntegerAppendValueModification"), + @XmlElement( + type = IntegerInsertValueModification.class, + name = "IntegerInsertValueModification"), + @XmlElement( + type = IntegerPrependValueModification.class, + name = "IntegerPrependValueModification"), + @XmlElement(type = LongXorModification.class, name = "LongXorModification"), + @XmlElement(type = LongSwapEndianModification.class, name = "LongSwapEndianModification"), + @XmlElement(type = LongSubtractModification.class, name = "LongSubtractModification"), + @XmlElement( + type = LongExplicitValueFromFileModification.class, + name = "LongExplicitValueFromFileModification"), + @XmlElement( + type = LongExplicitValueModification.class, + name = "LongExplicitValueModification"), + @XmlElement(type = LongAppendValueModification.class, name = "LongAppendValueModification"), + @XmlElement(type = LongInsertValueModification.class, name = "LongInsertValueModification"), + @XmlElement( + type = LongPrependValueModification.class, + name = "LongPrependValueModification"), + @XmlElement(type = LongMultiplyModification.class, name = "LongMultiplyModification"), + @XmlElement(type = LongShiftLeftModification.class, name = "LongShiftLeftModification"), + @XmlElement(type = LongShiftRightModification.class, name = "LongShiftRightModification"), + @XmlElement(type = LongAddModification.class, name = "LongAddModification"), + @XmlElement(type = ByteXorModification.class, name = "ByteXorModification"), + @XmlElement(type = ByteSubtractModification.class, name = "ByteSubtractModification"), + @XmlElement(type = ByteAddModification.class, name = "ByteAddModification"), + @XmlElement( + type = ByteExplicitValueFromFileModification.class, + name = "ByteExplicitValueFromFileModification"), + @XmlElement( + type = ByteExplicitValueModification.class, + name = "ByteExplicitValueModification"), + @XmlElement( + type = StringPrependValueModification.class, + name = "StringPrependValueModification"), + @XmlElement( + type = StringAppendValueModification.class, + name = "StringAppendValueModification"), + @XmlElement( + type = StringExplicitValueFromFileModification.class, + name = "StringExplicitValueFromFileModification"), + @XmlElement( + type = StringExplicitValueModification.class, + name = "StringExplicitValueModification"), + @XmlElement( + type = StringInsertValueModification.class, + name = "StringInsertValueModification"), + @XmlElement(type = StringDeleteModification.class, name = "StringDeleteModification"), + @XmlElement( + type = PathExplicitValueFromFileModification.class, + name = "PathExplicitValueFromFileModification"), + @XmlElement( + type = PathExplicitValueModification.class, + name = "PathExplicitValueModification"), + @XmlElement(type = PathAppendValueModification.class, name = "PathAppendValueModification"), + @XmlElement( + type = PathInsertDirectorySeparatorModification.class, + name = "PathInsertDirectorySeparatorModification"), + @XmlElement(type = PathDeleteModification.class, name = "PathDeleteModification"), + @XmlElement( + type = PathInsertDirectoryTraversalModification.class, + name = "PathInsertDirectoryTraversalValueModification"), + @XmlElement(type = PathInsertValueModification.class, name = "PathInsertValueModification"), + @XmlElement( + type = PathPrependValueModification.class, + name = "PathPrependValueModification"), + @XmlElement( + type = PathToggleRootModification.class, + name = "PathToggleRootValueModification"), + }) + private LinkedList> modifications; private Boolean createRandomModification; protected E assertEquals; - public ModifiableVariable() {} + protected ModifiableVariable() { + super(); + } + + protected ModifiableVariable(ModifiableVariable other) { + super(); + if (other.modifications != null) { + modifications = new LinkedList<>(); + for (VariableModification item : other.modifications) { + modifications.add(item != null ? item.createCopy() : null); + } + } + createRandomModification = other.createRandomModification; + // Warning: Make sure to copy assertEquals in subclass correctly + assertEquals = other.assertEquals; + } + /** Set a single modification, all previously set modifications are removed */ public void setModification(VariableModification modification) { - this.modification = modification; + if (modification != null) { + modifications = new LinkedList<>(); + modifications.add(modification); + } else { + modifications = null; + } } - @XmlTransient + /** Adds a modification to this modifiable variable */ + public void addModification(VariableModification modification) { + if (modification != null) { + if (modifications == null) { + modifications = new LinkedList<>(); + } + modifications.add(modification); + } + } + + /** + * Returns the first modification that was set for this modifiable variable, if one exists. + * + *

Use {@code getModifications()} to get all modifications + */ public VariableModification getModification() { - return modification; + if (modifications == null || modifications.isEmpty()) { + return null; + } + return modifications.getFirst(); + } + + /** Returns all modifications that are set for this modifiable variable */ + public LinkedList> getModifications() { + return modifications; } public E getValue() { if (Objects.equals(createRandomModification, Boolean.TRUE)) { - createRandomModification(); + setRandomModification(); createRandomModification = false; } - if (modification != null) { - return modification.modify(getOriginalValue()); + return getModifiedValue(); + } + + private E getModifiedValue() { + E resultValue = getOriginalValue(); + if (modifications != null) { + for (VariableModification modification : modifications) { + resultValue = modification.modify(resultValue); + } + } + return resultValue; + } + + /** + * Sets the original value to the value changed by the modification. The modification is then + * set to null, to reduce the modifiable variable to the original value. + * + *

createRandomModification is ignored + */ + public void reduceToOriginalValue(boolean evenWithNullOriginalValue) { + if (evenWithNullOriginalValue || getOriginalValue() != null) { + if (modifications != null) { + setOriginalValue(getModifiedValue()); + modifications = null; + } } - return getOriginalValue(); } public abstract E getOriginalValue(); public abstract void setOriginalValue(E originalValue); - protected abstract void createRandomModification(); + /** Set a single random modification, all previously set modifications are removed */ + public abstract void setRandomModification(); + + public abstract ModifiableVariable createCopy(); public void createRandomModificationAtRuntime() { createRandomModification = true; @@ -195,13 +300,31 @@ public void createRandomModificationAtRuntime() { public abstract boolean validateAssertions(); public boolean containsAssertion() { - return (assertEquals != null); + return assertEquals != null; } public Boolean isCreateRandomModification() { - if (createRandomModification == null) { - return false; + return Objects.requireNonNullElse(createRandomModification, false); + } + + public String innerToString() { + StringBuilder result = new StringBuilder(); + if (modifications != null) { + result.append(", modifications=[") + .append( + modifications.stream() + .map(Object::toString) + .collect(Collectors.joining(", "))) + .append("]"); + } + + if (createRandomModification != null) { + result.append(", createRandomModification=").append(createRandomModification); + } + if (assertEquals != null) { + result.append(", assertEquals=").append(assertEquals); } - return createRandomModification; + + return result.toString(); } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/ModifiableVariableFactory.java b/src/main/java/de/rub/nds/modifiablevariable/ModifiableVariableFactory.java index 19b9a22d..3c0d2f1a 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/ModifiableVariableFactory.java +++ b/src/main/java/de/rub/nds/modifiablevariable/ModifiableVariableFactory.java @@ -12,11 +12,12 @@ import de.rub.nds.modifiablevariable.bytearray.ModifiableByteArray; import de.rub.nds.modifiablevariable.integer.ModifiableInteger; import de.rub.nds.modifiablevariable.longint.ModifiableLong; +import de.rub.nds.modifiablevariable.path.ModifiablePath; import de.rub.nds.modifiablevariable.singlebyte.ModifiableByte; import de.rub.nds.modifiablevariable.string.ModifiableString; import java.math.BigInteger; -public class ModifiableVariableFactory { +public final class ModifiableVariableFactory { public static ModifiableBigInteger createBigIntegerModifiableVariable() { return new ModifiableBigInteger(); @@ -38,61 +39,297 @@ public static ModifiableLong createLongModifiableVariable() { return new ModifiableLong(); } + public static ModifiableBoolean createBooleanModifiableVariable() { + return new ModifiableBoolean(); + } + + public static ModifiableString createStringModifiableVariable() { + return new ModifiableString(); + } + + public static ModifiablePath createPathModifiableVariable() { + return new ModifiablePath(); + } + public static ModifiableBigInteger safelySetValue(ModifiableBigInteger mv, BigInteger value) { if (mv == null) { - mv = new ModifiableBigInteger(); + return new ModifiableBigInteger(value); } mv.setOriginalValue(value); return mv; } + /** + * Returns only a ModifiableBigInteger with the value, if the given mv is null or the original + * value of the mv is null + */ + public static ModifiableBigInteger softlySetValue(ModifiableBigInteger mv, BigInteger value) { + if (mv == null) { + return new ModifiableBigInteger(value); + } else if (mv.getOriginalValue() == null) { + mv.setOriginalValue(value); + } + return mv; + } + + /** + * Returns only a ModifiableBigInteger with the value, if the given mv is null or the original + * value of the mv is null or alwaysSet is true + */ + public static ModifiableBigInteger softlySetValue( + ModifiableBigInteger mv, BigInteger value, boolean alwaysSet) { + if (mv == null) { + return new ModifiableBigInteger(value); + } else if (alwaysSet || mv.getOriginalValue() == null) { + mv.setOriginalValue(value); + } + return mv; + } + public static ModifiableString safelySetValue(ModifiableString mv, String value) { if (mv == null) { - mv = new ModifiableString(); + return new ModifiableString(value); } mv.setOriginalValue(value); return mv; } + /** + * Returns only a ModifiableString with the value, if the given mv is null or the original value + * of the mv is null + */ + public static ModifiableString softlySetValue(ModifiableString mv, String value) { + if (mv == null) { + return new ModifiableString(value); + } else if (mv.getOriginalValue() == null) { + mv.setOriginalValue(value); + } + return mv; + } + + /** + * Returns only a ModifiableString with the value, if the given mv is null or the original value + * of the mv is null or alwaysSet is true + */ + public static ModifiableString softlySetValue( + ModifiableString mv, String value, boolean alwaysSet) { + if (mv == null) { + return new ModifiableString(value); + } else if (alwaysSet || mv.getOriginalValue() == null) { + mv.setOriginalValue(value); + } + return mv; + } + public static ModifiableInteger safelySetValue(ModifiableInteger mv, Integer value) { if (mv == null) { - mv = new ModifiableInteger(); + return new ModifiableInteger(value); } mv.setOriginalValue(value); return mv; } + /** + * Returns only a ModifiableInteger with the value, if the given mv is null or the original + * value of the mv is null + */ + public static ModifiableInteger softlySetValue(ModifiableInteger mv, Integer value) { + if (mv == null) { + return new ModifiableInteger(value); + } else if (mv.getOriginalValue() == null) { + mv.setOriginalValue(value); + } + return mv; + } + + /** + * Returns only a ModifiableInteger with the value, if the given mv is null or the original + * value of the mv is null or alwaysSet is true + */ + public static ModifiableInteger softlySetValue( + ModifiableInteger mv, Integer value, boolean alwaysSet) { + if (mv == null) { + return new ModifiableInteger(value); + } else if (alwaysSet || mv.getOriginalValue() == null) { + mv.setOriginalValue(value); + } + return mv; + } + public static ModifiableByte safelySetValue(ModifiableByte mv, Byte value) { if (mv == null) { - mv = new ModifiableByte(); + return new ModifiableByte(value); } mv.setOriginalValue(value); return mv; } + /** + * Returns only a ModifiableByte with the value, if the given mv is null or the original value + * of the mv is null + */ + public static ModifiableByte softlySetValue(ModifiableByte mv, Byte value) { + if (mv == null) { + return new ModifiableByte(value); + } else if (mv.getOriginalValue() == null) { + mv.setOriginalValue(value); + } + return mv; + } + + /** + * Returns only a ModifiableByte with the value, if the given mv is null or the original value + * of the mv is null or alwaysSet is true + */ + public static ModifiableByte softlySetValue(ModifiableByte mv, Byte value, boolean alwaysSet) { + if (mv == null) { + return new ModifiableByte(value); + } else if (alwaysSet || mv.getOriginalValue() == null) { + mv.setOriginalValue(value); + } + return mv; + } + public static ModifiableByteArray safelySetValue(ModifiableByteArray mv, byte[] value) { if (mv == null) { - mv = new ModifiableByteArray(); + return new ModifiableByteArray(value); } mv.setOriginalValue(value); return mv; } + /** + * Returns only a ModifiableByteArray with the value, if the given mv is null or the original + * value of the mv is null + */ + public static ModifiableByteArray softlySetValue(ModifiableByteArray mv, byte[] value) { + if (mv == null) { + return new ModifiableByteArray(value); + } else if (mv.getOriginalValue() == null) { + mv.setOriginalValue(value); + } + return mv; + } + + /** + * Returns only a ModifiableByteArray with the value, if the given mv is null or the original + * value of the mv is null or alwaysSet is true + */ + public static ModifiableByteArray softlySetValue( + ModifiableByteArray mv, byte[] value, boolean alwaysSet) { + if (mv == null) { + return new ModifiableByteArray(value); + } else if (alwaysSet || mv.getOriginalValue() == null) { + mv.setOriginalValue(value); + } + return mv; + } + public static ModifiableLong safelySetValue(ModifiableLong mv, Long value) { if (mv == null) { - mv = new ModifiableLong(); + return new ModifiableLong(value); } mv.setOriginalValue(value); return mv; } + /** + * Returns only a ModifiableLong with the value, if the given mv is null or the original value + * of the mv is null + */ + public static ModifiableLong softlySetValue(ModifiableLong mv, Long value) { + if (mv == null) { + return new ModifiableLong(value); + } else if (mv.getOriginalValue() == null) { + mv.setOriginalValue(value); + } + return mv; + } + + /** + * Returns only a ModifiableLong with the value, if the given mv is null or the original value + * of the mv is null or alwaysSet is true + */ + public static ModifiableLong softlySetValue(ModifiableLong mv, Long value, boolean alwaysSet) { + if (mv == null) { + return new ModifiableLong(value); + } else if (alwaysSet || mv.getOriginalValue() == null) { + mv.setOriginalValue(value); + } + return mv; + } + public static ModifiableBoolean safelySetValue(ModifiableBoolean mv, Boolean value) { if (mv == null) { - mv = new ModifiableBoolean(); + return new ModifiableBoolean(value); + } + mv.setOriginalValue(value); + return mv; + } + + /** + * Returns only a ModifiableBoolean with the value, if the given mv is null or the original + * value of the mv is null + */ + public static ModifiableBoolean softlySetValue(ModifiableBoolean mv, Boolean value) { + if (mv == null) { + return new ModifiableBoolean(value); + } else if (mv.getOriginalValue() == null) { + mv.setOriginalValue(value); + } + return mv; + } + + /** + * Returns only a ModifiableBoolean with the value, if the given mv is null or the original + * value of the mv is null or alwaysSet is true + */ + public static ModifiableBoolean softlySetValue( + ModifiableBoolean mv, Boolean value, boolean alwaysSet) { + if (mv == null) { + return new ModifiableBoolean(value); + } else if (alwaysSet || mv.getOriginalValue() == null) { + mv.setOriginalValue(value); + } + return mv; + } + + public static ModifiablePath safelySetValue(ModifiablePath mv, String value) { + if (mv == null) { + return new ModifiablePath(value); } mv.setOriginalValue(value); return mv; } - private ModifiableVariableFactory() {} + /** + * Returns only a ModifiablePath with the value, if the given mv is null or the original value + * of the mv is null + */ + public static ModifiablePath softlySetValue(ModifiablePath mv, String value) { + if (mv == null) { + return new ModifiablePath(value); + } else if (mv.getOriginalValue() == null) { + mv.setOriginalValue(value); + } + return mv; + } + + /** + * Returns only a ModifiablePath with the value, if the given mv is null or the original value + * of the mv is null or alwaysSet is true + */ + public static ModifiablePath softlySetValue( + ModifiablePath mv, String value, boolean alwaysSet) { + if (mv == null) { + return new ModifiablePath(value); + } else if (alwaysSet || mv.getOriginalValue() == null) { + mv.setOriginalValue(value); + } + return mv; + } + + private ModifiableVariableFactory() { + super(); + } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/ModifiableVariableHolder.java b/src/main/java/de/rub/nds/modifiablevariable/ModifiableVariableHolder.java index 137fc7b8..73bc4928 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/ModifiableVariableHolder.java +++ b/src/main/java/de/rub/nds/modifiablevariable/ModifiableVariableHolder.java @@ -30,7 +30,7 @@ public abstract class ModifiableVariableHolder implements Serializable { * @return List of all modifiableVariables declared in this class */ public List getAllModifiableVariableFields() { - return ReflectionHelper.getFieldsUpTo(this.getClass(), null, ModifiableVariable.class); + return ReflectionHelper.getFieldsUpTo(getClass(), null, ModifiableVariable.class); } /** @@ -70,12 +70,12 @@ public ModifiableVariableHolder getRandomModifiableVariableHolder(Random random) public void reset() { List fields = getAllModifiableVariableFields(); - for (Field f : fields) { - f.setAccessible(true); + for (Field field : fields) { + field.setAccessible(true); ModifiableVariable mv = null; try { - mv = (ModifiableVariable) f.get(this); + mv = (ModifiableVariable) field.get(this); } catch (IllegalArgumentException | IllegalAccessException ex) { LOGGER.warn("Could not retrieve ModifiableVariables"); LOGGER.debug(ex); @@ -85,7 +85,7 @@ public void reset() { mv.setOriginalValue(null); } else { try { - f.set(this, null); + field.set(this, null); } catch (IllegalArgumentException | IllegalAccessException ex) { LOGGER.warn("Could not strip ModifiableVariable without Modification"); } @@ -95,17 +95,12 @@ public void reset() { } public String getExtendedString() { - StringBuilder sb = new StringBuilder(); - sb.append(getClass().getSimpleName()); - sb.append("{\n"); - sb.append(getExtendedString(1)); - sb.append("}\n"); - return sb.toString(); + return getClass().getSimpleName() + "{\n" + getExtendedString(1) + "}\n"; } protected String getExtendedString(int depth) { StringBuilder stringBuilder = new StringBuilder(); - List fields = ReflectionHelper.getFieldsUpTo(this.getClass(), null, null); + List fields = ReflectionHelper.getFieldsUpTo(getClass(), null, null); for (Field field : fields) { field.setAccessible(true); // skip static @@ -122,41 +117,31 @@ protected String getExtendedString(int depth) { if (tempObject != null) { if (tempObject instanceof byte[]) { byte[] temp = (byte[]) tempObject; - for (int i = 0; i < depth; i++) { - stringBuilder.append("\t"); - } + stringBuilder.append("\t".repeat(Math.max(0, depth))); stringBuilder.append(field.getName()); stringBuilder.append(": "); stringBuilder.append(ArrayConverter.bytesToHexString(temp)); stringBuilder.append("\n"); } if (tempObject instanceof ModifiableVariableHolder) { - for (int i = 0; i < depth; i++) { - stringBuilder.append("\t"); - } + stringBuilder.append("\t".repeat(Math.max(0, depth))); stringBuilder.append(field.getName()); stringBuilder.append(":"); stringBuilder.append(tempObject.getClass().getSimpleName()); stringBuilder.append("{\n"); stringBuilder.append( ((ModifiableVariableHolder) tempObject).getExtendedString(depth + 1)); - for (int i = 0; i < depth; i++) { - stringBuilder.append("\t"); - } + stringBuilder.append("\t".repeat(Math.max(0, depth))); stringBuilder.append("}\n"); } else { - for (int i = 0; i < depth; i++) { - stringBuilder.append("\t"); - } + stringBuilder.append("\t".repeat(Math.max(0, depth))); stringBuilder.append(field.getName()); stringBuilder.append(": "); - stringBuilder.append(tempObject.toString()); + stringBuilder.append(tempObject); stringBuilder.append("\n"); } } else { - for (int i = 0; i < depth; i++) { - stringBuilder.append("\t"); - } + stringBuilder.append("\t".repeat(Math.max(0, depth))); stringBuilder.append(field.getName()); stringBuilder.append(": null\n"); } diff --git a/src/main/java/de/rub/nds/modifiablevariable/ModifiableVariableProperty.java b/src/main/java/de/rub/nds/modifiablevariable/ModifiableVariableProperty.java index e80a3d64..affcc4db 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/ModifiableVariableProperty.java +++ b/src/main/java/de/rub/nds/modifiablevariable/ModifiableVariableProperty.java @@ -17,7 +17,7 @@ @Retention(RetentionPolicy.RUNTIME) public @interface ModifiableVariableProperty { - public enum Type { + enum Type { LENGTH, COUNT, PADDING, @@ -38,7 +38,7 @@ public enum Type { BEHAVIOR_SWITCH } - public enum Format { + enum Format { ASN1, PKCS1, NONE diff --git a/src/main/java/de/rub/nds/modifiablevariable/ModificationFilter.java b/src/main/java/de/rub/nds/modifiablevariable/ModificationFilter.java index f7967f1b..24816427 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/ModificationFilter.java +++ b/src/main/java/de/rub/nds/modifiablevariable/ModificationFilter.java @@ -15,8 +15,18 @@ * data. For example, only the first data access returns a modified value. This can be achieved * using a ModificationFilter object. */ -@XmlSeeAlso({AccessModificationFilter.class}) +@XmlSeeAlso(AccessModificationFilter.class) public abstract class ModificationFilter { + protected ModificationFilter() { + super(); + } + + protected ModificationFilter(ModificationFilter other) { + super(); + } + + public abstract ModificationFilter createCopy(); + public abstract boolean filterModification(); } diff --git a/src/main/java/de/rub/nds/modifiablevariable/VariableModification.java b/src/main/java/de/rub/nds/modifiablevariable/VariableModification.java index 04e81ef2..be4396b4 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/VariableModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/VariableModification.java @@ -32,16 +32,24 @@ public abstract class VariableModification { * ModificationFilter is responsible for validating if the modification can be executed. */ @XmlElements( - value = { - @XmlElement( - type = AccessModificationFilter.class, - name = "AccessModificationFilter") - }) - private ModificationFilter modificationFilter = null; + @XmlElement(type = AccessModificationFilter.class, name = "AccessModificationFilter")) + private ModificationFilter modificationFilter; + + protected VariableModification() { + super(); + } + + protected VariableModification(VariableModification other) { + super(); + modificationFilter = + other.modificationFilter != null ? other.modificationFilter.createCopy() : null; + } + + public abstract VariableModification createCopy(); public E modify(E input) { E modifiedValue = modifyImplementationHook(input); - if ((modificationFilter == null) || (modificationFilter.filterModification() == false)) { + if (modificationFilter == null || !modificationFilter.filterModification()) { debug(modifiedValue); return modifiedValue; } else { @@ -54,7 +62,7 @@ public E modify(E input) { public abstract VariableModification getModifiedCopy(); /** - * Debugging modified variables. Getting stack trace can be time consuming, thus we use + * Debugging modified variables. Getting stack trace can be time-consuming, thus we use * isDebugEnabled() function * * @param value variable modification that is going to be debugged @@ -78,7 +86,7 @@ protected void debug(E value) { } LOGGER.debug( "Using {} in function:\n {}\n New value: {}", - this.getClass().getSimpleName(), + getClass().getSimpleName(), stack[index], valueString); } diff --git a/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerAddModification.java b/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerAddModification.java index 012555ca..8e5e44d2 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerAddModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerAddModification.java @@ -25,15 +25,28 @@ public class BigIntegerAddModification extends VariableModification private BigInteger summand; - public BigIntegerAddModification() {} + public BigIntegerAddModification() { + super(); + } + + public BigIntegerAddModification(BigInteger summand) { + super(); + this.summand = summand; + } + + public BigIntegerAddModification(BigIntegerAddModification other) { + super(other); + summand = other.summand; + } - public BigIntegerAddModification(BigInteger bi) { - this.summand = bi; + @Override + public BigIntegerAddModification createCopy() { + return new BigIntegerAddModification(this); } @Override protected BigInteger modifyImplementationHook(BigInteger input) { - return (input == null) ? summand : input.add(summand); + return input == null ? summand : input.add(summand); } public BigInteger getSummand() { @@ -53,7 +66,7 @@ public VariableModification getModifiedCopy() { @Override public int hashCode() { int hash = 7; - hash = 41 * hash + Objects.hashCode(this.summand); + hash = 31 * hash + summand.hashCode(); return hash; } @@ -68,10 +81,12 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final BigIntegerAddModification other = (BigIntegerAddModification) obj; - if (!Objects.equals(this.summand, other.summand)) { - return false; - } - return true; + BigIntegerAddModification other = (BigIntegerAddModification) obj; + return Objects.equals(summand, other.summand); + } + + @Override + public String toString() { + return "BigIntegerAddModification{" + "summand=" + summand + '}'; } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerAppendValueModification.java b/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerAppendValueModification.java new file mode 100644 index 00000000..0e7b70eb --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerAppendValueModification.java @@ -0,0 +1,95 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.biginteger; + +import de.rub.nds.modifiablevariable.VariableModification; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import java.math.BigInteger; +import java.util.Objects; +import java.util.Random; + +@XmlRootElement +@XmlType(propOrder = {"appendValue", "modificationFilter"}) +@XmlAccessorType(XmlAccessType.FIELD) +public class BigIntegerAppendValueModification extends VariableModification { + + private static final int MAX_APPEND_LENGTH = 8; + + private BigInteger appendValue; + + public BigIntegerAppendValueModification() { + super(); + } + + public BigIntegerAppendValueModification(BigInteger appendValue) { + super(); + this.appendValue = appendValue; + } + + public BigIntegerAppendValueModification(BigIntegerAppendValueModification other) { + super(other); + appendValue = other.appendValue; + } + + @Override + public BigIntegerAppendValueModification createCopy() { + return new BigIntegerAppendValueModification(this); + } + + @Override + protected BigInteger modifyImplementationHook(BigInteger input) { + if (input == null) { + input = BigInteger.ZERO; + } + return input.shiftLeft(appendValue.bitLength()).or(appendValue); + } + + public BigInteger getAppendValue() { + return appendValue; + } + + public void setAppendValue(BigInteger appendValue) { + this.appendValue = appendValue; + } + + @Override + public VariableModification getModifiedCopy() { + return new BigIntegerAppendValueModification( + appendValue.add(new BigInteger(MAX_APPEND_LENGTH, new Random()))); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + appendValue.hashCode(); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + BigIntegerAppendValueModification other = (BigIntegerAppendValueModification) obj; + return Objects.equals(appendValue, other.appendValue); + } + + @Override + public String toString() { + return "BigIntegerAppendValueModification{" + "appendValue=" + appendValue + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerExplicitValueFromFileModification.java b/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerExplicitValueFromFileModification.java new file mode 100644 index 00000000..3cfe18b1 --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerExplicitValueFromFileModification.java @@ -0,0 +1,91 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.biginteger; + +import de.rub.nds.modifiablevariable.VariableModification; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import java.math.BigInteger; +import java.util.Objects; + +@XmlRootElement +@XmlType(propOrder = "index") +@XmlAccessorType(XmlAccessType.FIELD) +public class BigIntegerExplicitValueFromFileModification + extends BigIntegerExplicitValueModification { + private int index; + + public BigIntegerExplicitValueFromFileModification() { + super(); + } + + public BigIntegerExplicitValueFromFileModification(int index, BigInteger explicitValue) { + super(explicitValue); + this.index = index; + } + + public BigIntegerExplicitValueFromFileModification( + BigIntegerExplicitValueFromFileModification other) { + super(other); + index = other.index; + } + + @Override + public BigIntegerExplicitValueFromFileModification createCopy() { + return new BigIntegerExplicitValueFromFileModification(this); + } + + public int getIndex() { + return index; + } + + @Override + public VariableModification getModifiedCopy() { + throw new UnsupportedOperationException( + "Cannot set modify Value of BigIntegerExplicitValueFromFileModification"); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + index; + hash = 31 * hash + explicitValue.hashCode(); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + BigIntegerExplicitValueFromFileModification other = + (BigIntegerExplicitValueFromFileModification) obj; + if (index != other.index) { + return false; + } + return Objects.equals(explicitValue, other.explicitValue); + } + + @Override + public String toString() { + return "BigIntegerExplicitValueFromFileModification{" + + "index=" + + index + + ", explicitValue=" + + explicitValue + + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerExplicitValueModification.java b/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerExplicitValueModification.java index 8f59ad9d..3150a89b 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerExplicitValueModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerExplicitValueModification.java @@ -23,16 +23,29 @@ public class BigIntegerExplicitValueModification extends VariableModification getModifiedCopy() { @Override public int hashCode() { - int hash = 3; - hash = 41 * hash + Objects.hashCode(this.explicitValue); + int hash = 7; + hash = 31 * hash + explicitValue.hashCode(); return hash; } @@ -74,10 +87,12 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final BigIntegerExplicitValueModification other = (BigIntegerExplicitValueModification) obj; - if (!Objects.equals(this.explicitValue, other.explicitValue)) { - return false; - } - return true; + BigIntegerExplicitValueModification other = (BigIntegerExplicitValueModification) obj; + return Objects.equals(explicitValue, other.explicitValue); + } + + @Override + public String toString() { + return "BigIntegerExplicitValueModification{" + "explicitValue=" + explicitValue + '}'; } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerInsertValueModification.java b/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerInsertValueModification.java new file mode 100644 index 00000000..007f9f12 --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerInsertValueModification.java @@ -0,0 +1,146 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.biginteger; + +import de.rub.nds.modifiablevariable.VariableModification; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import java.math.BigInteger; +import java.util.Objects; +import java.util.Random; + +@XmlRootElement +@XmlType(propOrder = {"insertValue", "startPosition", "modificationFilter"}) +@XmlAccessorType(XmlAccessType.FIELD) +public class BigIntegerInsertValueModification extends VariableModification { + + private static final int MAX_INSERT_LENGTH = 8; + private static final int MAX_POSITION_MODIFIER = 32; + + private BigInteger insertValue; + private int startPosition; + + public BigIntegerInsertValueModification() { + super(); + } + + public BigIntegerInsertValueModification(BigInteger insertValue, int startPosition) { + super(); + this.insertValue = insertValue; + this.startPosition = startPosition; + } + + public BigIntegerInsertValueModification(BigIntegerInsertValueModification other) { + super(other); + insertValue = other.insertValue; + startPosition = other.startPosition; + } + + @Override + public BigIntegerInsertValueModification createCopy() { + return new BigIntegerInsertValueModification(this); + } + + @Override + protected BigInteger modifyImplementationHook(BigInteger input) { + if (input == null) { + input = BigInteger.ZERO; + } + + int originalValueLength = input.bitLength(); + int insertValueLength = insertValue.bitLength(); + + // Wrap around and also allow to insert at the end of the original value + int insertPosition = startPosition % (originalValueLength + 1); + if (startPosition < 0) { + insertPosition += originalValueLength; + } + + BigInteger mask = BigInteger.valueOf((1L << insertPosition) - 1); + + return input.shiftRight(insertPosition) + .shiftLeft(insertValueLength) + .or(insertValue) + .shiftLeft(insertPosition) + .or(mask.and(input)); + } + + public BigInteger getInsertValue() { + return insertValue; + } + + public void setInsertValue(BigInteger insertValue) { + this.insertValue = insertValue; + } + + public int getStartPosition() { + return startPosition; + } + + public void setStartPosition(int startPosition) { + this.startPosition = startPosition; + } + + @Override + public VariableModification getModifiedCopy() { + Random r = new Random(); + + if (r.nextBoolean()) { + return new BigIntegerInsertValueModification( + insertValue.add(new BigInteger(MAX_INSERT_LENGTH, r)), startPosition); + } else { + int modifier = r.nextInt(MAX_POSITION_MODIFIER); + if (r.nextBoolean()) { + modifier *= -1; + } + modifier = startPosition + modifier; + if (modifier <= 0) { + modifier = 1; + } + return new BigIntegerInsertValueModification(insertValue, modifier); + } + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + insertValue.hashCode(); + hash = 31 * hash + startPosition; + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + BigIntegerInsertValueModification other = (BigIntegerInsertValueModification) obj; + if (startPosition != other.startPosition) { + return false; + } + return Objects.equals(insertValue, other.insertValue); + } + + @Override + public String toString() { + return "BigIntegerInsertValueModification{" + + "insertValue=" + + insertValue + + ", startPosition=" + + startPosition + + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerInteractiveModification.java b/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerInteractiveModification.java index 0ec3fa18..61162991 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerInteractiveModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerInteractiveModification.java @@ -16,23 +16,25 @@ import java.math.BigInteger; @XmlRootElement -@XmlType(propOrder = {"modificationFilter"}) +@XmlType(propOrder = "modificationFilter") @XmlAccessorType(XmlAccessType.FIELD) public class BigIntegerInteractiveModification extends VariableModification { - @XmlTransient private InteractiveBigIntegerModification modification; + @XmlTransient private final InteractiveBigIntegerModification modification; protected BigIntegerInteractiveModification() { - this.modification = BigIntegerModificationFactory.getStandardInteractiveModification(); + super(); + modification = BigIntegerModificationFactory.getStandardInteractiveModification(); } protected BigIntegerInteractiveModification(InteractiveBigIntegerModification modification) { + super(); this.modification = modification; } @Override - protected BigInteger modifyImplementationHook(final BigInteger input) { - return this.modification.modify(input); + protected BigInteger modifyImplementationHook(BigInteger input) { + return modification.modify(input); } public interface InteractiveBigIntegerModification { @@ -45,4 +47,10 @@ public VariableModification getModifiedCopy() { throw new UnsupportedOperationException( "This method is not supported for interactive modifications"); } + + @Override + public VariableModification createCopy() { + throw new UnsupportedOperationException( + "This method is not supported for interactive modifications"); + } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerModificationFactory.java b/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerModificationFactory.java index abb2c80e..57e3ba7a 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerModificationFactory.java +++ b/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerModificationFactory.java @@ -10,84 +10,115 @@ import de.rub.nds.modifiablevariable.FileConfigurationException; import de.rub.nds.modifiablevariable.VariableModification; import de.rub.nds.modifiablevariable.bytearray.ByteArrayModificationFactory; -import de.rub.nds.modifiablevariable.integer.IntegerModificationFactory; +import de.rub.nds.modifiablevariable.longint.LongModificationFactory; import de.rub.nds.modifiablevariable.util.RandomHelper; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.math.BigInteger; -import java.util.LinkedList; -import java.util.List; -import java.util.Random; -import java.util.Scanner; +import java.util.*; -public class BigIntegerModificationFactory { +public final class BigIntegerModificationFactory { - private static final int MODIFICATION_COUNT = 7; + private enum ModificationType { + ADD, + SUBTRACT, + MULTIPLY, + XOR, + EXPLICIT, + SHIFT_LEFT, + SHIFT_RIGHT, + EXPLICIT_FROM_FILE, + APPEND, + INSERT, + PREPEND + } + + private static final int MODIFICATION_COUNT = ModificationType.values().length; private static final int MAX_MODIFICATION_VALUE = 320000; + private static final int MAX_FILE_ENTRIES = 200; + private static final int MAX_MODIFICATION_SHIFT_VALUE = 50; + private static final int MAX_MODIFICATION_MULTIPLY_VALUE = 256; + + private static final int MAX_MODIFICATION_INSERT_VALUE = 256; + + private static final int MAX_MODIFICATION_INSERT_POSITION_VALUE = 50; + private static List> modificationsFromFile; - public static BigIntegerAddModification add(final String summand) { + public static BigIntegerAddModification add(String summand) { return add(new BigInteger(summand)); } - public static BigIntegerAddModification add(final BigInteger summand) { + public static BigIntegerAddModification add(BigInteger summand) { return new BigIntegerAddModification(summand); } - public static BigIntegerShiftLeftModification shiftLeft(final String shift) { + public static BigIntegerShiftLeftModification shiftLeft(String shift) { return shiftLeft(Integer.parseInt(shift)); } - public static BigIntegerShiftLeftModification shiftLeft(final Integer shift) { + public static BigIntegerShiftLeftModification shiftLeft(Integer shift) { return new BigIntegerShiftLeftModification(shift); } - public static BigIntegerShiftRightModification shiftRight(final String shift) { + public static BigIntegerShiftRightModification shiftRight(String shift) { return shiftRight(Integer.parseInt(shift)); } - public static BigIntegerShiftRightModification shiftRight(final Integer shift) { + public static BigIntegerShiftRightModification shiftRight(Integer shift) { return new BigIntegerShiftRightModification(shift); } - public static BigIntegerMultiplyModification multiply(final BigInteger factor) { + public static BigIntegerMultiplyModification multiply(BigInteger factor) { return new BigIntegerMultiplyModification(factor); } - public static VariableModification sub(final String subtrahend) { + public static VariableModification sub(String subtrahend) { return sub(new BigInteger(subtrahend)); } - public static VariableModification sub(final BigInteger subtrahend) { + public static VariableModification sub(BigInteger subtrahend) { return new BigIntegerSubtractModification(subtrahend); } - public static VariableModification xor(final String xor) { + public static VariableModification xor(String xor) { return xor(new BigInteger(xor)); } - public static VariableModification xor(final BigInteger xor) { + public static VariableModification xor(BigInteger xor) { return new BigIntegerXorModification(xor); } - public static VariableModification explicitValue(final String value) { + public static VariableModification explicitValue(String value) { return explicitValue(new BigInteger(value)); } - public static VariableModification explicitValue(final BigInteger value) { + public static VariableModification explicitValue(BigInteger value) { return new BigIntegerExplicitValueModification(value); } - public static VariableModification explicitValueFromFile(int value) { + public static VariableModification explicitValueFromFile(int pos) { List> modifications = modificationsFromFile(); - int pos = value % modifications.size(); - return modifications.get(pos); + return modifications.get(pos % modifications.size()); + } + + public static VariableModification appendValue(BigInteger value) { + return new BigIntegerAppendValueModification(value); + } + + public static VariableModification insertValue( + BigInteger value, int startPosition) { + return new BigIntegerInsertValueModification(value, startPosition); + } + + public static VariableModification prependValue(BigInteger value) { + return new BigIntegerPrependValueModification(value); } /* @@ -102,11 +133,8 @@ public static VariableModification explicitValueFromFile(int value) public BigInteger modify(BigInteger oldVal) { if (value == null) { System.out.println("Enter new value for BigInt: "); - Scanner scanner = new Scanner(System.in); - try { + try (Scanner scanner = new Scanner(System.in)) { value = scanner.nextBigInteger(); - } finally { - scanner.close(); } } return value; @@ -118,7 +146,7 @@ public static void setStandardInteractiveModification( standardInteractiveModification = modification; } - protected static BigIntegerInteractiveModification.InteractiveBigIntegerModification + static BigIntegerInteractiveModification.InteractiveBigIntegerModification getStandardInteractiveModification() { return standardInteractiveModification; } @@ -130,16 +158,19 @@ public static VariableModification interactive() { public static synchronized List> modificationsFromFile() { try { if (modificationsFromFile == null) { - modificationsFromFile = new LinkedList<>(); + modificationsFromFile = new ArrayList<>(); ClassLoader classLoader = ByteArrayModificationFactory.class.getClassLoader(); - InputStream is = - classLoader.getResourceAsStream(IntegerModificationFactory.FILE_NAME); + InputStream is = classLoader.getResourceAsStream(LongModificationFactory.FILE_NAME); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String line; + int index = 0; while ((line = br.readLine()) != null) { String value = line.trim().split(" ")[0]; - if (!value.equals("")) { - modificationsFromFile.add(explicitValue(value)); + if (!value.isEmpty()) { + modificationsFromFile.add( + new BigIntegerExplicitValueFromFileModification( + index, new BigInteger(value))); + index++; } } } @@ -152,37 +183,43 @@ public static synchronized List> modificationsF public static VariableModification createRandomModification() { Random random = RandomHelper.getRandom(); - int r = random.nextInt(MODIFICATION_COUNT); + ModificationType randomType = ModificationType.values()[random.nextInt(MODIFICATION_COUNT)]; BigInteger modification = BigInteger.valueOf(random.nextInt(MAX_MODIFICATION_VALUE)); + BigInteger insert_modification = + BigInteger.valueOf(random.nextInt(MAX_MODIFICATION_INSERT_VALUE)); int shiftModification = random.nextInt(MAX_MODIFICATION_SHIFT_VALUE); - VariableModification vm = null; - switch (r) { - case 0: - vm = new BigIntegerAddModification(modification); - return vm; - case 1: - vm = new BigIntegerSubtractModification(modification); - return vm; - case 2: - vm = new BigIntegerXorModification(modification); - return vm; - case 3: - vm = new BigIntegerExplicitValueModification(modification); - return vm; - case 4: - vm = new BigIntegerShiftLeftModification(shiftModification); - return vm; - case 5: - vm = new BigIntegerShiftRightModification(shiftModification); - return vm; - case 6: - vm = explicitValueFromFile(MAX_MODIFICATION_VALUE); - return vm; - default: // unreachable but included for checkstyle - vm = explicitValueFromFile(MAX_MODIFICATION_VALUE); - return vm; + switch (randomType) { + case ADD: + return new BigIntegerAddModification(modification); + case SUBTRACT: + return new BigIntegerSubtractModification(modification); + case MULTIPLY: + return new BigIntegerMultiplyModification( + BigInteger.valueOf(random.nextInt(MAX_MODIFICATION_MULTIPLY_VALUE))); + case XOR: + return new BigIntegerXorModification(modification); + case EXPLICIT: + return new BigIntegerExplicitValueModification(modification); + case SHIFT_LEFT: + return new BigIntegerShiftLeftModification(shiftModification); + case SHIFT_RIGHT: + return new BigIntegerShiftRightModification(shiftModification); + case EXPLICIT_FROM_FILE: + return explicitValueFromFile(MAX_FILE_ENTRIES); + case APPEND: + return new BigIntegerAppendValueModification(insert_modification); + case INSERT: + return new BigIntegerInsertValueModification( + insert_modification, + random.nextInt(MAX_MODIFICATION_INSERT_POSITION_VALUE)); + case PREPEND: + return new BigIntegerPrependValueModification(insert_modification); + default: + throw new IllegalStateException("Unexpected modification type: " + randomType); } } - private BigIntegerModificationFactory() {} + private BigIntegerModificationFactory() { + super(); + } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerMultiplyModification.java b/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerMultiplyModification.java index 3faeb0c6..93a732e5 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerMultiplyModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerMultiplyModification.java @@ -25,18 +25,28 @@ public class BigIntegerMultiplyModification extends VariableModification getModifiedCopy() { @Override public int hashCode() { - int hash = 5; - hash = 61 * hash + Objects.hashCode(this.factor); + int hash = 7; + hash = 31 * hash + factor.hashCode(); return hash; } @@ -71,10 +81,12 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final BigIntegerMultiplyModification other = (BigIntegerMultiplyModification) obj; - if (!Objects.equals(this.factor, other.factor)) { - return false; - } - return true; + BigIntegerMultiplyModification other = (BigIntegerMultiplyModification) obj; + return Objects.equals(factor, other.factor); + } + + @Override + public String toString() { + return "BigIntegerMultiplyModification{" + "factor=" + factor + '}'; } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerPrependValueModification.java b/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerPrependValueModification.java new file mode 100644 index 00000000..d9e2fe1a --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerPrependValueModification.java @@ -0,0 +1,95 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.biginteger; + +import de.rub.nds.modifiablevariable.VariableModification; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import java.math.BigInteger; +import java.util.Objects; +import java.util.Random; + +@XmlRootElement +@XmlType(propOrder = {"prependValue", "modificationFilter"}) +@XmlAccessorType(XmlAccessType.FIELD) +public class BigIntegerPrependValueModification extends VariableModification { + + private static final int MAX_PREPEND_LENGTH = 8; + + private BigInteger prependValue; + + public BigIntegerPrependValueModification() { + super(); + } + + public BigIntegerPrependValueModification(BigInteger prependValue) { + super(); + this.prependValue = prependValue; + } + + public BigIntegerPrependValueModification(BigIntegerPrependValueModification other) { + super(other); + prependValue = other.prependValue; + } + + @Override + public BigIntegerPrependValueModification createCopy() { + return new BigIntegerPrependValueModification(this); + } + + @Override + protected BigInteger modifyImplementationHook(BigInteger input) { + if (input == null) { + input = BigInteger.ZERO; + } + return prependValue.shiftLeft(input.bitLength()).or(input); + } + + public BigInteger getPrependValue() { + return prependValue; + } + + public void setPrependValue(BigInteger prependValue) { + this.prependValue = prependValue; + } + + @Override + public VariableModification getModifiedCopy() { + return new BigIntegerPrependValueModification( + prependValue.add(new BigInteger(MAX_PREPEND_LENGTH, new Random()))); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + prependValue.hashCode(); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + BigIntegerPrependValueModification other = (BigIntegerPrependValueModification) obj; + return Objects.equals(prependValue, other.prependValue); + } + + @Override + public String toString() { + return "BigIntegerPrependValueModification{" + "prependValue=" + prependValue + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerShiftLeftModification.java b/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerShiftLeftModification.java index f07cddd7..77a9295f 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerShiftLeftModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerShiftLeftModification.java @@ -24,12 +24,25 @@ public class BigIntegerShiftLeftModification extends VariableModification getModifiedCopy() { @Override public int hashCode() { int hash = 7; - hash = 97 * hash + this.shift; + hash = 31 * hash + shift; return hash; } @@ -69,10 +82,12 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final BigIntegerShiftLeftModification other = (BigIntegerShiftLeftModification) obj; - if (this.shift != other.shift) { - return false; - } - return true; + BigIntegerShiftLeftModification other = (BigIntegerShiftLeftModification) obj; + return shift == other.shift; + } + + @Override + public String toString() { + return "BigIntegerShiftLeftModification{" + "shift=" + shift + '}'; } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerShiftRightModification.java b/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerShiftRightModification.java index 78443aa5..0d142373 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerShiftRightModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerShiftRightModification.java @@ -24,12 +24,25 @@ public class BigIntegerShiftRightModification extends VariableModification getModifiedCopy() { @Override public int hashCode() { int hash = 7; - hash = 97 * hash + this.shift; + hash = 31 * hash + shift; return hash; } @@ -69,10 +82,12 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final BigIntegerShiftRightModification other = (BigIntegerShiftRightModification) obj; - if (this.shift != other.shift) { - return false; - } - return true; + BigIntegerShiftRightModification other = (BigIntegerShiftRightModification) obj; + return shift == other.shift; + } + + @Override + public String toString() { + return "BigIntegerShiftRightModification{" + "shift=" + shift + '}'; } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerSubtractModification.java b/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerSubtractModification.java index 11fa6703..f07e4fb0 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerSubtractModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerSubtractModification.java @@ -25,10 +25,23 @@ public class BigIntegerSubtractModification extends VariableModification getModifiedCopy() { @Override public int hashCode() { - int hash = 5; - hash = 61 * hash + Objects.hashCode(this.subtrahend); + int hash = 7; + hash = 31 * hash + subtrahend.hashCode(); return hash; } @@ -71,10 +84,12 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final BigIntegerSubtractModification other = (BigIntegerSubtractModification) obj; - if (!Objects.equals(this.subtrahend, other.subtrahend)) { - return false; - } - return true; + BigIntegerSubtractModification other = (BigIntegerSubtractModification) obj; + return Objects.equals(subtrahend, other.subtrahend); + } + + @Override + public String toString() { + return "BigIntegerSubtractModification{" + "subtrahend=" + subtrahend + '}'; } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerXorModification.java b/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerXorModification.java index 064f6f85..c3d67759 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerXorModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerXorModification.java @@ -25,10 +25,23 @@ public class BigIntegerXorModification extends VariableModification private BigInteger xor; - public BigIntegerXorModification() {} + public BigIntegerXorModification() { + super(); + } + + public BigIntegerXorModification(BigInteger xor) { + super(); + this.xor = xor; + } + + public BigIntegerXorModification(BigIntegerXorModification other) { + super(other); + xor = other.xor; + } - public BigIntegerXorModification(BigInteger bi) { - this.xor = bi; + @Override + public BigIntegerXorModification createCopy() { + return new BigIntegerXorModification(this); } @Override @@ -55,7 +68,7 @@ public VariableModification getModifiedCopy() { @Override public int hashCode() { int hash = 7; - hash = 97 * hash + Objects.hashCode(this.xor); + hash = 31 * hash + xor.hashCode(); return hash; } @@ -70,10 +83,12 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final BigIntegerXorModification other = (BigIntegerXorModification) obj; - if (!Objects.equals(this.xor, other.xor)) { - return false; - } - return true; + BigIntegerXorModification other = (BigIntegerXorModification) obj; + return Objects.equals(xor, other.xor); + } + + @Override + public String toString() { + return "BigIntegerXorModification{" + "xor=" + xor + '}'; } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/biginteger/ModifiableBigInteger.java b/src/main/java/de/rub/nds/modifiablevariable/biginteger/ModifiableBigInteger.java index c9ab1e89..0788cdcf 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/biginteger/ModifiableBigInteger.java +++ b/src/main/java/de/rub/nds/modifiablevariable/biginteger/ModifiableBigInteger.java @@ -21,8 +21,27 @@ public class ModifiableBigInteger extends ModifiableVariable { private BigInteger originalValue; + public ModifiableBigInteger() { + super(); + } + + public ModifiableBigInteger(BigInteger originalValue) { + super(); + this.originalValue = originalValue; + } + + public ModifiableBigInteger(ModifiableBigInteger other) { + super(other); + originalValue = other.originalValue; + } + + @Override + public ModifiableBigInteger createCopy() { + return new ModifiableBigInteger(this); + } + @Override - protected void createRandomModification() { + public void setRandomModification() { VariableModification vm = BigIntegerModificationFactory.createRandomModification(); setModification(vm); @@ -38,7 +57,7 @@ public void setAssertEquals(BigInteger assertEquals) { @Override public boolean isOriginalValueModified() { - return getOriginalValue() != null && (getOriginalValue().compareTo(getValue()) != 0); + return originalValue != null && originalValue.compareTo(getValue()) != 0; } public byte[] getByteArray() { @@ -52,9 +71,7 @@ public byte[] getByteArray(int size) { @Override public boolean validateAssertions() { if (assertEquals != null) { - if (assertEquals.compareTo(getValue()) != 0) { - return false; - } + return assertEquals.compareTo(getValue()) == 0; } return true; } @@ -71,19 +88,19 @@ public void setOriginalValue(BigInteger originalValue) { @Override public String toString() { - return "ModifiableBigInteger{" + "originalValue=" + originalValue + '}'; + return "ModifiableBigInteger{" + "originalValue=" + originalValue + innerToString() + '}'; } @Override - public boolean equals(Object o) { - if (this == o) { + public boolean equals(Object obj) { + if (this == obj) { return true; } - if (!(o instanceof ModifiableBigInteger)) { + if (!(obj instanceof ModifiableBigInteger)) { return false; } - ModifiableBigInteger that = (ModifiableBigInteger) o; + ModifiableBigInteger that = (ModifiableBigInteger) obj; return getValue() != null ? getValue().equals(that.getValue()) : that.getValue() == null; } diff --git a/src/main/java/de/rub/nds/modifiablevariable/bool/BooleanExplicitValueModification.java b/src/main/java/de/rub/nds/modifiablevariable/bool/BooleanExplicitValueModification.java index d253c44e..123d95f4 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/bool/BooleanExplicitValueModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/bool/BooleanExplicitValueModification.java @@ -17,14 +17,27 @@ public class BooleanExplicitValueModification extends VariableModification getModifiedCopy() { @Override public int hashCode() { int hash = 7; - hash = 29 * hash + (this.explicitValue ? 1 : 0); + hash = 31 * hash + (explicitValue ? 1231 : 1237); return hash; } @@ -59,11 +72,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final BooleanExplicitValueModification other = (BooleanExplicitValueModification) obj; - if (this.explicitValue != other.explicitValue) { - return false; - } - return true; + BooleanExplicitValueModification other = (BooleanExplicitValueModification) obj; + return explicitValue == other.explicitValue; } @Override diff --git a/src/main/java/de/rub/nds/modifiablevariable/bool/BooleanModificationFactory.java b/src/main/java/de/rub/nds/modifiablevariable/bool/BooleanModificationFactory.java index 0a3c2a9e..653d6ddb 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/bool/BooleanModificationFactory.java +++ b/src/main/java/de/rub/nds/modifiablevariable/bool/BooleanModificationFactory.java @@ -11,21 +11,32 @@ import de.rub.nds.modifiablevariable.util.RandomHelper; import java.util.Random; -public class BooleanModificationFactory { +public final class BooleanModificationFactory { - private static final int MODIFICATION_COUNT = 3; + private BooleanModificationFactory() { + super(); + } + + private enum ModificationType { + EXPLICIT_TRUE, + EXPLICIT_FALSE, + TOGGLE + } + + private static final int MODIFICATION_COUNT = ModificationType.values().length; public static VariableModification createRandomModification() { Random random = RandomHelper.getRandom(); - switch (random.nextInt(MODIFICATION_COUNT)) { - case 0: + ModificationType randomType = ModificationType.values()[random.nextInt(MODIFICATION_COUNT)]; + switch (randomType) { + case EXPLICIT_TRUE: return new BooleanExplicitValueModification(true); - case 1: + case EXPLICIT_FALSE: return new BooleanExplicitValueModification(false); - case 2: + case TOGGLE: return new BooleanToggleModification(); default: - return null; + throw new IllegalStateException("Unexpected modification type: " + randomType); } } @@ -33,7 +44,7 @@ public static VariableModification toggle() { return new BooleanToggleModification(); } - public static VariableModification explicitValue(final boolean explicitValue) { + public static VariableModification explicitValue(boolean explicitValue) { return new BooleanExplicitValueModification(explicitValue); } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/bool/BooleanToggleModification.java b/src/main/java/de/rub/nds/modifiablevariable/bool/BooleanToggleModification.java index aee21384..34ad7608 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/bool/BooleanToggleModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/bool/BooleanToggleModification.java @@ -12,10 +12,21 @@ import jakarta.xml.bind.annotation.XmlType; @XmlRootElement -@XmlType(propOrder = {"modificationFilter"}) +@XmlType(propOrder = "modificationFilter") public class BooleanToggleModification extends VariableModification { - public BooleanToggleModification() {} + public BooleanToggleModification() { + super(); + } + + public BooleanToggleModification(BooleanToggleModification other) { + super(other); + } + + @Override + public BooleanToggleModification createCopy() { + return new BooleanToggleModification(this); + } @Override protected Boolean modifyImplementationHook(Boolean input) { @@ -32,8 +43,7 @@ public VariableModification getModifiedCopy() { @Override public int hashCode() { - int hash = 7; - return hash; + return 7; } @Override @@ -44,10 +54,7 @@ public boolean equals(Object obj) { if (obj == null) { return false; } - if (getClass() != obj.getClass()) { - return false; - } - return true; + return getClass() == obj.getClass(); } @Override diff --git a/src/main/java/de/rub/nds/modifiablevariable/bool/ModifiableBoolean.java b/src/main/java/de/rub/nds/modifiablevariable/bool/ModifiableBoolean.java index 9dc3fc21..b6c2e97c 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/bool/ModifiableBoolean.java +++ b/src/main/java/de/rub/nds/modifiablevariable/bool/ModifiableBoolean.java @@ -19,12 +19,25 @@ public class ModifiableBoolean extends ModifiableVariable { private Boolean originalValue; - public ModifiableBoolean() {} + public ModifiableBoolean() { + super(); + } public ModifiableBoolean(Boolean originalValue) { + super(); this.originalValue = originalValue; } + public ModifiableBoolean(ModifiableBoolean other) { + super(other); + originalValue = other.originalValue; + } + + @Override + public ModifiableBoolean createCopy() { + return new ModifiableBoolean(this); + } + @Override public Boolean getOriginalValue() { return originalValue; @@ -36,41 +49,39 @@ public void setOriginalValue(Boolean originalValue) { } @Override - protected void createRandomModification() { + public void setRandomModification() { VariableModification vm = BooleanModificationFactory.createRandomModification(); setModification(vm); } @Override public boolean isOriginalValueModified() { - return getOriginalValue() != null && (getOriginalValue().compareTo(getValue()) != 0); + return originalValue != null && originalValue.compareTo(getValue()) != 0; } @Override public boolean validateAssertions() { if (assertEquals != null) { - if (assertEquals.compareTo(getValue()) != 0) { - return false; - } + return assertEquals.compareTo(getValue()) == 0; } return true; } @Override public String toString() { - return "ModifiableBoolean{" + "originalValue=" + originalValue + '}'; + return "ModifiableBoolean{" + "originalValue=" + originalValue + innerToString() + '}'; } @Override - public boolean equals(Object o) { - if (this == o) { + public boolean equals(Object obj) { + if (this == obj) { return true; } - if (!(o instanceof ModifiableBoolean)) { + if (!(obj instanceof ModifiableBoolean)) { return false; } - ModifiableBoolean that = (ModifiableBoolean) o; + ModifiableBoolean that = (ModifiableBoolean) obj; return getValue() != null ? getValue().equals(that.getValue()) : that.getValue() == null; } diff --git a/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayAppendValueModification.java b/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayAppendValueModification.java new file mode 100644 index 00000000..78eb3d2e --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayAppendValueModification.java @@ -0,0 +1,105 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.bytearray; + +import de.rub.nds.modifiablevariable.VariableModification; +import de.rub.nds.modifiablevariable.util.ArrayConverter; +import de.rub.nds.modifiablevariable.util.UnformattedByteArrayAdapter; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import java.util.Arrays; +import java.util.Random; + +@XmlRootElement +@XmlType(propOrder = {"bytesToAppend", "modificationFilter"}) +@XmlAccessorType(XmlAccessType.FIELD) +public class ByteArrayAppendValueModification extends VariableModification { + + private static final int MAX_EXPLICIT_VALUE = 256; + + @XmlJavaTypeAdapter(UnformattedByteArrayAdapter.class) + private byte[] bytesToAppend; + + public ByteArrayAppendValueModification() { + super(); + } + + public ByteArrayAppendValueModification(byte[] bytesToAppend) { + super(); + this.bytesToAppend = bytesToAppend; + } + + public ByteArrayAppendValueModification(ByteArrayAppendValueModification other) { + super(other); + bytesToAppend = other.bytesToAppend != null ? other.bytesToAppend.clone() : null; + } + + @Override + public ByteArrayAppendValueModification createCopy() { + return new ByteArrayAppendValueModification(this); + } + + @Override + protected byte[] modifyImplementationHook(byte[] input) { + if (input == null) { + input = new byte[0]; + } + + return ArrayConverter.concatenate(input, bytesToAppend); + } + + public byte[] getBytesToAppend() { + return bytesToAppend; + } + + public void setBytesToAppend(byte[] bytesToAppend) { + this.bytesToAppend = bytesToAppend; + } + + @Override + public VariableModification getModifiedCopy() { + Random r = new Random(); + + int index = r.nextInt(bytesToAppend.length); + byte[] newValue = Arrays.copyOf(bytesToAppend, bytesToAppend.length); + newValue[index] = (byte) r.nextInt(MAX_EXPLICIT_VALUE); + return new ByteArrayAppendValueModification(newValue); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + Arrays.hashCode(bytesToAppend); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + ByteArrayAppendValueModification other = (ByteArrayAppendValueModification) obj; + return Arrays.equals(bytesToAppend, other.bytesToAppend); + } + + @Override + public String toString() { + return "ByteArrayInsertModification{bytesToAppend=" + + ArrayConverter.bytesToHexString(bytesToAppend) + + "}"; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayDeleteModification.java b/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayDeleteModification.java index c2e96dae..88b25d5f 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayDeleteModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayDeleteModification.java @@ -7,8 +7,6 @@ */ package de.rub.nds.modifiablevariable.bytearray; -import static de.rub.nds.modifiablevariable.util.ArrayConverter.bytesToHexString; - import de.rub.nds.modifiablevariable.VariableModification; import de.rub.nds.modifiablevariable.util.ArrayConverter; import jakarta.xml.bind.annotation.XmlAccessType; @@ -29,44 +27,52 @@ public class ByteArrayDeleteModification extends VariableModification { private int startPosition; - public ByteArrayDeleteModification() {} + public ByteArrayDeleteModification() { + super(); + } public ByteArrayDeleteModification(int startPosition, int count) { + super(); this.startPosition = startPosition; this.count = count; } + public ByteArrayDeleteModification(ByteArrayDeleteModification other) { + super(other); + count = other.count; + startPosition = other.startPosition; + } + + @Override + public ByteArrayDeleteModification createCopy() { + return new ByteArrayDeleteModification(this); + } + @Override protected byte[] modifyImplementationHook(byte[] input) { if (input == null) { input = new byte[0]; } - int start = startPosition; - if (start < 0) { - start += input.length; - if (start < 0) { - LOGGER.debug( - "Trying to delete from too negative Startposition. start = " - + (start - input.length)); - return input; - } - } - final int endPosition = start + count; - if ((endPosition) > input.length) { - LOGGER.debug( - String.format( - "Bytes %d..%d cannot be deleted from {%s} of length %d", - start, endPosition, bytesToHexString(input), input.length)); + if (input.length == 0) { return input; } - if (count <= 0) { - LOGGER.debug("You must delete at least one byte. count = " + count); - return input; + + // Wrap around and also allow to delete at the end of the original value + int deleteStartPosition = startPosition % input.length; + if (startPosition < 0) { + deleteStartPosition += input.length - 1; + } + + // If the end position overflows, it is fixed at the end of the byte array + int deleteEndPosition = deleteStartPosition + Math.max(0, count); + if (deleteEndPosition > input.length) { + deleteEndPosition = input.length; } - byte[] ret1 = Arrays.copyOf(input, start); + + byte[] ret1 = Arrays.copyOf(input, deleteStartPosition); byte[] ret2 = null; - if ((endPosition) < input.length) { - ret2 = Arrays.copyOfRange(input, endPosition, input.length); + if (deleteEndPosition < input.length) { + ret2 = Arrays.copyOfRange(input, deleteEndPosition, input.length); } return ArrayConverter.concatenate(ret1, ret2); } @@ -112,8 +118,8 @@ public VariableModification getModifiedCopy() { @Override public int hashCode() { int hash = 7; - hash = 89 * hash + this.count; - hash = 89 * hash + this.startPosition; + hash = 31 * hash + count; + hash = 31 * hash + startPosition; return hash; } @@ -128,14 +134,11 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final ByteArrayDeleteModification other = (ByteArrayDeleteModification) obj; - if (this.count != other.count) { - return false; - } - if (this.startPosition != other.startPosition) { + ByteArrayDeleteModification other = (ByteArrayDeleteModification) obj; + if (count != other.count) { return false; } - return true; + return startPosition == other.startPosition; } @Override diff --git a/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayDuplicateModification.java b/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayDuplicateModification.java index 697837d2..b919fccf 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayDuplicateModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayDuplicateModification.java @@ -15,11 +15,22 @@ import jakarta.xml.bind.annotation.XmlType; @XmlRootElement -@XmlType(propOrder = {"modificationFilter"}) +@XmlType(propOrder = "modificationFilter") @XmlAccessorType(XmlAccessType.FIELD) public class ByteArrayDuplicateModification extends VariableModification { - public ByteArrayDuplicateModification() {} + public ByteArrayDuplicateModification() { + super(); + } + + public ByteArrayDuplicateModification(ByteArrayDuplicateModification other) { + super(other); + } + + @Override + public ByteArrayDuplicateModification createCopy() { + return new ByteArrayDuplicateModification(this); + } @Override protected byte[] modifyImplementationHook(byte[] input) { @@ -36,8 +47,7 @@ public VariableModification getModifiedCopy() { @Override public int hashCode() { - int hash = 7; - return hash; + return 7; } @Override @@ -48,10 +58,7 @@ public boolean equals(Object obj) { if (obj == null) { return false; } - if (getClass() != obj.getClass()) { - return false; - } - return true; + return getClass() == obj.getClass(); } @Override diff --git a/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayExplicitValueFromFileModification.java b/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayExplicitValueFromFileModification.java new file mode 100644 index 00000000..f303e922 --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayExplicitValueFromFileModification.java @@ -0,0 +1,90 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.bytearray; + +import de.rub.nds.modifiablevariable.VariableModification; +import de.rub.nds.modifiablevariable.util.ArrayConverter; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import java.util.Arrays; + +@XmlRootElement +@XmlType(propOrder = "index") +@XmlAccessorType(XmlAccessType.FIELD) +public class ByteArrayExplicitValueFromFileModification extends ByteArrayExplicitValueModification { + private int index; + + public ByteArrayExplicitValueFromFileModification() { + super(); + } + + public ByteArrayExplicitValueFromFileModification(int index, byte[] explicitValue) { + super(explicitValue); + this.index = index; + } + + public ByteArrayExplicitValueFromFileModification( + ByteArrayExplicitValueFromFileModification other) { + super(other); + index = other.index; + } + + @Override + public ByteArrayExplicitValueFromFileModification createCopy() { + return new ByteArrayExplicitValueFromFileModification(this); + } + + public int getIndex() { + return index; + } + + @Override + public VariableModification getModifiedCopy() { + throw new UnsupportedOperationException( + "Cannot set modify Value of ByteArrayExplicitValueFromFileModification"); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + index; + hash = 31 * hash + Arrays.hashCode(explicitValue); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + ByteArrayExplicitValueFromFileModification other = + (ByteArrayExplicitValueFromFileModification) obj; + if (index != other.index) { + return false; + } + return Arrays.equals(explicitValue, other.explicitValue); + } + + @Override + public String toString() { + return "ByteArrayExplicitValueFromFileModification{" + + "index=" + + index + + ", explicitValue=" + + ArrayConverter.bytesToHexString(explicitValue) + + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayExplicitValueModification.java b/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayExplicitValueModification.java index 85c5d8e5..83fca1b1 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayExplicitValueModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayExplicitValueModification.java @@ -26,16 +26,29 @@ public class ByteArrayExplicitValueModification extends VariableModification getModifiedCopy() { @Override public int hashCode() { - int hash = 5; - hash = 53 * hash + Arrays.hashCode(this.explicitValue); + int hash = 7; + hash = 31 * hash + Arrays.hashCode(explicitValue); return hash; } @@ -85,10 +98,7 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final ByteArrayExplicitValueModification other = (ByteArrayExplicitValueModification) obj; - if (!Arrays.equals(this.explicitValue, other.explicitValue)) { - return false; - } - return true; + ByteArrayExplicitValueModification other = (ByteArrayExplicitValueModification) obj; + return Arrays.equals(explicitValue, other.explicitValue); } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayInsertModification.java b/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayInsertValueModification.java similarity index 66% rename from src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayInsertModification.java rename to src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayInsertValueModification.java index 660d6e0c..59579e1d 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayInsertModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayInsertValueModification.java @@ -21,52 +21,54 @@ @XmlRootElement @XmlType(propOrder = {"bytesToInsert", "startPosition", "modificationFilter"}) @XmlAccessorType(XmlAccessType.FIELD) -public class ByteArrayInsertModification extends VariableModification { +public class ByteArrayInsertValueModification extends VariableModification { private static final int MAX_EXPLICIT_VALUE = 256; - private static final int MAX_INSERT_MODIFIER = 32; + private static final int MAX_POSITION_MODIFIER = 32; @XmlJavaTypeAdapter(UnformattedByteArrayAdapter.class) private byte[] bytesToInsert; private int startPosition; - public ByteArrayInsertModification() {} + public ByteArrayInsertValueModification() { + super(); + } - public ByteArrayInsertModification(byte[] bytesToInsert, int startPosition) { + public ByteArrayInsertValueModification(byte[] bytesToInsert, int startPosition) { + super(); this.bytesToInsert = bytesToInsert; this.startPosition = startPosition; } + public ByteArrayInsertValueModification(ByteArrayInsertValueModification other) { + super(other); + bytesToInsert = other.bytesToInsert != null ? other.bytesToInsert.clone() : null; + startPosition = other.startPosition; + } + + @Override + public ByteArrayInsertValueModification createCopy() { + return new ByteArrayInsertValueModification(this); + } + @Override protected byte[] modifyImplementationHook(byte[] input) { if (input == null) { input = new byte[0]; } - int start = startPosition; - if (start < 0) { - start += input.length; - if (start < 0) { - LOGGER.debug( - "Trying to insert from too negative Startposition. start = " - + startPosition); - return input; - } - } - if (startPosition > input.length) { - LOGGER.debug( - "Trying to insert behind the Array. ArraySize:" - + input.length - + " Insert Position:" - + startPosition); - return input; + // Wrap around and also allow to insert at the end of the original value + int insertPosition = startPosition % (input.length + 1); + if (startPosition < 0) { + insertPosition += input.length; } - byte[] ret1 = Arrays.copyOf(input, start); + + byte[] ret1 = Arrays.copyOf(input, insertPosition); byte[] ret3 = null; - if ((start) < input.length) { - ret3 = Arrays.copyOfRange(input, start, input.length); + if (insertPosition < input.length) { + ret3 = Arrays.copyOfRange(input, insertPosition, input.length); } return ArrayConverter.concatenate(ret1, bytesToInsert, ret3); } @@ -95,10 +97,10 @@ public VariableModification getModifiedCopy() { int index = r.nextInt(bytesToInsert.length); byte[] newValue = Arrays.copyOf(bytesToInsert, bytesToInsert.length); newValue[index] = (byte) r.nextInt(MAX_EXPLICIT_VALUE); - return new ByteArrayInsertModification(newValue, startPosition); + return new ByteArrayInsertValueModification(newValue, startPosition); } else { byte[] newValue = Arrays.copyOf(bytesToInsert, bytesToInsert.length); - int modifier = r.nextInt(MAX_INSERT_MODIFIER); + int modifier = r.nextInt(MAX_POSITION_MODIFIER); if (r.nextBoolean()) { modifier *= -1; } @@ -106,15 +108,15 @@ public VariableModification getModifiedCopy() { if (modifier <= 0) { modifier = 1; } - return new ByteArrayInsertModification(newValue, modifier); + return new ByteArrayInsertValueModification(newValue, modifier); } } @Override public int hashCode() { int hash = 7; - hash = 59 * hash + Arrays.hashCode(this.bytesToInsert); - hash = 59 * hash + this.startPosition; + hash = 31 * hash + Arrays.hashCode(bytesToInsert); + hash = 31 * hash + startPosition; return hash; } @@ -129,14 +131,11 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final ByteArrayInsertModification other = (ByteArrayInsertModification) obj; - if (this.startPosition != other.startPosition) { - return false; - } - if (!Arrays.equals(this.bytesToInsert, other.bytesToInsert)) { + ByteArrayInsertValueModification other = (ByteArrayInsertValueModification) obj; + if (startPosition != other.startPosition) { return false; } - return true; + return Arrays.equals(bytesToInsert, other.bytesToInsert); } @Override diff --git a/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayModificationFactory.java b/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayModificationFactory.java index ce26299d..ee603cff 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayModificationFactory.java +++ b/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayModificationFactory.java @@ -15,31 +15,29 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.util.LinkedList; +import java.util.ArrayList; import java.util.List; import java.util.Random; -public class ByteArrayModificationFactory { - - private static final int BYTE_ARRAY_SHUFFLE_MODIFICATION = 6; - - private static final int BYTE_ARRAY_EXPLICIT_VALUE_MODIFICATION_FROM_FILE = 5; - - private static final int BYTE_ARRAY_DUPLICATE_MODIFICATION = 4; - - private static final int BYTE_ARRAY_EXPLICIT_VALUE_MODIFICATION = 3; - - private static final int BYTE_ARRAY_DELETE_MODIFICATION = 2; - - private static final int BYTE_ARRAY_INSERT_MODIFICATION = 1; - - private static final int BYTE_ARRAY_XOR_MODIFICATION = 0; +public final class ByteArrayModificationFactory { + + private enum ModificationType { + XOR, + APPEND, + INSERT, + PREPEND, + DELETE, + EXPLICIT, + DUPLICATE, + EXPLICIT_FROM_FILE, + SHUFFLE + } - private static final int MODIFICATION_COUNT = 7; + private static final int MODIFICATION_COUNT = ModificationType.values().length; - private static final int MAX_CONFIG_PARAMETER = 200; + private static final int MAX_BYTE_ARRAY_LENGTH = 200; - private static final int EXPLICIT_VALUE_RANDOM = 1000; + private static final int MAX_FILE_ENTRIES = 1000; private static final int MODIFIED_ARRAY_LENGTH_ESTIMATION = 50; @@ -52,20 +50,28 @@ public class ByteArrayModificationFactory { * @param startPosition negative numbers mean that the position is taken from the end * @return variable modification */ - public static VariableModification xor(final byte[] xor, final int startPosition) { + public static VariableModification xor(byte[] xor, int startPosition) { return new ByteArrayXorModification(xor, startPosition); } /** * * * - * @param bytesToInsert bytes to xor + * @param bytesToInsert bytes to insert * @param startPosition negative numbers mean that the position is taken from the end * @return variable modification */ - public static VariableModification insert( - final byte[] bytesToInsert, final int startPosition) { - return new ByteArrayInsertModification(bytesToInsert, startPosition); + public static VariableModification insertValue( + byte[] bytesToInsert, int startPosition) { + return new ByteArrayInsertValueModification(bytesToInsert, startPosition); + } + + public static VariableModification appendValue(byte[] bytesToAppend) { + return new ByteArrayAppendValueModification(bytesToAppend); + } + + public static VariableModification prependValue(byte[] bytesToPrepend) { + return new ByteArrayPrependValueModification(bytesToPrepend); } /** @@ -75,7 +81,7 @@ public static VariableModification insert( * @param count number of bytes to be deleted * @return variable modification */ - public static VariableModification delete(final int startPosition, final int count) { + public static VariableModification delete(int startPosition, int count) { return new ByteArrayDeleteModification(startPosition, count); } @@ -88,14 +94,13 @@ public static VariableModification duplicate() { return new ByteArrayDuplicateModification(); } - public static VariableModification explicitValue(final byte[] explicitValue) { + public static VariableModification explicitValue(byte[] explicitValue) { return new ByteArrayExplicitValueModification(explicitValue); } public static VariableModification explicitValueFromFile(int value) { List> modifications = modificationsFromFile(); - int pos = value % modifications.size(); - return modifications.get(pos); + return modifications.get(value % modifications.size()); } /** @@ -104,22 +109,25 @@ public static VariableModification explicitValueFromFile(int value) { * @param shuffle positions that define shuffling * @return shuffling variable modification */ - public static VariableModification shuffle(final byte[] shuffle) { + public static VariableModification shuffle(byte[] shuffle) { return new ByteArrayShuffleModification(shuffle); } public static synchronized List> modificationsFromFile() { try { if (modificationsFromFile == null) { - modificationsFromFile = new LinkedList<>(); + modificationsFromFile = new ArrayList<>(); ClassLoader classLoader = ByteArrayModificationFactory.class.getClassLoader(); InputStream is = classLoader.getResourceAsStream(FILE_NAME); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String line; + int index = 0; while ((line = br.readLine()) != null) { line = line.replaceAll("\\s+", ""); byte[] value = ArrayConverter.hexStringToByteArray(line); - modificationsFromFile.add(explicitValue(value)); + modificationsFromFile.add( + new ByteArrayExplicitValueFromFileModification(index, value)); + index++; } } return modificationsFromFile; @@ -131,69 +139,62 @@ public static synchronized List> modificationsFromF public static VariableModification createRandomModification(byte[] originalValue) { Random random = RandomHelper.getRandom(); - int r = random.nextInt(MODIFICATION_COUNT); - VariableModification vm = null; + ModificationType randomType = ModificationType.values()[random.nextInt(MODIFICATION_COUNT)]; int modifiedArrayLength; + int modificationArrayLength; + int startPosition; if (originalValue == null) { modifiedArrayLength = MODIFIED_ARRAY_LENGTH_ESTIMATION; } else { modifiedArrayLength = originalValue.length; if (originalValue.length == 0 || originalValue.length == 1) { - r = BYTE_ARRAY_EXPLICIT_VALUE_MODIFICATION; + randomType = ModificationType.EXPLICIT; } } - switch (r) { - case BYTE_ARRAY_XOR_MODIFICATION: - int modificationArrayLength = random.nextInt(modifiedArrayLength); - if (modificationArrayLength == 0) { - modificationArrayLength++; - } + modificationArrayLength = random.nextInt(MAX_BYTE_ARRAY_LENGTH - 1) + 1; + switch (randomType) { + case XOR: byte[] xor = new byte[modificationArrayLength]; random.nextBytes(xor); - int startPosition = random.nextInt(modifiedArrayLength - modificationArrayLength); - vm = new ByteArrayXorModification(xor, startPosition); - return vm; - case BYTE_ARRAY_INSERT_MODIFICATION: - modificationArrayLength = random.nextInt(MAX_CONFIG_PARAMETER); - if (modificationArrayLength == 0) { - modificationArrayLength++; - } + startPosition = random.nextInt(modifiedArrayLength - modificationArrayLength); + return new ByteArrayXorModification(xor, startPosition); + case APPEND: + byte[] bytesToAppend = new byte[modificationArrayLength]; + random.nextBytes(bytesToAppend); + return new ByteArrayAppendValueModification(bytesToAppend); + case INSERT: byte[] bytesToInsert = new byte[modificationArrayLength]; random.nextBytes(bytesToInsert); - int insertPosition = random.nextInt(modifiedArrayLength); - vm = new ByteArrayInsertModification(bytesToInsert, insertPosition); - return vm; - case BYTE_ARRAY_DELETE_MODIFICATION: + return new ByteArrayInsertValueModification( + bytesToInsert, random.nextInt(modifiedArrayLength)); + case PREPEND: + byte[] bytesToPrepend = new byte[modificationArrayLength]; + random.nextBytes(bytesToPrepend); + return new ByteArrayPrependValueModification(bytesToPrepend); + case DELETE: startPosition = random.nextInt(modifiedArrayLength - 1); int count = random.nextInt(modifiedArrayLength - startPosition); count++; - vm = new ByteArrayDeleteModification(startPosition, count); - return vm; - case BYTE_ARRAY_EXPLICIT_VALUE_MODIFICATION: - modificationArrayLength = random.nextInt(MAX_CONFIG_PARAMETER); - if (modificationArrayLength == 0) { - modificationArrayLength++; - } + return new ByteArrayDeleteModification(startPosition, count); + case EXPLICIT: byte[] explicitValue = new byte[modificationArrayLength]; random.nextBytes(explicitValue); - vm = new ByteArrayExplicitValueModification(explicitValue); - return vm; - case BYTE_ARRAY_DUPLICATE_MODIFICATION: - vm = new ByteArrayDuplicateModification(); - return vm; - case BYTE_ARRAY_EXPLICIT_VALUE_MODIFICATION_FROM_FILE: - vm = explicitValueFromFile(random.nextInt(EXPLICIT_VALUE_RANDOM)); - return vm; - case BYTE_ARRAY_SHUFFLE_MODIFICATION: - int shuffleSize = random.nextInt(MAX_CONFIG_PARAMETER); + return new ByteArrayExplicitValueModification(explicitValue); + case DUPLICATE: + return new ByteArrayDuplicateModification(); + case EXPLICIT_FROM_FILE: + return explicitValueFromFile(random.nextInt(MAX_FILE_ENTRIES)); + case SHUFFLE: + int shuffleSize = random.nextInt(MAX_BYTE_ARRAY_LENGTH); byte[] shuffle = new byte[shuffleSize]; random.nextBytes(shuffle); - vm = shuffle(shuffle); - return vm; + return new ByteArrayShuffleModification(shuffle); default: - return vm; + throw new IllegalStateException("Unexpected modification type: " + randomType); } } - private ByteArrayModificationFactory() {} + private ByteArrayModificationFactory() { + super(); + } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayPrependValueModification.java b/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayPrependValueModification.java new file mode 100644 index 00000000..7399d6ec --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayPrependValueModification.java @@ -0,0 +1,105 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.bytearray; + +import de.rub.nds.modifiablevariable.VariableModification; +import de.rub.nds.modifiablevariable.util.ArrayConverter; +import de.rub.nds.modifiablevariable.util.UnformattedByteArrayAdapter; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import java.util.Arrays; +import java.util.Random; + +@XmlRootElement +@XmlType(propOrder = {"bytesToPrepend", "modificationFilter"}) +@XmlAccessorType(XmlAccessType.FIELD) +public class ByteArrayPrependValueModification extends VariableModification { + + private static final int MAX_EXPLICIT_VALUE = 256; + + @XmlJavaTypeAdapter(UnformattedByteArrayAdapter.class) + private byte[] bytesToPrepend; + + public ByteArrayPrependValueModification() { + super(); + } + + public ByteArrayPrependValueModification(byte[] bytesToPrepend) { + super(); + this.bytesToPrepend = bytesToPrepend; + } + + public ByteArrayPrependValueModification(ByteArrayPrependValueModification other) { + super(other); + bytesToPrepend = other.bytesToPrepend != null ? other.bytesToPrepend.clone() : null; + } + + @Override + public ByteArrayPrependValueModification createCopy() { + return new ByteArrayPrependValueModification(this); + } + + @Override + protected byte[] modifyImplementationHook(byte[] input) { + if (input == null) { + input = new byte[0]; + } + + return ArrayConverter.concatenate(bytesToPrepend, input); + } + + public byte[] getBytesToPrepend() { + return bytesToPrepend; + } + + public void setBytesToPrepend(byte[] bytesToPrepend) { + this.bytesToPrepend = bytesToPrepend; + } + + @Override + public VariableModification getModifiedCopy() { + Random r = new Random(); + + int index = r.nextInt(bytesToPrepend.length); + byte[] newValue = Arrays.copyOf(bytesToPrepend, bytesToPrepend.length); + newValue[index] = (byte) r.nextInt(MAX_EXPLICIT_VALUE); + return new ByteArrayPrependValueModification(newValue); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + Arrays.hashCode(bytesToPrepend); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + ByteArrayPrependValueModification other = (ByteArrayPrependValueModification) obj; + return Arrays.equals(bytesToPrepend, other.bytesToPrepend); + } + + @Override + public String toString() { + return "ByteArrayPrependValueModification{bytesToPrepend=" + + ArrayConverter.bytesToHexString(bytesToPrepend) + + "}"; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayShuffleModification.java b/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayShuffleModification.java index 379a7354..47990150 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayShuffleModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayShuffleModification.java @@ -32,20 +32,42 @@ public class ByteArrayShuffleModification extends VariableModification { @XmlJavaTypeAdapter(UnformattedByteArrayAdapter.class) private byte[] shuffle; - public ByteArrayShuffleModification() {} + public ByteArrayShuffleModification() { + super(); + } public ByteArrayShuffleModification(byte[] shuffle) { + super(); this.shuffle = shuffle; } + public ByteArrayShuffleModification(ByteArrayShuffleModification other) { + super(other); + shuffle = other.shuffle != null ? other.shuffle.clone() : null; + } + + @Override + public ByteArrayShuffleModification createCopy() { + return new ByteArrayShuffleModification(this); + } + @Override - protected byte[] modifyImplementationHook(final byte[] input) { + protected byte[] modifyImplementationHook(byte[] input) { if (input == null) { - return input; + return null; } byte[] result = input.clone(); int size = input.length; - if (size != 0) { + if (size > 255) { + for (int i = 0; i < shuffle.length - 3; i += 4) { + // Combine two consecutive bytes to form 16-bit values + int p1 = ((shuffle[i] & 0xff) << 8 | shuffle[i + 1] & 0xff) % size; + int p2 = ((shuffle[i + 2] & 0xff) << 8 | shuffle[i + 3] & 0xff) % size; + byte tmp = result[p1]; + result[p1] = result[p2]; + result[p2] = tmp; + } + } else if (size > 0) { for (int i = 0; i < shuffle.length - 1; i += 2) { int p1 = (shuffle[i] & 0xff) % size; int p2 = (shuffle[i + 1] & 0xff) % size; @@ -71,13 +93,13 @@ public VariableModification getModifiedCopy() { int index = r.nextInt(shuffle.length); byte[] newValue = Arrays.copyOf(shuffle, shuffle.length); newValue[index] = (byte) r.nextInt(MAX_MODIFIER_VALUE); - return new ByteArrayShuffleModification(shuffle); + return new ByteArrayShuffleModification(newValue); } @Override public int hashCode() { - int hash = 5; - hash = 71 * hash + Arrays.hashCode(this.shuffle); + int hash = 7; + hash = 31 * hash + Arrays.hashCode(shuffle); return hash; } @@ -92,11 +114,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final ByteArrayShuffleModification other = (ByteArrayShuffleModification) obj; - if (!Arrays.equals(this.shuffle, other.shuffle)) { - return false; - } - return true; + ByteArrayShuffleModification other = (ByteArrayShuffleModification) obj; + return Arrays.equals(shuffle, other.shuffle); } @Override diff --git a/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayXorModification.java b/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayXorModification.java index 9845db53..3471b3ea 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayXorModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/bytearray/ByteArrayXorModification.java @@ -32,38 +32,53 @@ public class ByteArrayXorModification extends VariableModification { private int startPosition; - public ByteArrayXorModification() {} + public ByteArrayXorModification() { + super(); + } public ByteArrayXorModification(byte[] xor, int startPosition) { + super(); this.xor = xor; this.startPosition = startPosition; } + public ByteArrayXorModification(ByteArrayXorModification other) { + super(other); + xor = other.xor != null ? other.xor.clone() : null; + startPosition = other.startPosition; + } + + @Override + public ByteArrayXorModification createCopy() { + return new ByteArrayXorModification(this); + } + @Override protected byte[] modifyImplementationHook(byte[] input) { if (input == null) { input = new byte[0]; } + if (input.length == 0) { + return input; + } byte[] result = input.clone(); - int start = startPosition; - if (start < 0) { - start += input.length; + + // Wrap around and also allow to xor at the end of the original value + int xorPosition = startPosition % input.length; + if (startPosition < 0) { + xorPosition += input.length - 1; } - final int end = start + xor.length; - if (end > result.length) { - // result = new byte[end]; - // System.arraycopy(input, 0, result, 0, input.length); - LOGGER.debug( - "Input {{}} of length {} cannot be xor-ed with {{}} of length {} with start position {}", - input, - input.length, - xor, - xor.length, - startPosition); - return input; + int endPosition = xorPosition + xor.length; + if (endPosition > result.length) { + // Fix the end position to the length of the original value + // This may not match the expected behavior of a user + // But for fuzzing purpose, that's fine + // Todo: Add an option that expands the byte array instead + endPosition = result.length; } - for (int i = 0; i < xor.length; ++i) { - result[start + i] = (byte) (input[start + i] ^ xor[i]); + + for (int i = 0; i < endPosition - xorPosition; ++i) { + result[xorPosition + i] = (byte) (input[xorPosition + i] ^ xor[i]); } return result; } @@ -109,8 +124,8 @@ public VariableModification getModifiedCopy() { @Override public int hashCode() { int hash = 7; - hash = 97 * hash + Arrays.hashCode(this.xor); - hash = 97 * hash + this.startPosition; + hash = 31 * hash + Arrays.hashCode(xor); + hash = 31 * hash + startPosition; return hash; } @@ -125,14 +140,11 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final ByteArrayXorModification other = (ByteArrayXorModification) obj; - if (this.startPosition != other.startPosition) { - return false; - } - if (!Arrays.equals(this.xor, other.xor)) { + ByteArrayXorModification other = (ByteArrayXorModification) obj; + if (startPosition != other.startPosition) { return false; } - return true; + return Arrays.equals(xor, other.xor); } @Override diff --git a/src/main/java/de/rub/nds/modifiablevariable/bytearray/ModifiableByteArray.java b/src/main/java/de/rub/nds/modifiablevariable/bytearray/ModifiableByteArray.java index a0d46cb4..9601e69e 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/bytearray/ModifiableByteArray.java +++ b/src/main/java/de/rub/nds/modifiablevariable/bytearray/ModifiableByteArray.java @@ -21,12 +21,30 @@ @XmlAccessorType(XmlAccessType.PROPERTY) public class ModifiableByteArray extends ModifiableVariable { - public ModifiableByteArray() {} - private byte[] originalValue; + public ModifiableByteArray() { + super(); + } + + public ModifiableByteArray(byte[] originalValue) { + super(); + this.originalValue = originalValue; + } + + public ModifiableByteArray(ModifiableByteArray other) { + super(other); + originalValue = other.originalValue != null ? other.originalValue.clone() : null; + assertEquals = other.assertEquals != null ? other.assertEquals.clone() : null; + } + + @Override + public ModifiableByteArray createCopy() { + return new ModifiableByteArray(this); + } + @Override - protected void createRandomModification() { + public void setRandomModification() { VariableModification vm = ByteArrayModificationFactory.createRandomModification(originalValue); setModification(vm); @@ -69,30 +87,15 @@ public boolean validateAssertions() { } @Override - public String toString() { - StringBuilder result = new StringBuilder(); - if (this.isOriginalValueModified()) { - result.append("Actual byte value is: "); - result.append(ArrayConverter.bytesToHexString(this)); - result.append("\nOriginal value was: "); - result.append(ArrayConverter.bytesToHexString(this.getOriginalValue())); - } else { - result.append("Original byte value is: "); - result.append(ArrayConverter.bytesToHexString(this.getOriginalValue())); - } - return result.toString(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { + public boolean equals(Object obj) { + if (this == obj) { return true; } - if (!(o instanceof ModifiableByteArray)) { + if (!(obj instanceof ModifiableByteArray)) { return false; } - ModifiableByteArray that = (ModifiableByteArray) o; + ModifiableByteArray that = (ModifiableByteArray) obj; return Arrays.equals(getValue(), that.getValue()); } @@ -103,4 +106,13 @@ public int hashCode() { result = 31 * result + Arrays.hashCode(getValue()); return result; } + + @Override + public String toString() { + return "ModifiableByteArray{" + + "originalValue=" + + ArrayConverter.bytesToHexString(originalValue) + + innerToString() + + '}'; + } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/filter/AccessModificationFilter.java b/src/main/java/de/rub/nds/modifiablevariable/filter/AccessModificationFilter.java index 02daf06f..cbf940ac 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/filter/AccessModificationFilter.java +++ b/src/main/java/de/rub/nds/modifiablevariable/filter/AccessModificationFilter.java @@ -29,14 +29,27 @@ public class AccessModificationFilter extends ModificationFilter { private int[] accessNumbers; public AccessModificationFilter() { + super(); accessCounter = 1; } - public AccessModificationFilter(final int[] accessNumbers) { + public AccessModificationFilter(int[] accessNumbers) { + super(); accessCounter = 1; this.accessNumbers = accessNumbers; } + public AccessModificationFilter(AccessModificationFilter other) { + super(other); + accessCounter = other.accessCounter; + accessNumbers = other.accessNumbers != null ? other.accessNumbers.clone() : null; + } + + @Override + public AccessModificationFilter createCopy() { + return new AccessModificationFilter(this); + } + @Override public boolean filterModification() { boolean filter = contains(accessNumbers, accessCounter); @@ -44,7 +57,7 @@ public boolean filterModification() { return filter; } - private boolean contains(int[] numbers, int number) { + private static boolean contains(int[] numbers, int number) { for (int i : numbers) { if (i == number) { return true; diff --git a/src/main/java/de/rub/nds/modifiablevariable/filter/ModificationFilterFactory.java b/src/main/java/de/rub/nds/modifiablevariable/filter/ModificationFilterFactory.java index db70b67f..66a46b03 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/filter/ModificationFilterFactory.java +++ b/src/main/java/de/rub/nds/modifiablevariable/filter/ModificationFilterFactory.java @@ -7,11 +7,13 @@ */ package de.rub.nds.modifiablevariable.filter; -public class ModificationFilterFactory { +public final class ModificationFilterFactory { - public static AccessModificationFilter access(final int[] accessNumbers) { + public static AccessModificationFilter access(int[] accessNumbers) { return new AccessModificationFilter(accessNumbers); } - private ModificationFilterFactory() {} + private ModificationFilterFactory() { + super(); + } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerAddModification.java b/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerAddModification.java index eb466c99..d0e24a60 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerAddModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerAddModification.java @@ -21,15 +21,28 @@ public class IntegerAddModification extends VariableModification { private Integer summand; - public IntegerAddModification() {} + public IntegerAddModification() { + super(); + } + + public IntegerAddModification(Integer summand) { + super(); + this.summand = summand; + } + + public IntegerAddModification(IntegerAddModification other) { + super(other); + summand = other.summand; + } - public IntegerAddModification(Integer bi) { - this.summand = bi; + @Override + public IntegerAddModification createCopy() { + return new IntegerAddModification(this); } @Override protected Integer modifyImplementationHook(Integer input) { - return (input == null) ? summand : input + summand; + return input == null ? summand : input + summand; } public Integer getSummand() { @@ -47,8 +60,8 @@ public VariableModification getModifiedCopy() { @Override public int hashCode() { - int hash = 3; - hash = 23 * hash + Objects.hashCode(this.summand); + int hash = 7; + hash = 31 * hash + summand; return hash; } @@ -63,10 +76,12 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final IntegerAddModification other = (IntegerAddModification) obj; - if (!Objects.equals(this.summand, other.summand)) { - return false; - } - return true; + IntegerAddModification other = (IntegerAddModification) obj; + return Objects.equals(summand, other.summand); + } + + @Override + public String toString() { + return "IntegerAddModification{" + "summand=" + summand + '}'; } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerAppendValueModification.java b/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerAppendValueModification.java new file mode 100644 index 00000000..1f4729ab --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerAppendValueModification.java @@ -0,0 +1,91 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.integer; + +import de.rub.nds.modifiablevariable.VariableModification; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import java.util.Objects; +import java.util.Random; + +@XmlRootElement +@XmlType(propOrder = {"appendValue", "modificationFilter"}) +public class IntegerAppendValueModification extends VariableModification { + + private static final int MAX_VALUE_MODIFIER = 256; + + private Integer appendValue; + + public IntegerAppendValueModification() { + super(); + } + + public IntegerAppendValueModification(Integer appendValue) { + super(); + this.appendValue = appendValue; + } + + public IntegerAppendValueModification(IntegerAppendValueModification other) { + super(other); + appendValue = other.appendValue; + } + + @Override + public IntegerAppendValueModification createCopy() { + return new IntegerAppendValueModification(this); + } + + @Override + protected Integer modifyImplementationHook(Integer input) { + if (input == null) { + input = 0; + } + return input << Integer.SIZE - Integer.numberOfLeadingZeros(appendValue) | appendValue; + } + + public Integer getAppendValue() { + return appendValue; + } + + public void setAppendValue(Integer appendValue) { + this.appendValue = appendValue; + } + + @Override + public VariableModification getModifiedCopy() { + return new IntegerAppendValueModification( + appendValue + new Random().nextInt(MAX_VALUE_MODIFIER)); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + appendValue; + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + IntegerAppendValueModification other = (IntegerAppendValueModification) obj; + return Objects.equals(appendValue, other.appendValue); + } + + @Override + public String toString() { + return "IntegerAppendValueModification{" + "appendValue=" + appendValue + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerExplicitValueFromFileModification.java b/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerExplicitValueFromFileModification.java new file mode 100644 index 00000000..f8affaed --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerExplicitValueFromFileModification.java @@ -0,0 +1,89 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.integer; + +import de.rub.nds.modifiablevariable.VariableModification; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import java.util.Objects; + +@XmlRootElement +@XmlType(propOrder = "index") +@XmlAccessorType(XmlAccessType.FIELD) +public class IntegerExplicitValueFromFileModification extends IntegerExplicitValueModification { + private int index; + + public IntegerExplicitValueFromFileModification() { + super(); + } + + public IntegerExplicitValueFromFileModification(int index, Integer explicitValue) { + super(explicitValue); + this.index = index; + } + + public IntegerExplicitValueFromFileModification( + IntegerExplicitValueFromFileModification other) { + super(other); + index = other.index; + } + + @Override + public IntegerExplicitValueFromFileModification createCopy() { + return new IntegerExplicitValueFromFileModification(this); + } + + public int getIndex() { + return index; + } + + @Override + public VariableModification getModifiedCopy() { + throw new UnsupportedOperationException( + "Cannot set modify Value of IntegerExplicitValueFromFileModification"); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + index; + hash = 31 * hash + explicitValue.hashCode(); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + IntegerExplicitValueFromFileModification other = + (IntegerExplicitValueFromFileModification) obj; + if (index != other.index) { + return false; + } + return Objects.equals(explicitValue, other.explicitValue); + } + + @Override + public String toString() { + return "IntegerExplicitValueFromFileModification{" + + "index=" + + index + + ", explicitValue=" + + explicitValue + + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerExplicitValueModification.java b/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerExplicitValueModification.java index 5b5e4db7..10d5e6f1 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerExplicitValueModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerExplicitValueModification.java @@ -19,16 +19,29 @@ public class IntegerExplicitValueModification extends VariableModification getModifiedCopy() { @Override public int hashCode() { int hash = 7; - hash = 53 * hash + Objects.hashCode(this.explicitValue); + hash = 31 * hash + explicitValue; return hash; } @@ -70,10 +83,12 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final IntegerExplicitValueModification other = (IntegerExplicitValueModification) obj; - if (!Objects.equals(this.explicitValue, other.explicitValue)) { - return false; - } - return true; + IntegerExplicitValueModification other = (IntegerExplicitValueModification) obj; + return Objects.equals(explicitValue, other.explicitValue); + } + + @Override + public String toString() { + return "IntegerExplicitValueModification{" + "explicitValue=" + explicitValue + '}'; } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerInsertValueModification.java b/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerInsertValueModification.java new file mode 100644 index 00000000..2473144b --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerInsertValueModification.java @@ -0,0 +1,140 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.integer; + +import de.rub.nds.modifiablevariable.VariableModification; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import java.util.Objects; +import java.util.Random; + +@XmlRootElement +@XmlType(propOrder = {"insertValue", "startPosition", "modificationFilter"}) +public class IntegerInsertValueModification extends VariableModification { + + private static final int MAX_VALUE_MODIFIER = 256; + + private static final int MAX_POSITION_MODIFIER = 32; + + private Integer insertValue; + + private int startPosition; + + public IntegerInsertValueModification() { + super(); + } + + public IntegerInsertValueModification(Integer insertValue, int startPosition) { + super(); + this.insertValue = insertValue; + this.startPosition = startPosition; + } + + public IntegerInsertValueModification(IntegerInsertValueModification other) { + super(other); + insertValue = other.insertValue; + startPosition = other.startPosition; + } + + @Override + public IntegerInsertValueModification createCopy() { + return new IntegerInsertValueModification(this); + } + + @Override + protected Integer modifyImplementationHook(Integer input) { + if (input == null) { + input = 0; + } + + int insertValueLength = Integer.SIZE - Integer.numberOfLeadingZeros(insertValue); + + // Wrap around integer size + int insertPosition = startPosition % Integer.SIZE; + if (startPosition < 0) { + insertPosition += Integer.SIZE - 1; + } + + int mask = (1 << insertPosition) - 1; + + return (input >> insertPosition << insertValueLength | insertValue) << insertPosition + | mask & input; + } + + public Integer getInsertValue() { + return insertValue; + } + + public void setInsertValue(Integer insertValue) { + this.insertValue = insertValue; + } + + public int getStartPosition() { + return startPosition; + } + + public void setStartPosition(int startPosition) { + this.startPosition = startPosition; + } + + @Override + public VariableModification getModifiedCopy() { + Random r = new Random(); + + if (r.nextBoolean()) { + return new IntegerInsertValueModification( + insertValue + r.nextInt(MAX_VALUE_MODIFIER), startPosition); + } else { + int modifier = r.nextInt(MAX_POSITION_MODIFIER); + if (r.nextBoolean()) { + modifier *= -1; + } + modifier = startPosition + modifier; + if (modifier <= 0) { + modifier = 1; + } + return new IntegerInsertValueModification(insertValue, modifier); + } + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + insertValue; + hash = 31 * hash + startPosition; + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + IntegerInsertValueModification other = (IntegerInsertValueModification) obj; + if (startPosition != other.startPosition) { + return false; + } + return Objects.equals(insertValue, other.insertValue); + } + + @Override + public String toString() { + return "IntegerInsertValueModification{" + + "insertValue=" + + insertValue + + ", startPosition=" + + startPosition + + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerModificationFactory.java b/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerModificationFactory.java index 824f9f87..9acd71eb 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerModificationFactory.java +++ b/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerModificationFactory.java @@ -14,87 +14,133 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.util.LinkedList; +import java.util.ArrayList; import java.util.List; import java.util.Random; -public class IntegerModificationFactory { +public final class IntegerModificationFactory { + + private enum ModificationType { + ADD, + SUBTRACT, + MULTIPLY, + XOR, + SWAP_ENDIAN, + EXPLICIT, + SHIFT_LEFT, + SHIFT_RIGHT, + EXPLICIT_FROM_FILE, + APPEND, + INSERT, + PREPEND + } - private static final int MODIFICATION_COUNT = 7; + private static final int MODIFICATION_COUNT = ModificationType.values().length; private static final int MAX_MODIFICATION_VALUE = 32000; + private static final int MAX_FILE_ENTRIES = 200; + private static final int MAX_MODIFICATION_SHIFT_VALUE = 20; + private static final int MAX_MODIFICATION_MULTIPLY_VALUE = 256; + + private static final int MAX_MODIFICATION_INSERT_VALUE = 256; + + private static final int MAX_MODIFICATION_INSERT_POSITION_VALUE = 32; + private static List> modificationsFromFile; public static final String FILE_NAME = "de/rub/nds/modifiablevariable/explicit/integer.vec"; - public static IntegerAddModification add(final String summand) { + public static IntegerAddModification add(String summand) { return add(Integer.parseInt(summand)); } - public static IntegerAddModification add(final Integer summand) { + public static IntegerAddModification add(Integer summand) { return new IntegerAddModification(summand); } - public static IntegerShiftLeftModification shiftLeft(final String shift) { + public static IntegerShiftLeftModification shiftLeft(String shift) { return shiftLeft(Integer.parseInt(shift)); } - public static IntegerShiftLeftModification shiftLeft(final Integer shift) { + public static IntegerShiftLeftModification shiftLeft(Integer shift) { return new IntegerShiftLeftModification(shift); } - public static IntegerShiftRightModification shiftRight(final String shift) { + public static IntegerShiftRightModification shiftRight(String shift) { return shiftRight(Integer.parseInt(shift)); } - public static IntegerShiftRightModification shiftRight(final Integer shift) { + public static IntegerShiftRightModification shiftRight(Integer shift) { return new IntegerShiftRightModification(shift); } - public static VariableModification sub(final String subtrahend) { + public static VariableModification sub(String subtrahend) { return sub(Integer.parseInt(subtrahend)); } - public static VariableModification sub(final Integer subtrahend) { + public static VariableModification sub(Integer subtrahend) { return new IntegerSubtractModification(subtrahend); } - public static VariableModification xor(final String xor) { + public static VariableModification xor(String xor) { return xor(Integer.parseInt(xor)); } - public static VariableModification xor(final Integer xor) { + public static VariableModification xor(Integer xor) { return new IntegerXorModification(xor); } - public static VariableModification explicitValue(final String value) { + public static VariableModification swapEndian() { + return new IntegerSwapEndianModification(); + } + + public static VariableModification explicitValue(String value) { return explicitValue(Integer.parseInt(value)); } - public static VariableModification explicitValue(final Integer value) { + public static VariableModification explicitValue(Integer value) { return new IntegerExplicitValueModification(value); } - public static VariableModification explicitValueFromFile(int value) { + public static VariableModification explicitValueFromFile(int pos) { List> modifications = modificationsFromFile(); - int pos = value % modifications.size(); - return modifications.get(pos); + return modifications.get(pos % modifications.size()); + } + + public static VariableModification appendValue(Integer value) { + return new IntegerAppendValueModification(value); + } + + public static VariableModification insertValue(Integer value, int position) { + return new IntegerInsertValueModification(value, position); + } + + public static VariableModification prependValue(Integer value) { + return new IntegerPrependValueModification(value); + } + + public static VariableModification multiply(Integer value) { + return new IntegerMultiplyModification(value); } public static synchronized List> modificationsFromFile() { try { if (modificationsFromFile == null) { - modificationsFromFile = new LinkedList<>(); + modificationsFromFile = new ArrayList<>(); ClassLoader classLoader = IntegerModificationFactory.class.getClassLoader(); InputStream is = classLoader.getResourceAsStream(FILE_NAME); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String line; + int index = 0; while ((line = br.readLine()) != null) { String value = line.trim().split(" ")[0]; - modificationsFromFile.add(explicitValue(value)); + modificationsFromFile.add( + new IntegerExplicitValueFromFileModification( + index, Integer.parseInt(value))); + index++; } } return modificationsFromFile; @@ -106,36 +152,44 @@ public static synchronized List> modificationsFrom public static VariableModification createRandomModification() { Random random = RandomHelper.getRandom(); - int r = random.nextInt(MODIFICATION_COUNT); + ModificationType randomType = ModificationType.values()[random.nextInt(MODIFICATION_COUNT)]; int modification = random.nextInt(MAX_MODIFICATION_VALUE); + int insert_modification = random.nextInt(MAX_MODIFICATION_INSERT_VALUE); int shiftModification = random.nextInt(MAX_MODIFICATION_SHIFT_VALUE); - VariableModification vm = null; - switch (r) { - case 0: - vm = new IntegerAddModification(modification); - return vm; - case 1: - vm = new IntegerSubtractModification(modification); - return vm; - case 2: - vm = new IntegerXorModification(modification); - return vm; - case 3: - vm = new IntegerExplicitValueModification(modification); - return vm; - case 4: - vm = new IntegerShiftLeftModification(shiftModification); - return vm; - case 5: - vm = new IntegerShiftRightModification(shiftModification); - return vm; - case 6: - vm = explicitValueFromFile(random.nextInt(MAX_MODIFICATION_VALUE)); - return vm; + switch (randomType) { + case ADD: + return new IntegerAddModification(modification); + case SUBTRACT: + return new IntegerSubtractModification(modification); + case MULTIPLY: + return new IntegerSubtractModification( + random.nextInt(MAX_MODIFICATION_MULTIPLY_VALUE)); + case XOR: + return new IntegerXorModification(modification); + case SWAP_ENDIAN: + return new IntegerSwapEndianModification(); + case EXPLICIT: + return new IntegerExplicitValueModification(modification); + case SHIFT_LEFT: + return new IntegerShiftLeftModification(shiftModification); + case SHIFT_RIGHT: + return new IntegerShiftRightModification(shiftModification); + case EXPLICIT_FROM_FILE: + return explicitValueFromFile(random.nextInt(MAX_FILE_ENTRIES)); + case APPEND: + return new IntegerAppendValueModification(insert_modification); + case INSERT: + return new IntegerInsertValueModification( + insert_modification, + random.nextInt(MAX_MODIFICATION_INSERT_POSITION_VALUE)); + case PREPEND: + return new IntegerPrependValueModification(insert_modification); default: - return vm; + throw new IllegalStateException("Unexpected modification type: " + randomType); } } - private IntegerModificationFactory() {} + private IntegerModificationFactory() { + super(); + } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerMultiplyModification.java b/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerMultiplyModification.java new file mode 100644 index 00000000..0f441bba --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerMultiplyModification.java @@ -0,0 +1,89 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.integer; + +import de.rub.nds.modifiablevariable.VariableModification; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import java.util.Objects; +import java.util.Random; + +@XmlRootElement +@XmlType(propOrder = {"factor", "modificationFilter"}) +public class IntegerMultiplyModification extends VariableModification { + + private static final int MAX_FACTOR_MODIFIER = 256; + + private Integer factor; + + public IntegerMultiplyModification() { + super(); + } + + public IntegerMultiplyModification(Integer factor) { + super(); + this.factor = factor; + } + + public IntegerMultiplyModification(IntegerMultiplyModification other) { + super(other); + factor = other.factor; + } + + @Override + public IntegerMultiplyModification createCopy() { + return new IntegerMultiplyModification(this); + } + + @Override + protected Integer modifyImplementationHook(Integer input) { + return input == null ? 0 : input * factor; + } + + public Integer getFactor() { + return factor; + } + + public void setFactor(Integer factor) { + this.factor = factor; + } + + @Override + public VariableModification getModifiedCopy() { + Random r = new Random(); + + return new IntegerMultiplyModification(factor + r.nextInt(MAX_FACTOR_MODIFIER)); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + factor; + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + IntegerMultiplyModification other = (IntegerMultiplyModification) obj; + return Objects.equals(factor, other.factor); + } + + @Override + public String toString() { + return "IntegerMultiplyModification{" + "factor=" + factor + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerPrependValueModification.java b/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerPrependValueModification.java new file mode 100644 index 00000000..ddbf3676 --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerPrependValueModification.java @@ -0,0 +1,92 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.integer; + +import de.rub.nds.modifiablevariable.VariableModification; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import java.util.Objects; +import java.util.Random; + +@XmlRootElement +@XmlType(propOrder = {"prependValue", "modificationFilter"}) +public class IntegerPrependValueModification extends VariableModification { + + private static final int MAX_VALUE_MODIFIER = 256; + + private Integer prependValue; + + public IntegerPrependValueModification() { + super(); + } + + public IntegerPrependValueModification(Integer prependValue) { + super(); + this.prependValue = prependValue; + } + + public IntegerPrependValueModification(IntegerPrependValueModification other) { + super(other); + prependValue = other.prependValue; + } + + @Override + public IntegerPrependValueModification createCopy() { + return new IntegerPrependValueModification(this); + } + + @Override + protected Integer modifyImplementationHook(Integer input) { + if (input == null) { + input = 0; + } + + return prependValue << Integer.SIZE - Integer.numberOfLeadingZeros(input) | input; + } + + public Integer getPrependValue() { + return prependValue; + } + + public void setPrependValue(Integer prependValue) { + this.prependValue = prependValue; + } + + @Override + public VariableModification getModifiedCopy() { + return new IntegerPrependValueModification( + prependValue + new Random().nextInt(MAX_VALUE_MODIFIER)); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + prependValue; + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + IntegerPrependValueModification other = (IntegerPrependValueModification) obj; + return Objects.equals(prependValue, other.prependValue); + } + + @Override + public String toString() { + return "IntegerPrependValueModification{" + "prependValue=" + prependValue + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerShiftLeftModification.java b/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerShiftLeftModification.java index 3647542c..7c6aced5 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerShiftLeftModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerShiftLeftModification.java @@ -20,15 +20,28 @@ public class IntegerShiftLeftModification extends VariableModification private int shift; - public IntegerShiftLeftModification() {} + public IntegerShiftLeftModification() { + super(); + } public IntegerShiftLeftModification(int shift) { + super(); this.shift = shift; } + public IntegerShiftLeftModification(IntegerShiftLeftModification other) { + super(other); + shift = other.shift; + } + + @Override + public IntegerShiftLeftModification createCopy() { + return new IntegerShiftLeftModification(this); + } + @Override protected Integer modifyImplementationHook(Integer input) { - return (input == null) ? 0 : input << shift; + return input == null ? 0 : input << shift % MAX_SHIFT_MODIFIER; } public int getShift() { @@ -59,7 +72,7 @@ public VariableModification getModifiedCopy() { @Override public int hashCode() { int hash = 7; - hash = 73 * hash + this.shift; + hash = 31 * hash + shift; return hash; } @@ -74,10 +87,12 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final IntegerShiftLeftModification other = (IntegerShiftLeftModification) obj; - if (this.shift != other.shift) { - return false; - } - return true; + IntegerShiftLeftModification other = (IntegerShiftLeftModification) obj; + return shift == other.shift; + } + + @Override + public String toString() { + return "IntegerShiftLeftModification{" + "shift=" + shift + '}'; } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerShiftRightModification.java b/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerShiftRightModification.java index f0cfb2e6..bb25bd2b 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerShiftRightModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerShiftRightModification.java @@ -20,15 +20,28 @@ public class IntegerShiftRightModification extends VariableModification private int shift; - public IntegerShiftRightModification() {} + public IntegerShiftRightModification() { + super(); + } public IntegerShiftRightModification(int shift) { + super(); this.shift = shift; } + public IntegerShiftRightModification(IntegerShiftRightModification other) { + super(other); + shift = other.shift; + } + + @Override + public IntegerShiftRightModification createCopy() { + return new IntegerShiftRightModification(this); + } + @Override - protected Integer modifyImplementationHook(final Integer input) { - return (input == null) ? 0 : input >> shift; + protected Integer modifyImplementationHook(Integer input) { + return input == null ? 0 : input >> shift % MAX_SHIFT_MODIFIER; } public int getShift() { @@ -58,8 +71,8 @@ public VariableModification getModifiedCopy() { @Override public int hashCode() { - int hash = 5; - hash = 59 * hash + this.shift; + int hash = 7; + hash = 31 * hash + shift; return hash; } @@ -74,10 +87,12 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final IntegerShiftRightModification other = (IntegerShiftRightModification) obj; - if (this.shift != other.shift) { - return false; - } - return true; + IntegerShiftRightModification other = (IntegerShiftRightModification) obj; + return shift == other.shift; + } + + @Override + public String toString() { + return "IntegerShiftRightModification{" + "shift=" + shift + '}'; } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerSubtractModification.java b/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerSubtractModification.java index 12c43435..3586d55c 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerSubtractModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerSubtractModification.java @@ -21,15 +21,28 @@ public class IntegerSubtractModification extends VariableModification { private Integer subtrahend; - public IntegerSubtractModification() {} + public IntegerSubtractModification() { + super(); + } + + public IntegerSubtractModification(Integer subtrahend) { + super(); + this.subtrahend = subtrahend; + } + + public IntegerSubtractModification(IntegerSubtractModification other) { + super(other); + subtrahend = other.subtrahend; + } - public IntegerSubtractModification(Integer bi) { - this.subtrahend = bi; + @Override + public IntegerSubtractModification createCopy() { + return new IntegerSubtractModification(this); } @Override - protected Integer modifyImplementationHook(final Integer input) { - return (input == null) ? -subtrahend : input - subtrahend; + protected Integer modifyImplementationHook(Integer input) { + return input == null ? -subtrahend : input - subtrahend; } public Integer getSubtrahend() { @@ -49,7 +62,7 @@ public VariableModification getModifiedCopy() { @Override public int hashCode() { int hash = 7; - hash = 23 * hash + Objects.hashCode(this.subtrahend); + hash = 31 * hash + subtrahend; return hash; } @@ -64,10 +77,12 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final IntegerSubtractModification other = (IntegerSubtractModification) obj; - if (!Objects.equals(this.subtrahend, other.subtrahend)) { - return false; - } - return true; + IntegerSubtractModification other = (IntegerSubtractModification) obj; + return Objects.equals(subtrahend, other.subtrahend); + } + + @Override + public String toString() { + return "IntegerSubtractModification{" + "subtrahend=" + subtrahend + '}'; } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerSwapEndianModification.java b/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerSwapEndianModification.java new file mode 100644 index 00000000..601b9abd --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerSwapEndianModification.java @@ -0,0 +1,64 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.integer; + +import de.rub.nds.modifiablevariable.VariableModification; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; + +@XmlRootElement +@XmlType(propOrder = "modificationFilter") +public class IntegerSwapEndianModification extends VariableModification { + + public IntegerSwapEndianModification() { + super(); + } + + public IntegerSwapEndianModification(IntegerSwapEndianModification other) { + super(other); + } + + @Override + public IntegerSwapEndianModification createCopy() { + return new IntegerSwapEndianModification(this); + } + + @Override + protected Integer modifyImplementationHook(Integer input) { + if (input == null) { + return null; + } + return Integer.reverseBytes(input); + } + + @Override + public VariableModification getModifiedCopy() { + return new IntegerSwapEndianModification(); + } + + @Override + public int hashCode() { + return 7; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + return getClass() == obj.getClass(); + } + + @Override + public String toString() { + return "IntegerSwapEndianModification{" + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerXorModification.java b/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerXorModification.java index b91a6e1f..d33f6fc3 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerXorModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/integer/IntegerXorModification.java @@ -21,15 +21,28 @@ public class IntegerXorModification extends VariableModification { private Integer xor; - public IntegerXorModification() {} + public IntegerXorModification() { + super(); + } + + public IntegerXorModification(Integer xor) { + super(); + this.xor = xor; + } + + public IntegerXorModification(IntegerXorModification other) { + super(other); + xor = other.xor; + } - public IntegerXorModification(Integer bi) { - this.xor = bi; + @Override + public IntegerXorModification createCopy() { + return new IntegerXorModification(this); } @Override - protected Integer modifyImplementationHook(final Integer input) { - return (input == null) ? xor : input ^ xor; + protected Integer modifyImplementationHook(Integer input) { + return input == null ? xor : input ^ xor; } public Integer getXor() { @@ -44,16 +57,16 @@ public void setXor(Integer xor) { public VariableModification getModifiedCopy() { Random r = new Random(); if (r.nextBoolean()) { - return new IntegerSubtractModification(xor + new Random().nextInt(MAX_VALUE_MODIFIER)); + return new IntegerXorModification(xor + new Random().nextInt(MAX_VALUE_MODIFIER)); } else { - return new IntegerSubtractModification(xor - new Random().nextInt(MAX_VALUE_MODIFIER)); + return new IntegerXorModification(xor - new Random().nextInt(MAX_VALUE_MODIFIER)); } } @Override public int hashCode() { - int hash = 3; - hash = 97 * hash + Objects.hashCode(this.xor); + int hash = 7; + hash = 31 * hash + xor; return hash; } @@ -68,10 +81,12 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final IntegerXorModification other = (IntegerXorModification) obj; - if (!Objects.equals(this.xor, other.xor)) { - return false; - } - return true; + IntegerXorModification other = (IntegerXorModification) obj; + return Objects.equals(xor, other.xor); + } + + @Override + public String toString() { + return "IntegerXorModification{" + "xor=" + xor + '}'; } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/integer/ModifiableInteger.java b/src/main/java/de/rub/nds/modifiablevariable/integer/ModifiableInteger.java index e3daeb21..d9612ec3 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/integer/ModifiableInteger.java +++ b/src/main/java/de/rub/nds/modifiablevariable/integer/ModifiableInteger.java @@ -20,8 +20,27 @@ public class ModifiableInteger extends ModifiableVariable { private Integer originalValue; + public ModifiableInteger() { + super(); + } + + public ModifiableInteger(Integer originalValue) { + super(); + this.originalValue = originalValue; + } + + public ModifiableInteger(ModifiableInteger other) { + super(other); + originalValue = other.originalValue; + } + + @Override + public ModifiableInteger createCopy() { + return new ModifiableInteger(this); + } + @Override - protected void createRandomModification() { + public void setRandomModification() { VariableModification vm = IntegerModificationFactory.createRandomModification(); setModification(vm); } @@ -66,19 +85,19 @@ public void setOriginalValue(Integer originalValue) { @Override public String toString() { - return "ModifiableInteger{" + "originalValue=" + originalValue + '}'; + return "ModifiableInteger{" + "originalValue=" + originalValue + innerToString() + '}'; } @Override - public boolean equals(Object o) { - if (this == o) { + public boolean equals(Object obj) { + if (this == obj) { return true; } - if (!(o instanceof ModifiableInteger)) { + if (!(obj instanceof ModifiableInteger)) { return false; } - ModifiableInteger that = (ModifiableInteger) o; + ModifiableInteger that = (ModifiableInteger) obj; return getValue() != null ? getValue().equals(that.getValue()) : that.getValue() == null; } diff --git a/src/main/java/de/rub/nds/modifiablevariable/length/ModifiableLengthField.java b/src/main/java/de/rub/nds/modifiablevariable/length/ModifiableLengthField.java index f54b99e4..0afcfe2d 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/length/ModifiableLengthField.java +++ b/src/main/java/de/rub/nds/modifiablevariable/length/ModifiableLengthField.java @@ -20,9 +20,20 @@ public class ModifiableLengthField extends ModifiableInteger { private final ModifiableByteArray ref; public ModifiableLengthField(ModifiableByteArray ref) { + super(); this.ref = ref; } + public ModifiableLengthField(ModifiableLengthField other) { + super(other); + ref = other.ref; + } + + @Override + public ModifiableLengthField createCopy() { + return new ModifiableLengthField(this); + } + @Override public Integer getOriginalValue() { return ref.getValue().length; @@ -36,19 +47,19 @@ public void setOriginalValue(Integer originalValue) { @Override public String toString() { - return "ModifiableLengthField{" + "ref=" + ref + "} " + super.toString(); + return "ModifiableLengthField{" + "ref=" + ref + super.toString() + "} "; } @Override - public boolean equals(Object o) { - if (this == o) { + public boolean equals(Object obj) { + if (this == obj) { return true; } - if (!(o instanceof ModifiableLengthField)) { + if (!(obj instanceof ModifiableLengthField)) { return false; } - ModifiableLengthField that = (ModifiableLengthField) o; + ModifiableLengthField that = (ModifiableLengthField) obj; return ref != null ? getValue().equals(that.getValue()) : that.getValue() == null; } diff --git a/src/main/java/de/rub/nds/modifiablevariable/logging/ExtendedPatternLayout.java b/src/main/java/de/rub/nds/modifiablevariable/logging/ExtendedPatternLayout.java index 36475e7b..e35a58e9 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/logging/ExtendedPatternLayout.java +++ b/src/main/java/de/rub/nds/modifiablevariable/logging/ExtendedPatternLayout.java @@ -39,7 +39,7 @@ category = "Core", elementType = "layout", printObject = true) -public class ExtendedPatternLayout extends AbstractStringLayout { +public final class ExtendedPatternLayout extends AbstractStringLayout { public static final String DEFAULT_CONVERSION_PATTERN = "%m%n"; public static final String TTCC_CONVERSION_PATTERN = "%r [%t] %p %c %notEmpty{%x }- %m%n"; public static final String SIMPLE_CONVERSION_PATTERN = "%d [%t] %p %c - %m%n"; @@ -80,9 +80,9 @@ private ExtendedPatternLayout( .setNoConsoleNoAnsi(noConsoleNoAnsi) .setPattern(footerPattern) .build()); - this.conversionPattern = eventPattern; + conversionPattern = eventPattern; this.patternSelector = patternSelector; - this.eventSerializer = + eventSerializer = newSerializerBuilder() .setConfiguration(config) .setReplace(replace) @@ -101,8 +101,8 @@ public static ExtendedPatternLayout.SerializerBuilder newSerializerBuilder() { @Override public boolean requiresLocation() { - return this.eventSerializer instanceof LocationAware - && ((LocationAware) this.eventSerializer).requiresLocation(); + return eventSerializer instanceof LocationAware + && ((LocationAware) eventSerializer).requiresLocation(); } /** @@ -129,7 +129,7 @@ public static AbstractStringLayout.Serializer createSerializer( } public String getConversionPattern() { - return this.conversionPattern; + return conversionPattern; } @Override @@ -137,32 +137,32 @@ public Map getContentFormat() { Map result = new HashMap<>(); result.put("structured", "false"); result.put("formatType", "conversion"); - result.put("format", this.conversionPattern); + result.put("format", conversionPattern); return result; } @Override public String toSerializable(LogEvent event) { - return this.eventSerializer.toSerializable(event); + return eventSerializer.toSerializable(event); } public void serialize(LogEvent event, StringBuilder stringBuilder) { - this.eventSerializer.toSerializable(event, stringBuilder); + eventSerializer.toSerializable(event, stringBuilder); } @Override public void encode(LogEvent event, ByteBufferDestination destination) { - if (this.eventSerializer == null) { + if (eventSerializer == null) { super.encode(event, destination); } else { - StringBuilder text = this.toText(this.eventSerializer, event, getStringBuilder()); - Encoder encoder = this.getStringBuilderEncoder(); + StringBuilder text = toText(eventSerializer, event, getStringBuilder()); + Encoder encoder = getStringBuilderEncoder(); encoder.encode(text, destination); trimToMaxSize(text); } } - private StringBuilder toText( + private static StringBuilder toText( AbstractStringLayout.Serializer2 serializer, LogEvent event, StringBuilder destination) { @@ -171,7 +171,7 @@ private StringBuilder toText( public static PatternParser createPatternParser(Configuration config) { if (config == null) { - return new PatternParser(config, "Converter", LogEventPatternConverter.class); + return new PatternParser(null, "Converter", LogEventPatternConverter.class); } else { PatternParser parser = config.getComponent("Converter"); if (parser == null) { @@ -186,9 +186,7 @@ public static PatternParser createPatternParser(Configuration config) { @Override public String toString() { - return this.patternSelector == null - ? this.conversionPattern - : this.patternSelector.toString(); + return patternSelector == null ? conversionPattern : patternSelector.toString(); } /** @@ -234,10 +232,10 @@ public static ExtendedPatternLayout.Builder newBuilder() { } public AbstractStringLayout.Serializer getEventSerializer() { - return this.eventSerializer; + return eventSerializer; } - public static class Builder + public static final class Builder implements org.apache.logging.log4j.core.util.Builder { @PluginBuilderAttribute private String pattern; @@ -263,13 +261,14 @@ public static class Builder private static boolean prettyPrinting; private Builder() { - this.pattern = "%m%n"; - this.charset = Charset.defaultCharset(); - this.alwaysWriteExceptions = true; - this.disableAnsi = !this.useAnsiEscapeCodes(); + super(); + pattern = "%m%n"; + charset = Charset.defaultCharset(); + alwaysWriteExceptions = true; + disableAnsi = !useAnsiEscapeCodes(); } - private boolean useAnsiEscapeCodes() { + private static boolean useAnsiEscapeCodes() { PropertiesUtil propertiesUtil = PropertiesUtil.getProperties(); boolean isPlatformSupportsAnsi = !propertiesUtil.isOsWindows(); boolean isJansiRequested = !propertiesUtil.getBooleanProperty("log4j.skipJansi", true); @@ -333,78 +332,79 @@ public ExtendedPatternLayout.Builder withFooter(String footer) { @Override public ExtendedPatternLayout build() { - if (this.configuration == null) { - this.configuration = new DefaultConfiguration(); + if (configuration == null) { + configuration = new DefaultConfiguration(); } return new ExtendedPatternLayout( - this.configuration, - this.regexReplacement, - this.pattern, - this.patternSelector, - this.charset, - this.alwaysWriteExceptions, - this.disableAnsi, - this.noConsoleNoAnsi, - this.header, - this.footer); + configuration, + regexReplacement, + pattern, + patternSelector, + charset, + alwaysWriteExceptions, + disableAnsi, + noConsoleNoAnsi, + header, + footer); } } - private static class PatternSelectorSerializer + private static final class PatternSelectorSerializer implements AbstractStringLayout.Serializer, LocationAware { private final PatternSelector patternSelector; private final RegexReplacement replace; private PatternSelectorSerializer( PatternSelector patternSelector, RegexReplacement replace) { + super(); this.patternSelector = patternSelector; this.replace = replace; } @Override public String toSerializable(LogEvent event) { - StringBuilder sb = AbstractStringLayout.getStringBuilder(); + StringBuilder sb = getStringBuilder(); String var3; try { - var3 = this.toSerializable(event, sb).toString(); + var3 = toSerializable(event, sb).toString(); } finally { - AbstractStringLayout.trimToMaxSize(sb); + trimToMaxSize(sb); } return var3; } @Override - public StringBuilder toSerializable(LogEvent event, StringBuilder buffer) { - PatternFormatter[] formatters = this.patternSelector.getFormatters(event); - Arrays.stream(formatters).forEachOrdered(formatter -> formatter.format(event, buffer)); - - if (this.replace != null) { - String str = buffer.toString(); - str = this.replace.format(str); - buffer.setLength(0); - buffer.append(str); + public StringBuilder toSerializable(LogEvent event, StringBuilder builder) { + PatternFormatter[] formatters = patternSelector.getFormatters(event); + Arrays.stream(formatters).forEachOrdered(formatter -> formatter.format(event, builder)); + + if (replace != null) { + String str = builder.toString(); + str = replace.format(str); + builder.setLength(0); + builder.append(str); } - return buffer; + return builder; } @Override public boolean requiresLocation() { - return this.patternSelector instanceof LocationAware - && ((LocationAware) this.patternSelector).requiresLocation(); + return patternSelector instanceof LocationAware + && ((LocationAware) patternSelector).requiresLocation(); } @Override public String toString() { return super.toString() - .concat("[patternSelector=") - .concat(this.patternSelector.toString()) - .concat(", replace=") - .concat(this.replace.toString()) - .concat("]"); + + "[patternSelector=" + + patternSelector.toString() + + ", replace=" + + replace.toString() + + "]"; } } @@ -421,28 +421,27 @@ public static class SerializerBuilder @Override public AbstractStringLayout.Serializer build() { - if (Strings.isEmpty(this.pattern) && Strings.isEmpty(this.defaultPattern)) { + if (Strings.isEmpty(pattern) && Strings.isEmpty(defaultPattern)) { return null; - } else if (this.patternSelector == null) { + } else if (patternSelector == null) { try { - PatternParser parser = - ExtendedPatternLayout.createPatternParser(this.configuration); + PatternParser parser = createPatternParser(configuration); List list = parser.parse( - this.pattern == null ? this.defaultPattern : this.pattern, - this.alwaysWriteExceptions, - this.disableAnsi, - this.noConsoleNoAnsi); + pattern == null ? defaultPattern : pattern, + alwaysWriteExceptions, + disableAnsi, + noConsoleNoAnsi); PatternFormatter[] formatters = list.toArray(new PatternFormatter[0]); return new ExtendedPatternLayout.ExtendedPatternLayoutSerializer( - formatters, this.replace); + formatters, replace); } catch (RuntimeException var4) { throw new IllegalArgumentException( - "Cannot parse pattern '" + this.pattern + "'", var4); + "Cannot parse pattern '" + pattern + "'", var4); } } else { return new ExtendedPatternLayout.PatternSelectorSerializer( - this.patternSelector, this.replace); + patternSelector, replace); } } @@ -490,39 +489,40 @@ public ExtendedPatternLayout.SerializerBuilder setNoConsoleNoAnsi(boolean noCons } } - private static class ExtendedPatternLayoutSerializer + private static final class ExtendedPatternLayoutSerializer implements AbstractStringLayout.Serializer, LocationAware { private final PatternFormatter[] formatters; private final RegexReplacement replace; private ExtendedPatternLayoutSerializer( PatternFormatter[] formatters, RegexReplacement replace) { + super(); this.formatters = formatters; this.replace = replace; } @Override public String toSerializable(LogEvent event) { - StringBuilder sb = AbstractStringLayout.getStringBuilder(); + StringBuilder sb = getStringBuilder(); String var3; try { - var3 = this.toSerializable(event, sb).toString(); + var3 = toSerializable(event, sb).toString(); } finally { - AbstractStringLayout.trimToMaxSize(sb); + trimToMaxSize(sb); } return var3; } @Override - public StringBuilder toSerializable(LogEvent event, StringBuilder buffer) { - Arrays.stream(formatters).forEachOrdered(formatter -> formatter.format(event, buffer)); - - if (this.replace != null) { - String str = buffer.toString(); - str = this.replace.format(str); - buffer.setLength(0); - buffer.append(str); + public StringBuilder toSerializable(LogEvent event, StringBuilder builder) { + Arrays.stream(formatters).forEachOrdered(formatter -> formatter.format(event, builder)); + + if (replace != null) { + String str = builder.toString(); + str = replace.format(str); + builder.setLength(0); + builder.append(str); } // Added section to parse ByteArrays to the correct output format. @@ -538,9 +538,9 @@ public StringBuilder toSerializable(LogEvent event, StringBuilder buffer) { // calculated // by the ArrayConverter. if (param != null && bArrayClass.equals(param.getClass())) { - buffer.replace( - buffer.indexOf(Arrays.toString((byte[]) param)), - buffer.indexOf(Arrays.toString((byte[]) param)) + builder.replace( + builder.indexOf(Arrays.toString((byte[]) param)), + builder.indexOf(Arrays.toString((byte[]) param)) + Arrays.toString((byte[]) param).length(), ArrayConverter.bytesToHexString( (byte[]) param, @@ -549,21 +549,21 @@ public StringBuilder toSerializable(LogEvent event, StringBuilder buffer) { } } } - return buffer; + return builder; } public boolean requiresLocation() { - return Arrays.stream(this.formatters).anyMatch(PatternFormatter::requiresLocation); + return Arrays.stream(formatters).anyMatch(PatternFormatter::requiresLocation); } @Override public String toString() { return super.toString() - .concat("[formatters=") - .concat(Arrays.toString(this.formatters)) - .concat(", replace=") - .concat(this.replace.toString()) - .concat("]"); + + "[formatters=" + + Arrays.toString(formatters) + + ", replace=" + + replace.toString() + + "]"; } } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/longint/LongAddModification.java b/src/main/java/de/rub/nds/modifiablevariable/longint/LongAddModification.java index 6f89d677..a42604f4 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/longint/LongAddModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/longint/LongAddModification.java @@ -21,15 +21,28 @@ public class LongAddModification extends VariableModification { private Long summand; - public LongAddModification() {} + public LongAddModification() { + super(); + } + + public LongAddModification(Long summand) { + super(); + this.summand = summand; + } + + public LongAddModification(LongAddModification other) { + super(other); + summand = other.summand; + } - public LongAddModification(Long bi) { - this.summand = bi; + @Override + public LongAddModification createCopy() { + return new LongAddModification(this); } @Override - protected Long modifyImplementationHook(final Long input) { - return (input == null) ? summand : input + summand; + protected Long modifyImplementationHook(Long input) { + return input == null ? summand : input + summand; } public Long getSummand() { @@ -48,7 +61,7 @@ public VariableModification getModifiedCopy() { @Override public int hashCode() { int hash = 7; - hash = 43 * hash + Objects.hashCode(this.summand); + hash = 31 * hash + summand.hashCode(); return hash; } @@ -63,10 +76,12 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final LongAddModification other = (LongAddModification) obj; - if (!Objects.equals(this.summand, other.summand)) { - return false; - } - return true; + LongAddModification other = (LongAddModification) obj; + return Objects.equals(summand, other.summand); + } + + @Override + public String toString() { + return "LongAddModification{" + "summand=" + summand + '}'; } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/longint/LongAppendValueModification.java b/src/main/java/de/rub/nds/modifiablevariable/longint/LongAppendValueModification.java new file mode 100644 index 00000000..b6f05442 --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/longint/LongAppendValueModification.java @@ -0,0 +1,91 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.longint; + +import de.rub.nds.modifiablevariable.VariableModification; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import java.util.Objects; +import java.util.Random; + +@XmlRootElement +@XmlType(propOrder = {"appendValue", "modificationFilter"}) +public class LongAppendValueModification extends VariableModification { + + private static final int MAX_VALUE_MODIFIER = 256; + + private Long appendValue; + + public LongAppendValueModification() { + super(); + } + + public LongAppendValueModification(Long appendValue) { + super(); + this.appendValue = appendValue; + } + + public LongAppendValueModification(LongAppendValueModification other) { + super(other); + appendValue = other.appendValue; + } + + @Override + public LongAppendValueModification createCopy() { + return new LongAppendValueModification(this); + } + + @Override + protected Long modifyImplementationHook(Long input) { + if (input == null) { + input = 0L; + } + return input << Long.SIZE - Long.numberOfLeadingZeros(appendValue) | appendValue; + } + + public Long getAppendValue() { + return appendValue; + } + + public void setAppendValue(Long appendValue) { + this.appendValue = appendValue; + } + + @Override + public VariableModification getModifiedCopy() { + return new LongAppendValueModification( + appendValue + new Random().nextInt(MAX_VALUE_MODIFIER)); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + appendValue.hashCode(); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + LongAppendValueModification other = (LongAppendValueModification) obj; + return Objects.equals(appendValue, other.appendValue); + } + + @Override + public String toString() { + return "LongAppendValueModification{" + "appendValue=" + appendValue + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/longint/LongExplicitValueFromFileModification.java b/src/main/java/de/rub/nds/modifiablevariable/longint/LongExplicitValueFromFileModification.java new file mode 100644 index 00000000..9635702d --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/longint/LongExplicitValueFromFileModification.java @@ -0,0 +1,87 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.longint; + +import de.rub.nds.modifiablevariable.VariableModification; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import java.util.Objects; + +@XmlRootElement +@XmlType(propOrder = "index") +@XmlAccessorType(XmlAccessType.FIELD) +public class LongExplicitValueFromFileModification extends LongExplicitValueModification { + private int index; + + public LongExplicitValueFromFileModification() { + super(); + } + + public LongExplicitValueFromFileModification(int index, Long explicitValue) { + super(explicitValue); + this.index = index; + } + + public LongExplicitValueFromFileModification(LongExplicitValueFromFileModification other) { + super(other); + index = other.index; + } + + @Override + public LongExplicitValueFromFileModification createCopy() { + return new LongExplicitValueFromFileModification(this); + } + + public int getIndex() { + return index; + } + + @Override + public VariableModification getModifiedCopy() { + throw new UnsupportedOperationException( + "Cannot set modify Value of LongExplicitValueFromFileModification"); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + index; + hash = 31 * hash + explicitValue.hashCode(); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + LongExplicitValueFromFileModification other = (LongExplicitValueFromFileModification) obj; + if (index != other.index) { + return false; + } + return Objects.equals(explicitValue, other.explicitValue); + } + + @Override + public String toString() { + return "LongExplicitValueFromFileModification{" + + "index=" + + index + + ", explicitValue=" + + explicitValue + + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/longint/LongExplicitValueModification.java b/src/main/java/de/rub/nds/modifiablevariable/longint/LongExplicitValueModification.java index d8136779..a52d08ed 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/longint/LongExplicitValueModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/longint/LongExplicitValueModification.java @@ -19,16 +19,29 @@ public class LongExplicitValueModification extends VariableModification { private static final int MAX_EXPLICIT_MODIFIER = 256; - private Long explicitValue; + protected Long explicitValue; - public LongExplicitValueModification() {} + public LongExplicitValueModification() { + super(); + } + + public LongExplicitValueModification(Long explicitValue) { + super(); + this.explicitValue = explicitValue; + } + + public LongExplicitValueModification(LongExplicitValueModification other) { + super(other); + explicitValue = other.explicitValue; + } - public LongExplicitValueModification(Long bi) { - this.explicitValue = bi; + @Override + public LongExplicitValueModification createCopy() { + return new LongExplicitValueModification(this); } @Override - protected Long modifyImplementationHook(final Long input) { + protected Long modifyImplementationHook(Long input) { return explicitValue; } @@ -54,8 +67,8 @@ public VariableModification getModifiedCopy() { @Override public int hashCode() { - int hash = 3; - hash = 43 * hash + Objects.hashCode(this.explicitValue); + int hash = 7; + hash = 31 * hash + explicitValue.hashCode(); return hash; } @@ -70,10 +83,12 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final LongExplicitValueModification other = (LongExplicitValueModification) obj; - if (!Objects.equals(this.explicitValue, other.explicitValue)) { - return false; - } - return true; + LongExplicitValueModification other = (LongExplicitValueModification) obj; + return Objects.equals(explicitValue, other.explicitValue); + } + + @Override + public String toString() { + return "LongExplicitValueModification{" + "explicitValue=" + explicitValue + '}'; } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/longint/LongInsertValueModification.java b/src/main/java/de/rub/nds/modifiablevariable/longint/LongInsertValueModification.java new file mode 100644 index 00000000..3eb30715 --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/longint/LongInsertValueModification.java @@ -0,0 +1,138 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.longint; + +import de.rub.nds.modifiablevariable.VariableModification; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import java.util.Objects; +import java.util.Random; + +@XmlRootElement +@XmlType(propOrder = {"insertValue", "startPosition", "modificationFilter"}) +public class LongInsertValueModification extends VariableModification { + + private static final int MAX_VALUE_MODIFIER = 256; + private static final int MAX_POSITION_MODIFIER = 32; + + private Long insertValue; + private int startPosition; + + public LongInsertValueModification() { + super(); + } + + public LongInsertValueModification(Long insertValue, int startPosition) { + super(); + this.insertValue = insertValue; + this.startPosition = startPosition; + } + + public LongInsertValueModification(LongInsertValueModification other) { + super(other); + insertValue = other.insertValue; + startPosition = other.startPosition; + } + + @Override + public LongInsertValueModification createCopy() { + return new LongInsertValueModification(this); + } + + @Override + protected Long modifyImplementationHook(Long input) { + if (input == null) { + input = 0L; + } + + int insertValueLength = Long.SIZE - Long.numberOfLeadingZeros(insertValue); + + // Wrap around long size + int insertPosition = startPosition % Long.SIZE; + if (startPosition < 0) { + insertPosition += Long.SIZE - 1; + } + + long mask = (1L << insertPosition) - 1; + + return (input >> insertPosition << insertValueLength | insertValue) << insertPosition + | mask & input; + } + + public Long getInsertValue() { + return insertValue; + } + + public void setInsertValue(Long insertValue) { + this.insertValue = insertValue; + } + + public int getStartPosition() { + return startPosition; + } + + public void setStartPosition(int startPosition) { + this.startPosition = startPosition; + } + + @Override + public VariableModification getModifiedCopy() { + Random r = new Random(); + + if (r.nextBoolean()) { + return new LongInsertValueModification( + insertValue + r.nextInt(MAX_VALUE_MODIFIER), startPosition); + } else { + int modifier = r.nextInt(MAX_POSITION_MODIFIER); + if (r.nextBoolean()) { + modifier *= -1; + } + modifier = startPosition + modifier; + if (modifier <= 0) { + modifier = 1; + } + return new LongInsertValueModification(insertValue, modifier); + } + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + insertValue.hashCode(); + hash = 31 * hash + startPosition; + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + LongInsertValueModification other = (LongInsertValueModification) obj; + if (startPosition != other.startPosition) { + return false; + } + return Objects.equals(insertValue, other.insertValue); + } + + @Override + public String toString() { + return "LongInsertValueModification{" + + "insertValue=" + + insertValue + + ", startPosition=" + + startPosition + + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/longint/LongModificationFactory.java b/src/main/java/de/rub/nds/modifiablevariable/longint/LongModificationFactory.java index bbfd4f09..546db557 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/longint/LongModificationFactory.java +++ b/src/main/java/de/rub/nds/modifiablevariable/longint/LongModificationFactory.java @@ -15,68 +15,125 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.util.LinkedList; +import java.util.ArrayList; import java.util.List; import java.util.Random; -public class LongModificationFactory { +public final class LongModificationFactory { + + private enum ModificationType { + ADD, + SUBTRACT, + MULTIPLY, + XOR, + SWAP_ENDIAN, + EXPLICIT, + SHIFT_LEFT, + SHIFT_RIGHT, + EXPLICIT_FROM_FILE, + APPEND, + INSERT, + PREPEND + } - private static final int MODIFICATION_COUNT = 5; + private static final int MODIFICATION_COUNT = ModificationType.values().length; private static final int MAX_MODIFICATION_VALUE = 32000; + private static final int MAX_FILE_ENTRIES = 200; + + private static final int MAX_MODIFICATION_SHIFT_VALUE = 40; + + private static final int MAX_MODIFICATION_MULTIPLY_VALUE = 256; + + private static final int MAX_MODIFICATION_INSERT_VALUE = 256; + + private static final int MAX_MODIFICATION_INSERT_POSITION_VALUE = 64; + private static List> modificationsFromFile; - public static LongAddModification add(final String summand) { + public static final String FILE_NAME = "de/rub/nds/modifiablevariable/explicit/long.vec"; + + public static LongAddModification add(String summand) { return add(Long.parseLong(summand)); } - public static LongAddModification add(final Long summand) { + public static LongAddModification add(Long summand) { return new LongAddModification(summand); } - public static VariableModification sub(final String subtrahend) { + public static VariableModification sub(String subtrahend) { return sub(Long.parseLong(subtrahend)); } - public static VariableModification sub(final Long subtrahend) { + public static VariableModification sub(Long subtrahend) { return new LongSubtractModification(subtrahend); } - public static VariableModification xor(final String xor) { + public static VariableModification xor(String xor) { return xor(Long.parseLong(xor)); } - public static VariableModification xor(final Long xor) { + public static VariableModification xor(Long xor) { return new LongXorModification(xor); } - public static VariableModification explicitValue(final String value) { + public static VariableModification swapEndian() { + return new LongSwapEndianModification(); + } + + public static VariableModification explicitValue(String value) { return explicitValue(Long.parseLong(value)); } - public static VariableModification explicitValue(final Long value) { + public static VariableModification explicitValue(Long value) { return new LongExplicitValueModification(value); } - public static VariableModification explicitValueFromFile(int value) { + public static VariableModification explicitValueFromFile(int pos) { List> modifications = modificationsFromFile(); - int pos = value % modifications.size(); - return modifications.get(pos); + return modifications.get(pos % modifications.size()); + } + + public static VariableModification appendValue(Long value) { + return new LongAppendValueModification(value); + } + + public static VariableModification insertValue(Long value, int position) { + return new LongInsertValueModification(value, position); + } + + public static VariableModification prependValue(Long value) { + return new LongPrependValueModification(value); + } + + public static VariableModification multiply(Long factor) { + return new LongMultiplyModification(factor); + } + + public static VariableModification shiftLeft(int shift) { + return new LongShiftLeftModification(shift); + } + + public static VariableModification shiftRight(int shift) { + return new LongShiftRightModification(shift); } public static synchronized List> modificationsFromFile() { try { if (modificationsFromFile == null) { - modificationsFromFile = new LinkedList<>(); + modificationsFromFile = new ArrayList<>(); ClassLoader classLoader = IntegerModificationFactory.class.getClassLoader(); - InputStream is = - classLoader.getResourceAsStream(IntegerModificationFactory.FILE_NAME); + InputStream is = classLoader.getResourceAsStream(FILE_NAME); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String line; + int index = 0; while ((line = br.readLine()) != null) { String value = line.trim().split(" ")[0]; - modificationsFromFile.add(explicitValue(value)); + modificationsFromFile.add( + new LongExplicitValueFromFileModification( + index, Long.parseLong(value))); + index++; } } return modificationsFromFile; @@ -88,29 +145,44 @@ public static synchronized List> modificationsFromFil public static VariableModification createRandomModification() { Random random = RandomHelper.getRandom(); - int r = random.nextInt(MODIFICATION_COUNT); + ModificationType randomType = ModificationType.values()[random.nextInt(MODIFICATION_COUNT)]; long modification = random.nextInt(MAX_MODIFICATION_VALUE); - VariableModification vm = null; - switch (r) { - case 0: - vm = new LongAddModification(modification); - return vm; - case 1: - vm = new LongSubtractModification(modification); - return vm; - case 2: - vm = new LongXorModification(modification); - return vm; - case 3: - vm = new LongExplicitValueModification(modification); - return vm; - case 4: - vm = explicitValueFromFile(random.nextInt(MAX_MODIFICATION_VALUE)); - return vm; + long insert_modification = random.nextInt(MAX_MODIFICATION_INSERT_VALUE); + int shiftModification = random.nextInt(MAX_MODIFICATION_SHIFT_VALUE); + switch (randomType) { + case ADD: + return new LongAddModification(modification); + case SUBTRACT: + return new LongSubtractModification(modification); + case MULTIPLY: + return new LongMultiplyModification( + (long) random.nextInt(MAX_MODIFICATION_MULTIPLY_VALUE)); + case XOR: + return new LongXorModification(modification); + case SWAP_ENDIAN: + return new LongSwapEndianModification(); + case EXPLICIT: + return new LongExplicitValueModification(modification); + case SHIFT_LEFT: + return new LongShiftLeftModification(shiftModification); + case SHIFT_RIGHT: + return new LongShiftRightModification(shiftModification); + case EXPLICIT_FROM_FILE: + return explicitValueFromFile(random.nextInt(MAX_FILE_ENTRIES)); + case APPEND: + return new LongAppendValueModification(insert_modification); + case INSERT: + return new LongInsertValueModification( + insert_modification, + random.nextInt(MAX_MODIFICATION_INSERT_POSITION_VALUE)); + case PREPEND: + return new LongPrependValueModification(insert_modification); default: - return vm; + throw new IllegalStateException("Unexpected modification type: " + randomType); } } - private LongModificationFactory() {} + private LongModificationFactory() { + super(); + } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/longint/LongMultiplyModification.java b/src/main/java/de/rub/nds/modifiablevariable/longint/LongMultiplyModification.java new file mode 100644 index 00000000..180f96b3 --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/longint/LongMultiplyModification.java @@ -0,0 +1,87 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.longint; + +import de.rub.nds.modifiablevariable.VariableModification; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import java.util.Objects; +import java.util.Random; + +@XmlRootElement +@XmlType(propOrder = {"factor", "modificationFilter"}) +public class LongMultiplyModification extends VariableModification { + + private static final int MAX_FACTOR_MODIFIER = 256; + + private Long factor; + + public LongMultiplyModification() { + super(); + } + + public LongMultiplyModification(Long factor) { + super(); + this.factor = factor; + } + + public LongMultiplyModification(LongMultiplyModification other) { + super(other); + factor = other.factor; + } + + @Override + public LongMultiplyModification createCopy() { + return new LongMultiplyModification(this); + } + + @Override + protected Long modifyImplementationHook(Long input) { + return input == null ? 0L : input * factor; + } + + public Long getFactor() { + return factor; + } + + public void setFactor(Long factor) { + this.factor = factor; + } + + @Override + public VariableModification getModifiedCopy() { + return new LongMultiplyModification(factor + new Random().nextInt(MAX_FACTOR_MODIFIER)); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + factor.hashCode(); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + LongMultiplyModification other = (LongMultiplyModification) obj; + return Objects.equals(factor, other.factor); + } + + @Override + public String toString() { + return "LongMultiplyModification{" + "factor=" + factor + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/longint/LongPrependValueModification.java b/src/main/java/de/rub/nds/modifiablevariable/longint/LongPrependValueModification.java new file mode 100644 index 00000000..484d710c --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/longint/LongPrependValueModification.java @@ -0,0 +1,91 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.longint; + +import de.rub.nds.modifiablevariable.VariableModification; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import java.util.Objects; +import java.util.Random; + +@XmlRootElement +@XmlType(propOrder = {"prependValue", "modificationFilter"}) +public class LongPrependValueModification extends VariableModification { + + private static final int MAX_VALUE_MODIFIER = 256; + + private Long prependValue; + + public LongPrependValueModification() { + super(); + } + + public LongPrependValueModification(Long prependValue) { + super(); + this.prependValue = prependValue; + } + + public LongPrependValueModification(LongPrependValueModification other) { + super(other); + prependValue = other.prependValue; + } + + @Override + public LongPrependValueModification createCopy() { + return new LongPrependValueModification(this); + } + + @Override + protected Long modifyImplementationHook(Long input) { + if (input == null) { + input = 0L; + } + return prependValue << Long.SIZE - Long.numberOfLeadingZeros(input) | input; + } + + public Long getPrependValue() { + return prependValue; + } + + public void setPrependValue(Long prependValue) { + this.prependValue = prependValue; + } + + @Override + public VariableModification getModifiedCopy() { + return new LongPrependValueModification( + prependValue + new Random().nextInt(MAX_VALUE_MODIFIER)); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + prependValue.hashCode(); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + LongPrependValueModification other = (LongPrependValueModification) obj; + return Objects.equals(prependValue, other.prependValue); + } + + @Override + public String toString() { + return "LongPrependValueModification{" + "prependValue=" + prependValue + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/longint/LongShiftLeftModification.java b/src/main/java/de/rub/nds/modifiablevariable/longint/LongShiftLeftModification.java new file mode 100644 index 00000000..2d479360 --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/longint/LongShiftLeftModification.java @@ -0,0 +1,100 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.longint; + +import de.rub.nds.modifiablevariable.VariableModification; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import java.util.Objects; +import java.util.Random; + +@XmlRootElement +@XmlType(propOrder = {"shift", "modificationFilter"}) +public class LongShiftLeftModification extends VariableModification { + + private static final int MAX_SHIFT_MODIFIER = 64; + + private int shift; + + public LongShiftLeftModification() { + super(); + } + + public LongShiftLeftModification(int shift) { + super(); + this.shift = shift; + } + + public LongShiftLeftModification(LongShiftLeftModification other) { + super(other); + shift = other.shift; + } + + @Override + public LongShiftLeftModification createCopy() { + return new LongShiftLeftModification(this); + } + + @Override + protected Long modifyImplementationHook(Long input) { + return input == null ? 0L : input << shift % MAX_SHIFT_MODIFIER; + } + + public int getShift() { + return shift; + } + + public void setShift(int shift) { + this.shift = shift; + } + + @Override + public VariableModification getModifiedCopy() { + Random r = new Random(); + int newShift; + if (r.nextBoolean()) { + newShift = shift + r.nextInt(MAX_SHIFT_MODIFIER); + } else { + newShift = shift - r.nextInt(MAX_SHIFT_MODIFIER); + } + if (newShift < 0) { + newShift = MAX_SHIFT_MODIFIER - 1; + } else if (newShift > MAX_SHIFT_MODIFIER - 1) { + newShift = 0; + } + + return new LongShiftLeftModification(newShift); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + shift; + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + LongShiftLeftModification other = (LongShiftLeftModification) obj; + return Objects.equals(shift, other.shift); + } + + @Override + public String toString() { + return "LongShiftLeftModification{" + "shift=" + shift + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/longint/LongShiftRightModification.java b/src/main/java/de/rub/nds/modifiablevariable/longint/LongShiftRightModification.java new file mode 100644 index 00000000..0f8b2cfe --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/longint/LongShiftRightModification.java @@ -0,0 +1,100 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.longint; + +import de.rub.nds.modifiablevariable.VariableModification; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import java.util.Objects; +import java.util.Random; + +@XmlRootElement +@XmlType(propOrder = {"shift", "modificationFilter"}) +public class LongShiftRightModification extends VariableModification { + + private static final int MAX_SHIFT_MODIFIER = 64; + + private int shift; + + public LongShiftRightModification() { + super(); + } + + public LongShiftRightModification(int shift) { + super(); + this.shift = shift; + } + + public LongShiftRightModification(LongShiftRightModification other) { + super(other); + shift = other.shift; + } + + @Override + public LongShiftRightModification createCopy() { + return new LongShiftRightModification(this); + } + + @Override + protected Long modifyImplementationHook(Long input) { + return input == null ? 0L : input >> shift % MAX_SHIFT_MODIFIER; + } + + public int getShift() { + return shift; + } + + public void setShift(int shift) { + this.shift = shift; + } + + @Override + public VariableModification getModifiedCopy() { + Random r = new Random(); + int newShift; + if (r.nextBoolean()) { + newShift = shift + r.nextInt(MAX_SHIFT_MODIFIER); + } else { + newShift = shift - r.nextInt(MAX_SHIFT_MODIFIER); + } + if (newShift < 0) { + newShift = MAX_SHIFT_MODIFIER - 1; + } else if (newShift > MAX_SHIFT_MODIFIER - 1) { + newShift = 0; + } + + return new LongShiftRightModification(newShift); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + shift; + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + LongShiftRightModification other = (LongShiftRightModification) obj; + return Objects.equals(shift, other.shift); + } + + @Override + public String toString() { + return "LongShiftRightModification{" + "shift=" + shift + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/longint/LongSubtractModification.java b/src/main/java/de/rub/nds/modifiablevariable/longint/LongSubtractModification.java index ba2f488d..2f04ac48 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/longint/LongSubtractModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/longint/LongSubtractModification.java @@ -21,15 +21,28 @@ public class LongSubtractModification extends VariableModification { private Long subtrahend; - public LongSubtractModification() {} + public LongSubtractModification() { + super(); + } + + public LongSubtractModification(Long subtrahend) { + super(); + this.subtrahend = subtrahend; + } + + public LongSubtractModification(LongSubtractModification other) { + super(other); + subtrahend = other.subtrahend; + } - public LongSubtractModification(Long bi) { - this.subtrahend = bi; + @Override + public LongSubtractModification createCopy() { + return new LongSubtractModification(this); } @Override - protected Long modifyImplementationHook(final Long input) { - return (input == null) ? -subtrahend : input - subtrahend; + protected Long modifyImplementationHook(Long input) { + return input == null ? -subtrahend : input - subtrahend; } public Long getSubtrahend() { @@ -49,7 +62,7 @@ public VariableModification getModifiedCopy() { @Override public int hashCode() { int hash = 7; - hash = 97 * hash + Objects.hashCode(this.subtrahend); + hash = 31 * hash + subtrahend.hashCode(); return hash; } @@ -64,10 +77,12 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final LongSubtractModification other = (LongSubtractModification) obj; - if (!Objects.equals(this.subtrahend, other.subtrahend)) { - return false; - } - return true; + LongSubtractModification other = (LongSubtractModification) obj; + return Objects.equals(subtrahend, other.subtrahend); + } + + @Override + public String toString() { + return "LongSubtractModification{" + "subtrahend=" + subtrahend + '}'; } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/longint/LongSwapEndianModification.java b/src/main/java/de/rub/nds/modifiablevariable/longint/LongSwapEndianModification.java new file mode 100644 index 00000000..980b4b8e --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/longint/LongSwapEndianModification.java @@ -0,0 +1,64 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.longint; + +import de.rub.nds.modifiablevariable.VariableModification; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; + +@XmlRootElement +@XmlType(propOrder = "modificationFilter") +public class LongSwapEndianModification extends VariableModification { + + public LongSwapEndianModification() { + super(); + } + + public LongSwapEndianModification(LongSwapEndianModification other) { + super(other); + } + + @Override + public LongSwapEndianModification createCopy() { + return new LongSwapEndianModification(this); + } + + @Override + protected Long modifyImplementationHook(Long input) { + if (input == null) { + return null; + } + return Long.reverseBytes(input); + } + + @Override + public VariableModification getModifiedCopy() { + return new LongSwapEndianModification(); + } + + @Override + public int hashCode() { + return 7; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + return getClass() == obj.getClass(); + } + + @Override + public String toString() { + return "LongSwapEndianModification{" + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/longint/LongXorModification.java b/src/main/java/de/rub/nds/modifiablevariable/longint/LongXorModification.java index c9755784..9407bed8 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/longint/LongXorModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/longint/LongXorModification.java @@ -21,15 +21,28 @@ public class LongXorModification extends VariableModification { private Long xor; - public LongXorModification() {} + public LongXorModification() { + super(); + } + + public LongXorModification(Long xor) { + super(); + this.xor = xor; + } + + public LongXorModification(LongXorModification other) { + super(other); + xor = other.xor; + } - public LongXorModification(Long bi) { - this.xor = bi; + @Override + public LongXorModification createCopy() { + return new LongXorModification(this); } @Override - protected Long modifyImplementationHook(final Long input) { - return (input == null) ? xor : input ^ xor; + protected Long modifyImplementationHook(Long input) { + return input == null ? xor : input ^ xor; } public Long getXor() { @@ -44,16 +57,16 @@ public void setXor(Long xor) { public VariableModification getModifiedCopy() { Random r = new Random(); if (r.nextBoolean()) { - return new LongXorModification(xor + new Random().nextInt(MAX_XOR_MODIFIER)); + return new LongXorModification(xor + r.nextInt(MAX_XOR_MODIFIER)); } else { - return new LongXorModification(xor - new Random().nextInt(MAX_XOR_MODIFIER)); + return new LongXorModification(xor - r.nextInt(MAX_XOR_MODIFIER)); } } @Override public int hashCode() { - int hash = 3; - hash = 59 * hash + Objects.hashCode(this.xor); + int hash = 7; + hash = 31 * hash + xor.hashCode(); return hash; } @@ -68,10 +81,12 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final LongXorModification other = (LongXorModification) obj; - if (!Objects.equals(this.xor, other.xor)) { - return false; - } - return true; + LongXorModification other = (LongXorModification) obj; + return Objects.equals(xor, other.xor); + } + + @Override + public String toString() { + return "LongXorModification{" + "xor=" + xor + '}'; } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/longint/ModifiableLong.java b/src/main/java/de/rub/nds/modifiablevariable/longint/ModifiableLong.java index 5e75ea3f..44c233a4 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/longint/ModifiableLong.java +++ b/src/main/java/de/rub/nds/modifiablevariable/longint/ModifiableLong.java @@ -20,8 +20,27 @@ public class ModifiableLong extends ModifiableVariable { private Long originalValue; + public ModifiableLong() { + super(); + } + + public ModifiableLong(Long originalValue) { + super(); + this.originalValue = originalValue; + } + + public ModifiableLong(ModifiableLong other) { + super(other); + originalValue = other.originalValue; + } + + @Override + public ModifiableLong createCopy() { + return new ModifiableLong(this); + } + @Override - protected void createRandomModification() { + public void setRandomModification() { VariableModification vm = LongModificationFactory.createRandomModification(); setModification(vm); } @@ -66,19 +85,19 @@ public void setOriginalValue(Long originalValue) { @Override public String toString() { - return "ModifiableLong{" + "originalValue=" + originalValue + '}'; + return "ModifiableLong{" + "originalValue=" + originalValue + innerToString() + '}'; } @Override - public boolean equals(Object o) { - if (this == o) { + public boolean equals(Object obj) { + if (this == obj) { return true; } - if (!(o instanceof ModifiableLong)) { + if (!(obj instanceof ModifiableLong)) { return false; } - ModifiableLong that = (ModifiableLong) o; + ModifiableLong that = (ModifiableLong) obj; return getValue() != null ? getValue().equals(that.getValue()) : that.getValue() == null; } diff --git a/src/main/java/de/rub/nds/modifiablevariable/path/ModifiablePath.java b/src/main/java/de/rub/nds/modifiablevariable/path/ModifiablePath.java new file mode 100644 index 00000000..b3566ea1 --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/path/ModifiablePath.java @@ -0,0 +1,68 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.path; + +import static de.rub.nds.modifiablevariable.util.StringUtil.backslashEscapeString; + +import de.rub.nds.modifiablevariable.VariableModification; +import de.rub.nds.modifiablevariable.string.ModifiableString; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class ModifiablePath extends ModifiableString { + + public ModifiablePath() { + super(); + } + + public ModifiablePath(String originalValue) { + super(originalValue); + } + + public ModifiablePath(ModifiablePath other) { + super(other); + } + + @Override + public ModifiablePath createCopy() { + return new ModifiablePath(this); + } + + @Override + public void setRandomModification() { + VariableModification vm = PathModificationFactory.createRandomModification(null); + setModification(vm); + } + + @Override + public String toString() { + return "ModifiablePath{" + + "originalValue='" + + backslashEscapeString(originalValue) + + '\'' + + innerToString() + + '}'; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof ModifiablePath)) { + return false; + } + + ModifiablePath that = (ModifiablePath) obj; + + return getValue() != null ? getValue().equals(that.getValue()) : that.getValue() == null; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/path/PathAppendValueModification.java b/src/main/java/de/rub/nds/modifiablevariable/path/PathAppendValueModification.java new file mode 100644 index 00000000..1a806de9 --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/path/PathAppendValueModification.java @@ -0,0 +1,108 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.path; + +import static de.rub.nds.modifiablevariable.util.StringUtil.backslashEscapeString; + +import de.rub.nds.modifiablevariable.VariableModification; +import de.rub.nds.modifiablevariable.util.IllegalStringAdapter; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import java.util.Objects; +import java.util.Random; + +/** Modification that appends a path parts to the original value. */ +@XmlRootElement +@XmlType(propOrder = {"appendValue", "modificationFilter"}) +public class PathAppendValueModification extends VariableModification { + + private static final int MAX_EXPLICIT_VALUE = 256; + + @XmlJavaTypeAdapter(IllegalStringAdapter.class) + private String appendValue; + + public PathAppendValueModification() { + super(); + } + + public PathAppendValueModification(String appendValue) { + super(); + this.appendValue = appendValue; + } + + public PathAppendValueModification(PathAppendValueModification other) { + super(other); + appendValue = other.appendValue; + } + + @Override + public PathAppendValueModification createCopy() { + return new PathAppendValueModification(this); + } + + @Override + protected String modifyImplementationHook(String input) { + if (input == null) { + return null; + } + if (input.endsWith("/")) { + return input + appendValue + "/"; + } + return input + "/" + appendValue; + } + + public String getAppendValue() { + return appendValue; + } + + public void setAppendValue(String appendValue) { + this.appendValue = appendValue; + } + + @Override + public VariableModification getModifiedCopy() { + Random r = new Random(); + int index = r.nextInt(appendValue.length()); + char randomChar = (char) r.nextInt(MAX_EXPLICIT_VALUE); + StringBuilder modifiedString = new StringBuilder(appendValue); + modifiedString.setCharAt(index, randomChar); + return new PathAppendValueModification(modifiedString.toString()); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + appendValue.hashCode(); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + PathAppendValueModification other = (PathAppendValueModification) obj; + return Objects.equals(appendValue, other.appendValue); + } + + @Override + public String toString() { + return "PathAppendValueModification{" + + "appendValue='" + + backslashEscapeString(appendValue) + + '\'' + + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/path/PathDeleteModification.java b/src/main/java/de/rub/nds/modifiablevariable/path/PathDeleteModification.java new file mode 100644 index 00000000..3de7c144 --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/path/PathDeleteModification.java @@ -0,0 +1,161 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.path; + +import de.rub.nds.modifiablevariable.VariableModification; +import de.rub.nds.modifiablevariable.util.ArrayConverter; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import java.util.Arrays; +import java.util.Objects; +import java.util.Random; + +/** Modification that deletes path parts from the original value. */ +@XmlRootElement +@XmlType(propOrder = {"count", "startPosition", "modificationFilter"}) +public class PathDeleteModification extends VariableModification { + + private static final int MAX_MODIFIER_LENGTH = 32; + + private int count; + + private int startPosition; + + public PathDeleteModification() { + super(); + } + + public PathDeleteModification(int startPosition, int count) { + super(); + this.count = count; + this.startPosition = startPosition; + } + + public PathDeleteModification(PathDeleteModification other) { + super(other); + count = other.count; + startPosition = other.startPosition; + } + + @Override + public PathDeleteModification createCopy() { + return new PathDeleteModification(this); + } + + @Override + protected String modifyImplementationHook(String input) { + if (input == null) { + return null; + } + if (input.isEmpty()) { + return input; + } + String[] pathParts = input.split("/"); + boolean leadingSlash = pathParts[0].isEmpty(); + + // Wrap around and also allow to delete at the end of the original value + int deleteStartPosition = + PathUtil.getPathPartPosition(startPosition, leadingSlash, pathParts); + // If the end position overflows, it is fixed at the end of the path + int deleteEndPosition = deleteStartPosition + count; + if (deleteEndPosition > pathParts.length) { + deleteEndPosition = pathParts.length; + } + + String[] partsBefore = Arrays.copyOf(pathParts, deleteStartPosition); + String[] partsAfter = null; + if (deleteEndPosition < pathParts.length) { + partsAfter = Arrays.copyOfRange(pathParts, deleteEndPosition, pathParts.length); + } + String[] resultParts = ArrayConverter.concatenate(partsBefore, partsAfter); + + if (input.endsWith("/") && resultParts.length > 0) { + resultParts[resultParts.length - 1] += "/"; + } + return String.join("/", resultParts); + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + public int getStartPosition() { + return startPosition; + } + + public void setStartPosition(int startPosition) { + this.startPosition = startPosition; + } + + @Override + public VariableModification getModifiedCopy() { + Random r = new Random(); + + if (r.nextBoolean()) { + int modifier = r.nextInt(MAX_MODIFIER_LENGTH); + if (r.nextBoolean()) { + modifier *= -1; + } + modifier = count + modifier; + if (modifier <= 0) { + modifier = 1; + } + return new PathDeleteModification(modifier, startPosition); + } else { + int modifier = r.nextInt(MAX_MODIFIER_LENGTH); + if (r.nextBoolean()) { + modifier *= -1; + } + modifier = startPosition + modifier; + if (modifier <= 0) { + modifier = 1; + } + return new PathDeleteModification(count, modifier); + } + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + count; + hash = 31 * hash + startPosition; + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + PathDeleteModification other = (PathDeleteModification) obj; + if (startPosition != other.startPosition) { + return false; + } + return Objects.equals(count, other.count); + } + + @Override + public String toString() { + return "PathDeleteModification{" + + "count=" + + count + + ", startPosition=" + + startPosition + + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/path/PathExplicitValueFromFileModification.java b/src/main/java/de/rub/nds/modifiablevariable/path/PathExplicitValueFromFileModification.java new file mode 100644 index 00000000..7d78424e --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/path/PathExplicitValueFromFileModification.java @@ -0,0 +1,89 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.path; + +import static de.rub.nds.modifiablevariable.util.StringUtil.backslashEscapeString; + +import de.rub.nds.modifiablevariable.VariableModification; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import java.util.Objects; + +@XmlRootElement +@XmlType(propOrder = "index") +@XmlAccessorType(XmlAccessType.FIELD) +public class PathExplicitValueFromFileModification extends PathExplicitValueModification { + private int index; + + public PathExplicitValueFromFileModification() { + super(); + } + + public PathExplicitValueFromFileModification(int index, String explicitValue) { + super(explicitValue); + this.index = index; + } + + public PathExplicitValueFromFileModification(PathExplicitValueFromFileModification other) { + super(other); + index = other.index; + } + + @Override + public PathExplicitValueFromFileModification createCopy() { + return new PathExplicitValueFromFileModification(this); + } + + public int getIndex() { + return index; + } + + @Override + public VariableModification getModifiedCopy() { + throw new UnsupportedOperationException( + "Cannot set modify Value of PathExplicitValueFromFileModification"); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + index; + hash = 31 * hash + explicitValue.hashCode(); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + PathExplicitValueFromFileModification other = (PathExplicitValueFromFileModification) obj; + if (index != other.index) { + return false; + } + return Objects.equals(explicitValue, other.explicitValue); + } + + @Override + public String toString() { + return "PathExplicitValueFromFileModification{" + + "index=" + + index + + ", explicitValue=" + + backslashEscapeString(explicitValue) + + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/path/PathExplicitValueModification.java b/src/main/java/de/rub/nds/modifiablevariable/path/PathExplicitValueModification.java new file mode 100644 index 00000000..d5ea0b6c --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/path/PathExplicitValueModification.java @@ -0,0 +1,104 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.path; + +import static de.rub.nds.modifiablevariable.util.StringUtil.backslashEscapeString; + +import de.rub.nds.modifiablevariable.VariableModification; +import de.rub.nds.modifiablevariable.util.IllegalStringAdapter; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import java.util.Objects; +import java.util.Random; + +@XmlRootElement +@XmlType(propOrder = {"explicitValue", "modificationFilter"}) +public class PathExplicitValueModification extends VariableModification { + + private static final int MAX_EXPLICIT_VALUE = 256; + + @XmlJavaTypeAdapter(IllegalStringAdapter.class) + protected String explicitValue; + + public PathExplicitValueModification() { + super(); + } + + public PathExplicitValueModification(String explicitValue) { + super(); + this.explicitValue = explicitValue; + } + + public PathExplicitValueModification(PathExplicitValueModification other) { + super(other); + explicitValue = other.explicitValue; + } + + @Override + public PathExplicitValueModification createCopy() { + return new PathExplicitValueModification(this); + } + + @Override + protected String modifyImplementationHook(String input) { + return explicitValue; + } + + public String getExplicitValue() { + return explicitValue; + } + + public void setExplicitValue(String explicitValue) { + this.explicitValue = explicitValue; + } + + @Override + public VariableModification getModifiedCopy() { + if (explicitValue.isEmpty()) { + return this; + } + Random r = new Random(); + int index = r.nextInt(explicitValue.length()); + char randomChar = (char) r.nextInt(MAX_EXPLICIT_VALUE); + StringBuilder modifiedString = new StringBuilder(explicitValue); + modifiedString.setCharAt(index, randomChar); + return new PathExplicitValueModification(modifiedString.toString()); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + explicitValue.hashCode(); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + PathExplicitValueModification other = (PathExplicitValueModification) obj; + return Objects.equals(explicitValue, other.explicitValue); + } + + @Override + public String toString() { + return "PathExplicitValueModification{" + + "explicitValue='" + + backslashEscapeString(explicitValue) + + '\'' + + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/path/PathInsertDirectorySeparatorModification.java b/src/main/java/de/rub/nds/modifiablevariable/path/PathInsertDirectorySeparatorModification.java new file mode 100644 index 00000000..0dfa225d --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/path/PathInsertDirectorySeparatorModification.java @@ -0,0 +1,147 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.path; + +import de.rub.nds.modifiablevariable.VariableModification; +import de.rub.nds.modifiablevariable.util.IllegalStringAdapter; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import java.util.Objects; +import java.util.Random; + +/** Modification that inserts directory separators as path parts to the original value. */ +@XmlRootElement +@XmlType(propOrder = {"insertValue", "count", "startPosition", "modificationFilter"}) +public class PathInsertDirectorySeparatorModification extends VariableModification { + + private static final int MAX_INSERT_MODIFIER = 32; + + @XmlJavaTypeAdapter(IllegalStringAdapter.class) + private String insertValue; + + private int count; + private int startPosition; + + public PathInsertDirectorySeparatorModification() { + super(); + } + + public PathInsertDirectorySeparatorModification(int count, int startPosition) { + super(); + this.count = count; + this.startPosition = startPosition; + updateInsertValue(); + } + + public PathInsertDirectorySeparatorModification( + PathInsertDirectorySeparatorModification other) { + super(other); + insertValue = other.insertValue; + count = other.count; + startPosition = other.startPosition; + } + + @Override + public PathInsertDirectorySeparatorModification createCopy() { + return new PathInsertDirectorySeparatorModification(this); + } + + private void updateInsertValue() { + insertValue = "/".repeat(Math.max(0, count)); + } + + @Override + protected String modifyImplementationHook(String input) { + return PathUtil.insertValueAsPathPart(input, insertValue, startPosition); + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + updateInsertValue(); + } + + public int getStartPosition() { + return startPosition; + } + + public void setStartPosition(int startPosition) { + this.startPosition = startPosition; + } + + @Override + public VariableModification getModifiedCopy() { + Random r = new Random(); + + if (r.nextBoolean()) { + int modifier = r.nextInt(MAX_INSERT_MODIFIER); + if (r.nextBoolean()) { + modifier *= -1; + } + modifier = count + modifier; + if (modifier <= 0) { + modifier = 1; + } + return new PathInsertDirectorySeparatorModification(modifier, startPosition); + } else { + int modifier = r.nextInt(MAX_INSERT_MODIFIER); + if (r.nextBoolean()) { + modifier *= -1; + } + modifier = startPosition + modifier; + if (modifier <= 0) { + modifier = 1; + } + return new PathInsertDirectorySeparatorModification(count, modifier); + } + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + count; + hash = 31 * hash + startPosition; + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + PathInsertDirectorySeparatorModification other = + (PathInsertDirectorySeparatorModification) obj; + if (startPosition != other.startPosition) { + return false; + } + return Objects.equals(count, other.count); + } + + @Override + public String toString() { + return "PathInsertDirectorySeparatorModification{" + + "insertValue='" + + insertValue + + '\'' + + ", count=" + + count + + ", startPosition=" + + startPosition + + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/path/PathInsertDirectoryTraversalModification.java b/src/main/java/de/rub/nds/modifiablevariable/path/PathInsertDirectoryTraversalModification.java new file mode 100644 index 00000000..1e22284c --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/path/PathInsertDirectoryTraversalModification.java @@ -0,0 +1,158 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.path; + +import de.rub.nds.modifiablevariable.VariableModification; +import de.rub.nds.modifiablevariable.util.IllegalStringAdapter; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import java.util.Objects; +import java.util.Random; + +/** Modification that directory traversal path parts the original value. */ +@XmlRootElement +@XmlType(propOrder = {"insertValue", "count", "startPosition", "modificationFilter"}) +public class PathInsertDirectoryTraversalModification extends VariableModification { + + private static final int MAX_INSERT_MODIFIER = 32; + + @XmlJavaTypeAdapter(IllegalStringAdapter.class) + private String insertValue; + + private int count; + private int startPosition; + + public PathInsertDirectoryTraversalModification() { + super(); + } + + public PathInsertDirectoryTraversalModification(int count, int startPosition) { + super(); + this.count = count; + this.startPosition = startPosition; + updateInsertValue(); + } + + public PathInsertDirectoryTraversalModification( + PathInsertDirectoryTraversalModification other) { + super(other); + insertValue = other.insertValue; + count = other.count; + startPosition = other.startPosition; + } + + @Override + public PathInsertDirectoryTraversalModification createCopy() { + return new PathInsertDirectoryTraversalModification(this); + } + + private void updateInsertValue() { + if (count <= 0) { + insertValue = ""; + return; + } + StringBuilder builder = new StringBuilder(count * 3 - 1); + for (int i = 0; i < count; i++) { + builder.append(".."); + if (i < count - 1) { + builder.append("/"); + } + } + insertValue = builder.toString(); + } + + @Override + protected String modifyImplementationHook(String input) { + return PathUtil.insertValueAsPathPart(input, insertValue, startPosition); + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + updateInsertValue(); + } + + public int getStartPosition() { + return startPosition; + } + + public void setStartPosition(int startPosition) { + this.startPosition = startPosition; + } + + @Override + public VariableModification getModifiedCopy() { + Random r = new Random(); + + if (r.nextBoolean()) { + int modifier = r.nextInt(MAX_INSERT_MODIFIER); + if (r.nextBoolean()) { + modifier *= -1; + } + modifier = count + modifier; + if (modifier <= 0) { + modifier = 1; + } + return new PathInsertDirectoryTraversalModification(modifier, startPosition); + } else { + int modifier = r.nextInt(MAX_INSERT_MODIFIER); + if (r.nextBoolean()) { + modifier *= -1; + } + modifier = startPosition + modifier; + if (modifier <= 0) { + modifier = 1; + } + return new PathInsertDirectoryTraversalModification(count, modifier); + } + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + count; + hash = 31 * hash + startPosition; + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + PathInsertDirectoryTraversalModification other = + (PathInsertDirectoryTraversalModification) obj; + if (startPosition != other.startPosition) { + return false; + } + return Objects.equals(count, other.count); + } + + @Override + public String toString() { + return "PathInsertDirectoryTraversalModification{" + + "insertValue='" + + insertValue + + '\'' + + ", count=" + + count + + ", startPosition=" + + startPosition + + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/path/PathInsertValueModification.java b/src/main/java/de/rub/nds/modifiablevariable/path/PathInsertValueModification.java new file mode 100644 index 00000000..60ab6dc5 --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/path/PathInsertValueModification.java @@ -0,0 +1,135 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.path; + +import static de.rub.nds.modifiablevariable.util.StringUtil.backslashEscapeString; + +import de.rub.nds.modifiablevariable.VariableModification; +import de.rub.nds.modifiablevariable.util.IllegalStringAdapter; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import java.util.Objects; +import java.util.Random; + +/** Modification that inserts path parts to the original value. */ +@XmlRootElement +@XmlType(propOrder = {"insertValue", "startPosition", "modificationFilter"}) +public class PathInsertValueModification extends VariableModification { + + private static final int MAX_EXPLICIT_VALUE = 256; + + private static final int MAX_INSERT_MODIFIER = 32; + + @XmlJavaTypeAdapter(IllegalStringAdapter.class) + private String insertValue; + + private int startPosition; + + public PathInsertValueModification() { + super(); + } + + public PathInsertValueModification(String insertValue, int startPosition) { + super(); + this.insertValue = insertValue; + this.startPosition = startPosition; + } + + public PathInsertValueModification(PathInsertValueModification other) { + super(other); + insertValue = other.insertValue; + startPosition = other.startPosition; + } + + @Override + public PathInsertValueModification createCopy() { + return new PathInsertValueModification(this); + } + + @Override + protected String modifyImplementationHook(String input) { + return PathUtil.insertValueAsPathPart(input, insertValue, startPosition); + } + + public String getInsertValue() { + return insertValue; + } + + public void setInsertValue(String insertValue) { + this.insertValue = insertValue; + } + + public int getStartPosition() { + return startPosition; + } + + public void setStartPosition(int startPosition) { + this.startPosition = startPosition; + } + + @Override + public VariableModification getModifiedCopy() { + Random r = new Random(); + + if (r.nextBoolean()) { + int index = r.nextInt(insertValue.length()); + char randomChar = (char) r.nextInt(MAX_EXPLICIT_VALUE); + StringBuilder modifiedString = new StringBuilder(insertValue); + modifiedString.setCharAt(index, randomChar); + return new PathInsertValueModification(modifiedString.toString(), startPosition); + } else { + int modifier = r.nextInt(MAX_INSERT_MODIFIER); + if (r.nextBoolean()) { + modifier *= -1; + } + modifier = startPosition + modifier; + if (modifier <= 0) { + modifier = 1; + } + return new PathInsertValueModification(insertValue, modifier); + } + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + insertValue.hashCode(); + hash = 31 * hash + startPosition; + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + PathInsertValueModification other = (PathInsertValueModification) obj; + if (startPosition != other.startPosition) { + return false; + } + return Objects.equals(insertValue, other.insertValue); + } + + @Override + public String toString() { + return "PathInsertValueModification{" + + "insertValue='" + + backslashEscapeString(insertValue) + + '\'' + + ", startPosition=" + + startPosition + + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/path/PathModificationFactory.java b/src/main/java/de/rub/nds/modifiablevariable/path/PathModificationFactory.java new file mode 100644 index 00000000..f143360d --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/path/PathModificationFactory.java @@ -0,0 +1,146 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.path; + +import de.rub.nds.modifiablevariable.VariableModification; +import de.rub.nds.modifiablevariable.string.StringDeleteModification; +import de.rub.nds.modifiablevariable.util.RandomHelper; +import java.util.Random; + +/** */ +public final class PathModificationFactory { + + private PathModificationFactory() { + super(); + } + + private enum ModificationType { + APPEND, + PREPEND, + INSERT, + DELETE, + INSERT_DIRECTORY_TRAVERSAL, + INSERT_DIRECTORY_SEPERATOR, + TOGGLE_ROOT + } + + private static final int MODIFICATION_COUNT = ModificationType.values().length; + + private static final int MAX_BYTE_LENGTH_INSERT = 200; + + private static final int NUMBER_OF_PATH_PARTS_ESTIMATION = 50; + + private static final int MAX_NUMBER_OF_DIRECTORY_TRAVERSAL_INSERT = 10; + private static final int MAX_NUMBER_OF_DIRECTORY_SEPERATOR_INSERT = 10; + + public static VariableModification prependValue(String value) { + return new PathPrependValueModification(value); + } + + public static VariableModification explicitValue(String value) { + return new PathExplicitValueModification(value); + } + + public static VariableModification appendValue(String value) { + return new PathAppendValueModification(value); + } + + public static VariableModification insertValue(String value, int position) { + return new PathInsertValueModification(value, position); + } + + public static VariableModification delete(int position, int count) { + return new PathDeleteModification(position, count); + } + + public static VariableModification insertDirectoryTraversal(int count, int position) { + return new PathInsertDirectoryTraversalModification(count, position); + } + + public static VariableModification insertDirectorySeperator(int count, int position) { + return new PathInsertDirectorySeparatorModification(count, position); + } + + public static VariableModification toggleRoot() { + return new PathToggleRootModification(); + } + + public static VariableModification createRandomModification(String originalValue) { + Random random = RandomHelper.getRandom(); + ModificationType randomType = ModificationType.values()[random.nextInt(MODIFICATION_COUNT)]; + int modificationStringLength; + int numberOfPathParts; + if (originalValue == null) { + numberOfPathParts = NUMBER_OF_PATH_PARTS_ESTIMATION; + } else { + String[] pathParts = originalValue.split("/"); + if (pathParts.length == 0) { + if (randomType == ModificationType.INSERT + || randomType == ModificationType.DELETE) { + randomType = ModificationType.APPEND; + } + numberOfPathParts = 0; + } else { + if (pathParts[0].isEmpty()) { + numberOfPathParts = originalValue.split("/").length - 1; + } else { + numberOfPathParts = originalValue.split("/").length; + } + } + } + int insertPosition; + switch (randomType) { + case APPEND: + modificationStringLength = random.nextInt(MAX_BYTE_LENGTH_INSERT); + if (modificationStringLength == 0) { + modificationStringLength++; + } + byte[] bytesToAppend = new byte[modificationStringLength]; + random.nextBytes(bytesToAppend); + return new PathAppendValueModification(new String(bytesToAppend)); + case PREPEND: + modificationStringLength = random.nextInt(MAX_BYTE_LENGTH_INSERT); + if (modificationStringLength == 0) { + modificationStringLength++; + } + byte[] bytesToPrepend = new byte[modificationStringLength]; + random.nextBytes(bytesToPrepend); + return new PathPrependValueModification(new String(bytesToPrepend)); + case INSERT: + modificationStringLength = random.nextInt(MAX_BYTE_LENGTH_INSERT); + if (modificationStringLength == 0) { + modificationStringLength++; + } + byte[] bytesToInsert = new byte[modificationStringLength]; + random.nextBytes(bytesToInsert); + insertPosition = random.nextInt(numberOfPathParts); + return new PathInsertValueModification(new String(bytesToInsert), insertPosition); + case INSERT_DIRECTORY_TRAVERSAL: + int numberOfDirectoryTraversal = + random.nextInt(MAX_NUMBER_OF_DIRECTORY_TRAVERSAL_INSERT); + insertPosition = random.nextInt(numberOfPathParts); + return new PathInsertDirectoryTraversalModification( + numberOfDirectoryTraversal, insertPosition); + case INSERT_DIRECTORY_SEPERATOR: + int numberOfDirectorySeperator = + random.nextInt(MAX_NUMBER_OF_DIRECTORY_SEPERATOR_INSERT); + insertPosition = random.nextInt(numberOfPathParts); + return new PathInsertDirectorySeparatorModification( + numberOfDirectorySeperator, insertPosition); + case TOGGLE_ROOT: + return new PathToggleRootModification(); + case DELETE: + int startPosition = random.nextInt(numberOfPathParts - 1); + int count = random.nextInt(numberOfPathParts - startPosition); + count++; + return new StringDeleteModification(startPosition, count); + default: + throw new IllegalStateException("Unexpected modification type: " + randomType); + } + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/path/PathPrependValueModification.java b/src/main/java/de/rub/nds/modifiablevariable/path/PathPrependValueModification.java new file mode 100644 index 00000000..e56f147f --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/path/PathPrependValueModification.java @@ -0,0 +1,108 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.path; + +import static de.rub.nds.modifiablevariable.util.StringUtil.backslashEscapeString; + +import de.rub.nds.modifiablevariable.VariableModification; +import de.rub.nds.modifiablevariable.util.IllegalStringAdapter; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import java.util.Objects; +import java.util.Random; + +/** Modification that prepends a string to the original value. */ +@XmlRootElement +@XmlType(propOrder = {"prependValue", "modificationFilter"}) +public class PathPrependValueModification extends VariableModification { + + private static final int MAX_EXPLICIT_VALUE = 256; + + @XmlJavaTypeAdapter(IllegalStringAdapter.class) + private String prependValue; + + public PathPrependValueModification() { + super(); + } + + public PathPrependValueModification(String prependValue) { + super(); + this.prependValue = prependValue; + } + + public PathPrependValueModification(PathPrependValueModification other) { + super(other); + prependValue = other.prependValue; + } + + @Override + public PathPrependValueModification createCopy() { + return new PathPrependValueModification(this); + } + + @Override + protected String modifyImplementationHook(String input) { + if (input == null) { + return null; + } + if (input.startsWith("/")) { + return "/" + prependValue + input; + } + return prependValue + "/" + input; + } + + public String getPrependValue() { + return prependValue; + } + + public void setPrependValue(String prependValue) { + this.prependValue = prependValue; + } + + @Override + public VariableModification getModifiedCopy() { + Random r = new Random(); + int index = r.nextInt(prependValue.length()); + char randomChar = (char) r.nextInt(MAX_EXPLICIT_VALUE); + StringBuilder modifiedString = new StringBuilder(prependValue); + modifiedString.setCharAt(index, randomChar); + return new PathPrependValueModification(modifiedString.toString()); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + prependValue.hashCode(); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + PathPrependValueModification other = (PathPrependValueModification) obj; + return Objects.equals(prependValue, other.prependValue); + } + + @Override + public String toString() { + return "PathPrependValueModification{" + + "prependValue='" + + backslashEscapeString(prependValue) + + '\'' + + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/path/PathToggleRootModification.java b/src/main/java/de/rub/nds/modifiablevariable/path/PathToggleRootModification.java new file mode 100644 index 00000000..8d6ee3e8 --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/path/PathToggleRootModification.java @@ -0,0 +1,68 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.path; + +import de.rub.nds.modifiablevariable.VariableModification; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; + +/** Modification that toggle the root slash of the original value. */ +@XmlRootElement +@XmlType(propOrder = "modificationFilter") +public class PathToggleRootModification extends VariableModification { + + public PathToggleRootModification() { + super(); + } + + public PathToggleRootModification(PathToggleRootModification other) { + super(other); + } + + @Override + public PathToggleRootModification createCopy() { + return new PathToggleRootModification(this); + } + + @Override + protected String modifyImplementationHook(String input) { + if (input == null) { + return null; + } + if (!input.isEmpty() && input.charAt(0) == '/') { + return input.substring(1); + } + return "/" + input; + } + + @Override + public VariableModification getModifiedCopy() { + return new PathToggleRootModification(); + } + + @Override + public int hashCode() { + return 7; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + return getClass() == obj.getClass(); + } + + @Override + public String toString() { + return "PathToggleRootModification{}"; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/path/PathUtil.java b/src/main/java/de/rub/nds/modifiablevariable/path/PathUtil.java new file mode 100644 index 00000000..549f98ca --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/path/PathUtil.java @@ -0,0 +1,81 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.path; + +public final class PathUtil { + + private PathUtil() { + super(); + } + + public static String insertValueAsPathPart( + String input, String insertValue, int startPosition) { + if (input == null) { + return null; + } + + if (input.isEmpty()) { + return insertValue; + } + String[] pathParts = input.split("/"); + boolean leadingSlash = pathParts[0].isEmpty(); + + // Wrap around and also allow to insert at the end of the original value + int insertPosition = getInsertPosition(startPosition, leadingSlash, pathParts); + + if (insertPosition == 0 && leadingSlash) { + pathParts[insertPosition] = "/" + insertValue; + } else if (insertPosition == pathParts.length) { + pathParts[insertPosition - 1] = pathParts[insertPosition - 1] + "/" + insertValue; + } else { + pathParts[insertPosition] = insertValue + "/" + pathParts[insertPosition]; + } + if (input.endsWith("/")) { + pathParts[pathParts.length - 1] += "/"; + } + return String.join("/", pathParts); + } + + private static int getInsertPosition( + int startPosition, boolean leadingSlash, String[] pathParts) { + int insertPosition; + if (leadingSlash) { + // If the path starts with a slash, skip the first empty path part. + insertPosition = startPosition % pathParts.length; + if (startPosition < 0) { + insertPosition += pathParts.length - 1; + } + insertPosition++; + } else { + insertPosition = startPosition % (pathParts.length + 1); + if (startPosition < 0) { + insertPosition += pathParts.length; + } + } + return insertPosition; + } + + public static int getPathPartPosition( + int startPosition, boolean leadingSlash, String[] pathParts) { + int pathPartPosition; + if (leadingSlash) { + // If the path starts with a slash, skip the first empty path part. + pathPartPosition = startPosition % (pathParts.length - 1); + if (startPosition < 0) { + pathPartPosition += pathParts.length - 2; + } + pathPartPosition++; + } else { + pathPartPosition = startPosition % pathParts.length; + if (startPosition < 0) { + pathPartPosition += pathParts.length - 1; + } + } + return pathPartPosition; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/singlebyte/ByteAddModification.java b/src/main/java/de/rub/nds/modifiablevariable/singlebyte/ByteAddModification.java index 08d69948..2fd73b29 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/singlebyte/ByteAddModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/singlebyte/ByteAddModification.java @@ -21,10 +21,23 @@ public class ByteAddModification extends VariableModification { private Byte summand; - public ByteAddModification() {} + public ByteAddModification() { + super(); + } + + public ByteAddModification(Byte summand) { + super(); + this.summand = summand; + } + + public ByteAddModification(ByteAddModification other) { + super(other); + summand = other.summand; + } - public ByteAddModification(Byte bi) { - this.summand = bi; + @Override + public ByteAddModification createCopy() { + return new ByteAddModification(this); } @Override @@ -50,8 +63,8 @@ public VariableModification getModifiedCopy() { @Override public int hashCode() { - int hash = 5; - hash = 17 * hash + Objects.hashCode(this.summand); + int hash = 7; + hash = 31 * hash + summand; return hash; } @@ -66,10 +79,12 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final ByteAddModification other = (ByteAddModification) obj; - if (!Objects.equals(this.summand, other.summand)) { - return false; - } - return true; + ByteAddModification other = (ByteAddModification) obj; + return Objects.equals(summand, other.summand); + } + + @Override + public String toString() { + return "ByteAddModification{" + "summand=" + summand + '}'; } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/singlebyte/ByteExplicitValueFromFileModification.java b/src/main/java/de/rub/nds/modifiablevariable/singlebyte/ByteExplicitValueFromFileModification.java new file mode 100644 index 00000000..6460f962 --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/singlebyte/ByteExplicitValueFromFileModification.java @@ -0,0 +1,87 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.singlebyte; + +import de.rub.nds.modifiablevariable.VariableModification; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import java.util.Objects; + +@XmlRootElement +@XmlType(propOrder = "index") +@XmlAccessorType(XmlAccessType.FIELD) +public class ByteExplicitValueFromFileModification extends ByteExplicitValueModification { + private int index; + + public ByteExplicitValueFromFileModification() { + super(); + } + + public ByteExplicitValueFromFileModification(int index, Byte explicitValue) { + super(explicitValue); + this.index = index; + } + + public ByteExplicitValueFromFileModification(ByteExplicitValueFromFileModification other) { + super(other); + index = other.index; + } + + @Override + public ByteExplicitValueFromFileModification createCopy() { + return new ByteExplicitValueFromFileModification(this); + } + + public int getIndex() { + return index; + } + + @Override + public VariableModification getModifiedCopy() { + throw new UnsupportedOperationException( + "Cannot set modify Value of ByteExplicitValueFromFileModification"); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + index; + hash = 31 * hash + explicitValue.hashCode(); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + ByteExplicitValueFromFileModification other = (ByteExplicitValueFromFileModification) obj; + if (index != other.index) { + return false; + } + return Objects.equals(explicitValue, other.explicitValue); + } + + @Override + public String toString() { + return "ByteExplicitValueFromFileModification{" + + "index=" + + index + + ", explicitValue=" + + explicitValue + + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/singlebyte/ByteExplicitValueModification.java b/src/main/java/de/rub/nds/modifiablevariable/singlebyte/ByteExplicitValueModification.java index 4950545d..f0e6bffe 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/singlebyte/ByteExplicitValueModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/singlebyte/ByteExplicitValueModification.java @@ -19,16 +19,29 @@ public class ByteExplicitValueModification extends VariableModification { private static final int MAX_EXPLICIT_MODIFIER = 16; - private Byte explicitValue; + protected Byte explicitValue; - public ByteExplicitValueModification() {} + public ByteExplicitValueModification() { + super(); + } + + public ByteExplicitValueModification(Byte explicitValue) { + super(); + this.explicitValue = explicitValue; + } + + public ByteExplicitValueModification(ByteExplicitValueModification other) { + super(other); + explicitValue = other.explicitValue; + } - public ByteExplicitValueModification(Byte bi) { - this.explicitValue = bi; + @Override + public ByteExplicitValueModification createCopy() { + return new ByteExplicitValueModification(this); } @Override - protected Byte modifyImplementationHook(final Byte input) { + protected Byte modifyImplementationHook(Byte input) { return explicitValue; } @@ -55,7 +68,7 @@ public VariableModification getModifiedCopy() { @Override public int hashCode() { int hash = 7; - hash = 79 * hash + Objects.hashCode(this.explicitValue); + hash = 31 * hash + explicitValue; return hash; } @@ -70,10 +83,12 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final ByteExplicitValueModification other = (ByteExplicitValueModification) obj; - if (!Objects.equals(this.explicitValue, other.explicitValue)) { - return false; - } - return true; + ByteExplicitValueModification other = (ByteExplicitValueModification) obj; + return Objects.equals(explicitValue, other.explicitValue); + } + + @Override + public String toString() { + return "ByteExplicitValueModification{" + "explicitValue=" + explicitValue + '}'; } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/singlebyte/ByteModificationFactory.java b/src/main/java/de/rub/nds/modifiablevariable/singlebyte/ByteModificationFactory.java index 7b999e71..51593775 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/singlebyte/ByteModificationFactory.java +++ b/src/main/java/de/rub/nds/modifiablevariable/singlebyte/ByteModificationFactory.java @@ -14,75 +14,78 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.util.LinkedList; +import java.util.ArrayList; import java.util.List; import java.util.Random; -public class ByteModificationFactory { +public final class ByteModificationFactory { - private static final int BYTE_EXPLICIT_VALUE_MODIFICATION = 3; - - private static final int BYTE_XOR_MODIFICATION = 2; - - private static final int BYTE_SUBTRACT_MODIFICATION = 1; - - private static final int BYTE_ADD_MODIFICATION = 0; + private enum ModificationType { + ADD, + SUBTRACT, + XOR, + EXPLICIT, + EXPLICIT_FROM_FILE + } - private static final int MODIFICATION_COUNT = 5; + private static final int MODIFICATION_COUNT = ModificationType.values().length; private static List> modificationsFromFile; public static final String FILE_NAME = "de/rub/nds/modifiablevariable/explicit/byte.vec"; - public static ByteAddModification add(final String summand) { + public static ByteAddModification add(String summand) { return add(Byte.parseByte(summand)); } - public static ByteAddModification add(final Byte summand) { + public static ByteAddModification add(Byte summand) { return new ByteAddModification(summand); } - public static VariableModification sub(final String subtrahend) { + public static VariableModification sub(String subtrahend) { return sub(Byte.parseByte(subtrahend)); } - public static VariableModification sub(final Byte subtrahend) { + public static VariableModification sub(Byte subtrahend) { return new ByteSubtractModification(subtrahend); } - public static VariableModification xor(final String xor) { + public static VariableModification xor(String xor) { return xor(Byte.parseByte(xor)); } - public static VariableModification xor(final Byte xor) { + public static VariableModification xor(Byte xor) { return new ByteXorModification(xor); } - public static VariableModification explicitValue(final String value) { + public static VariableModification explicitValue(String value) { return explicitValue(Byte.parseByte(value)); } - public static VariableModification explicitValue(final Byte value) { + public static VariableModification explicitValue(Byte value) { return new ByteExplicitValueModification(value); } - public static VariableModification explicitValueFromFile(int value) { + public static VariableModification explicitValueFromFile(int pos) { List> modifications = modificationsFromFile(); - int pos = value % modifications.size(); - return modifications.get(pos); + return modifications.get(pos % modifications.size()); } public static synchronized List> modificationsFromFile() { try { if (modificationsFromFile == null) { - modificationsFromFile = new LinkedList<>(); + modificationsFromFile = new ArrayList<>(); ClassLoader classLoader = ByteModificationFactory.class.getClassLoader(); InputStream is = classLoader.getResourceAsStream(FILE_NAME); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String line; + int index = 0; while ((line = br.readLine()) != null) { String value = line.trim().split(" ")[0]; - modificationsFromFile.add(explicitValue(value)); + modificationsFromFile.add( + new ByteExplicitValueFromFileModification( + index, Byte.parseByte(value))); + index++; } } return modificationsFromFile; @@ -94,29 +97,25 @@ public static synchronized List> modificationsFromFil public static VariableModification createRandomModification() { Random random = RandomHelper.getRandom(); - int r = random.nextInt(MODIFICATION_COUNT); + ModificationType randomType = ModificationType.values()[random.nextInt(MODIFICATION_COUNT)]; byte modification = (byte) random.nextInt(Byte.MAX_VALUE); - VariableModification vm = null; - switch (r) { - case BYTE_ADD_MODIFICATION: - vm = new ByteAddModification(modification); - return vm; - case BYTE_SUBTRACT_MODIFICATION: - vm = new ByteSubtractModification(modification); - return vm; - case BYTE_XOR_MODIFICATION: - vm = new ByteXorModification(modification); - return vm; - case BYTE_EXPLICIT_VALUE_MODIFICATION: - vm = new ByteExplicitValueModification(modification); - return vm; - case 4: - vm = explicitValueFromFile(random.nextInt(Byte.MAX_VALUE)); - return vm; + switch (randomType) { + case ADD: + return new ByteAddModification(modification); + case SUBTRACT: + return new ByteSubtractModification(modification); + case XOR: + return new ByteXorModification(modification); + case EXPLICIT: + return new ByteExplicitValueModification(modification); + case EXPLICIT_FROM_FILE: + return explicitValueFromFile(random.nextInt(Byte.MAX_VALUE)); default: - return vm; + throw new IllegalStateException("Unexpected modification type: " + randomType); } } - private ByteModificationFactory() {} + private ByteModificationFactory() { + super(); + } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/singlebyte/ByteSubtractModification.java b/src/main/java/de/rub/nds/modifiablevariable/singlebyte/ByteSubtractModification.java index f5ccdde3..9093969c 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/singlebyte/ByteSubtractModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/singlebyte/ByteSubtractModification.java @@ -21,10 +21,23 @@ public class ByteSubtractModification extends VariableModification { private Byte subtrahend; - public ByteSubtractModification() {} + public ByteSubtractModification() { + super(); + } + + public ByteSubtractModification(Byte subtrahend) { + super(); + this.subtrahend = subtrahend; + } + + public ByteSubtractModification(ByteSubtractModification other) { + super(other); + subtrahend = other.subtrahend; + } - public ByteSubtractModification(Byte bi) { - this.subtrahend = bi; + @Override + public ByteSubtractModification createCopy() { + return new ByteSubtractModification(this); } @Override @@ -45,14 +58,14 @@ public void setSubtrahend(Byte subtrahend) { @Override public VariableModification getModifiedCopy() { - return new ByteAddModification( + return new ByteSubtractModification( (byte) (subtrahend + new Random().nextInt(MAX_SUBTRACT_MODIFIER))); } @Override public int hashCode() { - int hash = 3; - hash = 71 * hash + Objects.hashCode(this.subtrahend); + int hash = 7; + hash = 31 * hash + subtrahend; return hash; } @@ -67,10 +80,12 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final ByteSubtractModification other = (ByteSubtractModification) obj; - if (!Objects.equals(this.subtrahend, other.subtrahend)) { - return false; - } - return true; + ByteSubtractModification other = (ByteSubtractModification) obj; + return Objects.equals(subtrahend, other.subtrahend); + } + + @Override + public String toString() { + return "ByteSubtractModification{" + "subtrahend=" + subtrahend + '}'; } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/singlebyte/ByteXorModification.java b/src/main/java/de/rub/nds/modifiablevariable/singlebyte/ByteXorModification.java index 4cdce5d3..da6ed4db 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/singlebyte/ByteXorModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/singlebyte/ByteXorModification.java @@ -22,10 +22,23 @@ public class ByteXorModification extends VariableModification { private Byte xor; - public ByteXorModification() {} + public ByteXorModification() { + super(); + } + + public ByteXorModification(Byte xor) { + super(); + this.xor = xor; + } + + public ByteXorModification(ByteXorModification other) { + super(other); + xor = other.xor; + } - public ByteXorModification(Byte bi) { - this.xor = bi; + @Override + public ByteXorModification createCopy() { + return new ByteXorModification(this); } @Override @@ -57,7 +70,7 @@ public VariableModification getModifiedCopy() { @Override public int hashCode() { int hash = 7; - hash = 89 * hash + Objects.hashCode(this.xor); + hash = 31 * hash + xor; return hash; } @@ -72,10 +85,12 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final ByteXorModification other = (ByteXorModification) obj; - if (!Objects.equals(this.xor, other.xor)) { - return false; - } - return true; + ByteXorModification other = (ByteXorModification) obj; + return Objects.equals(xor, other.xor); + } + + @Override + public String toString() { + return "ByteXorModification{" + "xor=" + xor + '}'; } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/singlebyte/ModifiableByte.java b/src/main/java/de/rub/nds/modifiablevariable/singlebyte/ModifiableByte.java index 6e8c79c0..ee543274 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/singlebyte/ModifiableByte.java +++ b/src/main/java/de/rub/nds/modifiablevariable/singlebyte/ModifiableByte.java @@ -19,8 +19,27 @@ public class ModifiableByte extends ModifiableVariable { private Byte originalValue; + public ModifiableByte() { + super(); + } + + public ModifiableByte(Byte originalValue) { + super(); + this.originalValue = originalValue; + } + + public ModifiableByte(ModifiableByte other) { + super(other); + originalValue = other.originalValue; + } + + @Override + public ModifiableByte createCopy() { + return new ModifiableByte(this); + } + @Override - protected void createRandomModification() { + public void setRandomModification() { VariableModification vm = ByteModificationFactory.createRandomModification(); setModification(vm); } @@ -61,19 +80,19 @@ public void setOriginalValue(Byte originalValue) { @Override public String toString() { - return "ModifiableByte{" + "originalValue=" + originalValue + '}'; + return "ModifiableByte{" + "originalValue=" + originalValue + innerToString() + '}'; } @Override - public boolean equals(Object o) { - if (this == o) { + public boolean equals(Object obj) { + if (this == obj) { return true; } - if (!(o instanceof ModifiableByte)) { + if (!(obj instanceof ModifiableByte)) { return false; } - ModifiableByte that = (ModifiableByte) o; + ModifiableByte that = (ModifiableByte) obj; return getValue() != null ? getValue().equals(that.getValue()) : that.getValue() == null; } diff --git a/src/main/java/de/rub/nds/modifiablevariable/string/ModifiableString.java b/src/main/java/de/rub/nds/modifiablevariable/string/ModifiableString.java index 88076b21..fd18bbb9 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/string/ModifiableString.java +++ b/src/main/java/de/rub/nds/modifiablevariable/string/ModifiableString.java @@ -24,13 +24,30 @@ public class ModifiableString extends ModifiableVariable { @XmlJavaTypeAdapter(IllegalStringAdapter.class) - private String originalValue; + protected String originalValue; - public ModifiableString() {} + public ModifiableString() { + super(); + } + + public ModifiableString(String originalValue) { + super(); + this.originalValue = originalValue; + } + + public ModifiableString(ModifiableString other) { + super(other); + originalValue = other.originalValue; + } + + @Override + public ModifiableString createCopy() { + return new ModifiableString(this); + } @Override - protected void createRandomModification() { - VariableModification vm = StringModificationFactory.createRandomModification(); + public void setRandomModification() { + VariableModification vm = StringModificationFactory.createRandomModification(null); setModification(vm); } @@ -74,20 +91,24 @@ public void setOriginalValue(String originalValue) { @Override public String toString() { - return String.format( - "ModifiableString{originalValue=%s}", backslashEscapeString(originalValue)); + return "ModifiableString{" + + "originalValue='" + + backslashEscapeString(originalValue) + + '\'' + + innerToString() + + '}'; } @Override - public boolean equals(Object o) { - if (this == o) { + public boolean equals(Object obj) { + if (this == obj) { return true; } - if (!(o instanceof ModifiableString)) { + if (!(obj instanceof ModifiableString)) { return false; } - ModifiableString that = (ModifiableString) o; + ModifiableString that = (ModifiableString) obj; return getValue() != null ? getValue().equals(that.getValue()) : that.getValue() == null; } diff --git a/src/main/java/de/rub/nds/modifiablevariable/string/StringAppendValueModification.java b/src/main/java/de/rub/nds/modifiablevariable/string/StringAppendValueModification.java index ce8e1eb1..d5cd99be 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/string/StringAppendValueModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/string/StringAppendValueModification.java @@ -7,49 +7,72 @@ */ package de.rub.nds.modifiablevariable.string; +import static de.rub.nds.modifiablevariable.util.StringUtil.backslashEscapeString; + import de.rub.nds.modifiablevariable.VariableModification; import de.rub.nds.modifiablevariable.util.IllegalStringAdapter; import jakarta.xml.bind.annotation.XmlRootElement; import jakarta.xml.bind.annotation.XmlType; import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import java.util.Objects; +import java.util.Random; /** Modification that appends a string to the original value. */ @XmlRootElement @XmlType(propOrder = {"appendValue", "modificationFilter"}) public class StringAppendValueModification extends VariableModification { + private static final int MAX_EXPLICIT_VALUE = 256; + @XmlJavaTypeAdapter(IllegalStringAdapter.class) private String appendValue; - public StringAppendValueModification() {} + public StringAppendValueModification() { + super(); + } - public StringAppendValueModification(final String appendValue) { + public StringAppendValueModification(String appendValue) { + super(); this.appendValue = appendValue; } + public StringAppendValueModification(StringAppendValueModification other) { + super(other); + appendValue = other.appendValue; + } + @Override - protected String modifyImplementationHook(final String input) { - return input + this.appendValue; + public StringAppendValueModification createCopy() { + return new StringAppendValueModification(this); + } + + @Override + protected String modifyImplementationHook(String input) { + return input != null ? input + appendValue : appendValue; } public String getAppendValue() { - return this.appendValue; + return appendValue; } - public void setAppendValue(final String appendValue) { + public void setAppendValue(String appendValue) { this.appendValue = appendValue; } @Override public VariableModification getModifiedCopy() { - return new StringAppendValueModification(appendValue); + Random r = new Random(); + int index = r.nextInt(appendValue.length()); + char randomChar = (char) r.nextInt(MAX_EXPLICIT_VALUE); + StringBuilder modifiedString = new StringBuilder(appendValue); + modifiedString.setCharAt(index, randomChar); + return new StringAppendValueModification(modifiedString.toString()); } @Override public int hashCode() { - int hash = 4; - hash = 83 * hash + Objects.hashCode(this.appendValue); + int hash = 7; + hash = 31 * hash + appendValue.hashCode(); return hash; } @@ -64,7 +87,16 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final StringAppendValueModification other = (StringAppendValueModification) obj; - return Objects.equals(this.appendValue, other.getAppendValue()); + StringAppendValueModification other = (StringAppendValueModification) obj; + return Objects.equals(appendValue, other.appendValue); + } + + @Override + public String toString() { + return "StringAppendValueModification{" + + "appendValue='" + + backslashEscapeString(appendValue) + + '\'' + + '}'; } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/string/StringDeleteModification.java b/src/main/java/de/rub/nds/modifiablevariable/string/StringDeleteModification.java new file mode 100644 index 00000000..aea4e26f --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/string/StringDeleteModification.java @@ -0,0 +1,150 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.string; + +import de.rub.nds.modifiablevariable.VariableModification; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import java.util.Objects; +import java.util.Random; + +/** Modification that deletes part of a string from the original value. */ +@XmlRootElement +@XmlType(propOrder = {"count", "startPosition", "modificationFilter"}) +public class StringDeleteModification extends VariableModification { + + private static final int MAX_MODIFIER_LENGTH = 32; + + private int count; + + private int startPosition; + + public StringDeleteModification() { + super(); + } + + public StringDeleteModification(int startPosition, int count) { + super(); + this.startPosition = startPosition; + this.count = count; + } + + public StringDeleteModification(StringDeleteModification other) { + super(other); + count = other.count; + startPosition = other.startPosition; + } + + @Override + public StringDeleteModification createCopy() { + return new StringDeleteModification(this); + } + + @Override + protected String modifyImplementationHook(String input) { + if (input == null) { + return null; + } + if (input.isEmpty()) { + return input; + } + + // Wrap around and also allow to delete at the end of the original value + int deleteStartPosition = startPosition % input.length(); + if (startPosition < 0) { + deleteStartPosition += input.length() - 1; + } + + // If the end position overflows, it is fixed at the end of the string + int deleteEndPosition = deleteStartPosition + Math.max(0, count); + if (deleteEndPosition > input.length()) { + deleteEndPosition = input.length(); + } + + return new StringBuilder(input).delete(deleteStartPosition, deleteEndPosition).toString(); + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + public int getStartPosition() { + return startPosition; + } + + public void setStartPosition(int startPosition) { + this.startPosition = startPosition; + } + + @Override + public VariableModification getModifiedCopy() { + Random r = new Random(); + + if (r.nextBoolean()) { + int modifier = r.nextInt(MAX_MODIFIER_LENGTH); + if (r.nextBoolean()) { + modifier *= -1; + } + modifier = count + modifier; + if (modifier <= 0) { + modifier = 1; + } + return new StringDeleteModification(modifier, startPosition); + } else { + int modifier = r.nextInt(MAX_MODIFIER_LENGTH); + if (r.nextBoolean()) { + modifier *= -1; + } + modifier = startPosition + modifier; + if (modifier <= 0) { + modifier = 1; + } + return new StringDeleteModification(count, modifier); + } + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + count; + hash = 31 * hash + startPosition; + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + StringDeleteModification other = (StringDeleteModification) obj; + if (startPosition != other.startPosition) { + return false; + } + return Objects.equals(count, other.count); + } + + @Override + public String toString() { + return "StringDeleteModification{" + + "count=" + + count + + ", startPosition=" + + startPosition + + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/string/StringExplicitValueFromFileModification.java b/src/main/java/de/rub/nds/modifiablevariable/string/StringExplicitValueFromFileModification.java new file mode 100644 index 00000000..4c429947 --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/string/StringExplicitValueFromFileModification.java @@ -0,0 +1,91 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.string; + +import static de.rub.nds.modifiablevariable.util.StringUtil.backslashEscapeString; + +import de.rub.nds.modifiablevariable.VariableModification; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import java.util.Objects; + +@XmlRootElement +@XmlType(propOrder = "index") +@XmlAccessorType(XmlAccessType.FIELD) +public class StringExplicitValueFromFileModification extends StringExplicitValueModification { + private int index; + + public StringExplicitValueFromFileModification() { + super(); + } + + public StringExplicitValueFromFileModification(int index, String explicitValue) { + super(explicitValue); + this.index = index; + } + + public StringExplicitValueFromFileModification(StringExplicitValueFromFileModification other) { + super(other); + index = other.index; + } + + @Override + public StringExplicitValueFromFileModification createCopy() { + return new StringExplicitValueFromFileModification(this); + } + + public int getIndex() { + return index; + } + + @Override + public VariableModification getModifiedCopy() { + throw new UnsupportedOperationException( + "Cannot set modify Value of StringExplicitValueFromFileModification"); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + index; + hash = 31 * hash + explicitValue.hashCode(); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + StringExplicitValueFromFileModification other = + (StringExplicitValueFromFileModification) obj; + if (index != other.index) { + return false; + } + return Objects.equals(explicitValue, other.explicitValue); + } + + @Override + public String toString() { + return "StringExplicitValueFromFileModification{" + + "index=" + + index + + ", explicitValue='" + + backslashEscapeString(explicitValue) + + '\'' + + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/string/StringExplicitValueModification.java b/src/main/java/de/rub/nds/modifiablevariable/string/StringExplicitValueModification.java index c328c811..f2f9bdd2 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/string/StringExplicitValueModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/string/StringExplicitValueModification.java @@ -7,27 +7,45 @@ */ package de.rub.nds.modifiablevariable.string; +import static de.rub.nds.modifiablevariable.util.StringUtil.backslashEscapeString; + import de.rub.nds.modifiablevariable.VariableModification; import de.rub.nds.modifiablevariable.util.IllegalStringAdapter; import jakarta.xml.bind.annotation.XmlRootElement; import jakarta.xml.bind.annotation.XmlType; import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import java.util.Objects; +import java.util.Random; /** */ @XmlRootElement @XmlType(propOrder = {"explicitValue", "modificationFilter"}) public class StringExplicitValueModification extends VariableModification { + private static final int MAX_EXPLICIT_VALUE = 256; + @XmlJavaTypeAdapter(IllegalStringAdapter.class) - private String explicitValue; + protected String explicitValue; - public StringExplicitValueModification() {} + public StringExplicitValueModification() { + super(); + } public StringExplicitValueModification(String explicitValue) { + super(); this.explicitValue = explicitValue; } + public StringExplicitValueModification(StringExplicitValueModification other) { + super(other); + explicitValue = other.explicitValue; + } + + @Override + public StringExplicitValueModification createCopy() { + return new StringExplicitValueModification(this); + } + @Override protected String modifyImplementationHook(String input) { return explicitValue; @@ -43,13 +61,21 @@ public void setExplicitValue(String explicitValue) { @Override public VariableModification getModifiedCopy() { - return new StringExplicitValueModification(explicitValue); + if (explicitValue.isEmpty()) { + return this; + } + Random r = new Random(); + int index = r.nextInt(explicitValue.length()); + char randomChar = (char) r.nextInt(MAX_EXPLICIT_VALUE); + StringBuilder modifiedString = new StringBuilder(explicitValue); + modifiedString.setCharAt(index, randomChar); + return new StringExplicitValueModification(modifiedString.toString()); } @Override public int hashCode() { - int hash = 3; - hash = 83 * hash + Objects.hashCode(this.explicitValue); + int hash = 7; + hash = 31 * hash + explicitValue.hashCode(); return hash; } @@ -64,10 +90,16 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final StringExplicitValueModification other = (StringExplicitValueModification) obj; - if (!Objects.equals(this.explicitValue, other.explicitValue)) { - return false; - } - return true; + StringExplicitValueModification other = (StringExplicitValueModification) obj; + return Objects.equals(explicitValue, other.explicitValue); + } + + @Override + public String toString() { + return "StringExplicitValueModification{" + + "explicitValue='" + + backslashEscapeString(explicitValue) + + '\'' + + '}'; } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/string/StringInsertValueModification.java b/src/main/java/de/rub/nds/modifiablevariable/string/StringInsertValueModification.java new file mode 100644 index 00000000..595d92db --- /dev/null +++ b/src/main/java/de/rub/nds/modifiablevariable/string/StringInsertValueModification.java @@ -0,0 +1,144 @@ +/* + * ModifiableVariable - A Variable Concept for Runtime Modifications + * + * Ruhr University Bochum, Paderborn University, Technology Innovation Institute, and Hackmanit GmbH + * + * Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 + */ +package de.rub.nds.modifiablevariable.string; + +import static de.rub.nds.modifiablevariable.util.StringUtil.backslashEscapeString; + +import de.rub.nds.modifiablevariable.VariableModification; +import de.rub.nds.modifiablevariable.util.IllegalStringAdapter; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import java.util.Objects; +import java.util.Random; + +/** Modification that inserts a string to the original value. */ +@XmlRootElement +@XmlType(propOrder = {"insertValue", "startPosition", "modificationFilter"}) +public class StringInsertValueModification extends VariableModification { + + private static final int MAX_EXPLICIT_VALUE = 256; + + private static final int MAX_INSERT_MODIFIER = 32; + + @XmlJavaTypeAdapter(IllegalStringAdapter.class) + private String insertValue; + + private int startPosition; + + public StringInsertValueModification() { + super(); + } + + public StringInsertValueModification(String insertValue, int startPosition) { + super(); + this.insertValue = insertValue; + this.startPosition = startPosition; + } + + public StringInsertValueModification(StringInsertValueModification other) { + super(other); + insertValue = other.insertValue; + startPosition = other.startPosition; + } + + @Override + public StringInsertValueModification createCopy() { + return new StringInsertValueModification(this); + } + + @Override + protected String modifyImplementationHook(String input) { + if (input == null) { + return null; + } + // Wrap around and also allow to insert at the end of the original value + int insertPosition = startPosition % (input.length() + 1); + if (startPosition < 0) { + insertPosition += input.length(); + } + + return new StringBuilder(input).insert(insertPosition, insertValue).toString(); + } + + public String getInsertValue() { + return insertValue; + } + + public void setInsertValue(String insertValue) { + this.insertValue = insertValue; + } + + public int getStartPosition() { + return startPosition; + } + + public void setStartPosition(int startPosition) { + this.startPosition = startPosition; + } + + @Override + public VariableModification getModifiedCopy() { + Random r = new Random(); + + if (r.nextBoolean()) { + int index = r.nextInt(insertValue.length()); + char randomChar = (char) r.nextInt(MAX_EXPLICIT_VALUE); + StringBuilder modifiedString = new StringBuilder(insertValue); + modifiedString.setCharAt(index, randomChar); + return new StringInsertValueModification(modifiedString.toString(), startPosition); + } else { + int modifier = r.nextInt(MAX_INSERT_MODIFIER); + if (r.nextBoolean()) { + modifier *= -1; + } + modifier = startPosition + modifier; + if (modifier <= 0) { + modifier = 1; + } + return new StringInsertValueModification(insertValue, modifier); + } + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + insertValue.hashCode(); + hash = 31 * hash + startPosition; + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + StringInsertValueModification other = (StringInsertValueModification) obj; + if (startPosition != other.startPosition) { + return false; + } + return Objects.equals(insertValue, other.insertValue); + } + + @Override + public String toString() { + return "StringInsertValueModification{" + + "insertValue='" + + backslashEscapeString(insertValue) + + '\'' + + ", startPosition=" + + startPosition + + '}'; + } +} diff --git a/src/main/java/de/rub/nds/modifiablevariable/string/StringModificationFactory.java b/src/main/java/de/rub/nds/modifiablevariable/string/StringModificationFactory.java index c6c95710..b7d5709e 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/string/StringModificationFactory.java +++ b/src/main/java/de/rub/nds/modifiablevariable/string/StringModificationFactory.java @@ -9,28 +9,102 @@ import de.rub.nds.modifiablevariable.VariableModification; import de.rub.nds.modifiablevariable.util.RandomHelper; +import java.util.Random; /** */ -public class StringModificationFactory { +public final class StringModificationFactory { - private static final int MAX_BYTE_LENGTH = 1000; + private StringModificationFactory() { + super(); + } + + private enum ModificationType { + APPEND, + PREPEND, + EXPLICIT, + INSERT, + DELETE + } + + private static final int MODIFICATION_COUNT = ModificationType.values().length; + + private static final int MAX_BYTE_LENGTH_INSERT = 200; + + private static final int MAX_BYTE_LENGTH_EXPLICIT = 1000; - public static VariableModification prependValue(final String value) { + private static final int MODIFIED_STRING_LENGTH_ESTIMATION = 50; + + public static VariableModification prependValue(String value) { return new StringPrependValueModification(value); } - public static VariableModification appendValue(final String value) { + public static VariableModification appendValue(String value) { return new StringAppendValueModification(value); } - public static VariableModification explicitValue(final String value) { + public static VariableModification explicitValue(String value) { return new StringExplicitValueModification(value); } - public static VariableModification createRandomModification() { - int i = RandomHelper.getRandom().nextInt(MAX_BYTE_LENGTH); - byte[] randomBytes = new byte[i]; - RandomHelper.getRandom().nextBytes(randomBytes); - return explicitValue(new String(randomBytes)); + public static VariableModification insertValue(String value, int position) { + return new StringInsertValueModification(value, position); + } + + public static VariableModification delete(int startPosition, int count) { + return new StringDeleteModification(startPosition, count); + } + + public static VariableModification createRandomModification(String originalValue) { + Random random = RandomHelper.getRandom(); + ModificationType randomType = ModificationType.values()[random.nextInt(MODIFICATION_COUNT)]; + int modificationArrayLength; + int modifiedArrayLength; + if (originalValue == null) { + modifiedArrayLength = MODIFIED_STRING_LENGTH_ESTIMATION; + } else { + modifiedArrayLength = originalValue.length(); + if (modifiedArrayLength == 0 || modifiedArrayLength == 1) { + randomType = ModificationType.EXPLICIT; + } + } + switch (randomType) { + case APPEND: + modificationArrayLength = random.nextInt(MAX_BYTE_LENGTH_INSERT); + if (modificationArrayLength == 0) { + modificationArrayLength++; + } + byte[] bytesToAppend = new byte[modificationArrayLength]; + random.nextBytes(bytesToAppend); + return new StringAppendValueModification(new String(bytesToAppend)); + case PREPEND: + modificationArrayLength = random.nextInt(MAX_BYTE_LENGTH_INSERT); + if (modificationArrayLength == 0) { + modificationArrayLength++; + } + byte[] bytesToPrepend = new byte[modificationArrayLength]; + random.nextBytes(bytesToPrepend); + return new StringPrependValueModification(new String(bytesToPrepend)); + case EXPLICIT: + modificationArrayLength = random.nextInt(MAX_BYTE_LENGTH_EXPLICIT); + byte[] explicitValue = new byte[modificationArrayLength]; + random.nextBytes(explicitValue); + return new StringExplicitValueModification(new String(explicitValue)); + case INSERT: + modificationArrayLength = random.nextInt(MAX_BYTE_LENGTH_INSERT); + if (modificationArrayLength == 0) { + modificationArrayLength++; + } + byte[] bytesToInsert = new byte[modificationArrayLength]; + random.nextBytes(bytesToInsert); + int insertPosition = random.nextInt(modifiedArrayLength); + return new StringInsertValueModification(new String(bytesToInsert), insertPosition); + case DELETE: + int startPosition = random.nextInt(modifiedArrayLength - 1); + int count = random.nextInt(modifiedArrayLength - startPosition); + count++; + return new StringDeleteModification(startPosition, count); + default: + throw new IllegalStateException("Unexpected modification type: " + randomType); + } } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/string/StringPrependValueModification.java b/src/main/java/de/rub/nds/modifiablevariable/string/StringPrependValueModification.java index ea4112f5..ef96848c 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/string/StringPrependValueModification.java +++ b/src/main/java/de/rub/nds/modifiablevariable/string/StringPrependValueModification.java @@ -7,49 +7,72 @@ */ package de.rub.nds.modifiablevariable.string; +import static de.rub.nds.modifiablevariable.util.StringUtil.backslashEscapeString; + import de.rub.nds.modifiablevariable.VariableModification; import de.rub.nds.modifiablevariable.util.IllegalStringAdapter; import jakarta.xml.bind.annotation.XmlRootElement; import jakarta.xml.bind.annotation.XmlType; import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import java.util.Objects; +import java.util.Random; /** Modification that prepends a string to the original value. */ @XmlRootElement @XmlType(propOrder = {"prependValue", "modificationFilter"}) public class StringPrependValueModification extends VariableModification { + private static final int MAX_EXPLICIT_VALUE = 256; + @XmlJavaTypeAdapter(IllegalStringAdapter.class) private String prependValue; - public StringPrependValueModification() {} + public StringPrependValueModification() { + super(); + } - public StringPrependValueModification(final String prependValue) { + public StringPrependValueModification(String prependValue) { + super(); this.prependValue = prependValue; } + public StringPrependValueModification(StringPrependValueModification other) { + super(other); + prependValue = other.prependValue; + } + @Override - protected String modifyImplementationHook(final String input) { - return this.prependValue + input; + public StringPrependValueModification createCopy() { + return new StringPrependValueModification(this); + } + + @Override + protected String modifyImplementationHook(String input) { + return input != null ? prependValue + input : prependValue; } public String getPrependValue() { - return this.prependValue; + return prependValue; } - public void setPrependValue(final String prependValue) { + public void setPrependValue(String prependValue) { this.prependValue = prependValue; } @Override public VariableModification getModifiedCopy() { - return new StringPrependValueModification(prependValue); + Random r = new Random(); + int index = r.nextInt(prependValue.length()); + char randomChar = (char) r.nextInt(MAX_EXPLICIT_VALUE); + StringBuilder modifiedString = new StringBuilder(prependValue); + modifiedString.setCharAt(index, randomChar); + return new StringPrependValueModification(modifiedString.toString()); } @Override public int hashCode() { - int hash = 5; - hash = 83 * hash + Objects.hashCode(this.prependValue); + int hash = 7; + hash = 31 * hash + prependValue.hashCode(); return hash; } @@ -64,7 +87,16 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final StringPrependValueModification other = (StringPrependValueModification) obj; - return Objects.equals(this.prependValue, other.getPrependValue()); + StringPrependValueModification other = (StringPrependValueModification) obj; + return Objects.equals(prependValue, other.prependValue); + } + + @Override + public String toString() { + return "StringPrependValueModification{" + + "prependValue='" + + backslashEscapeString(prependValue) + + '\'' + + '}'; } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/util/ArrayConverter.java b/src/main/java/de/rub/nds/modifiablevariable/util/ArrayConverter.java index 4ad63982..7077f9b7 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/util/ArrayConverter.java +++ b/src/main/java/de/rub/nds/modifiablevariable/util/ArrayConverter.java @@ -13,43 +13,77 @@ import java.util.List; /** A utility class to handle arrays and array conversions */ -public class ArrayConverter { +public final class ArrayConverter { + + private ArrayConverter() { + super(); + } /** * Takes a long value and converts it to 8 bytes (needed for example to convert SQN numbers in * TLS records) * - * @param l long value + * @param value long value * @return long represented by 8 bytes */ - public static byte[] longToUint64Bytes(long l) { + public static byte[] longToEightBytes(long value) { byte[] result = new byte[8]; - result[0] = (byte) (l >>> 56); - result[1] = (byte) (l >>> 48); - result[2] = (byte) (l >>> 40); - result[3] = (byte) (l >>> 32); - result[4] = (byte) (l >>> 24); - result[5] = (byte) (l >>> 16); - result[6] = (byte) (l >>> 8); - result[7] = (byte) (l); + result[0] = (byte) (value >>> 56); + result[1] = (byte) (value >>> 48); + result[2] = (byte) (value >>> 40); + result[3] = (byte) (value >>> 32); + result[4] = (byte) (value >>> 24); + result[5] = (byte) (value >>> 16); + result[6] = (byte) (value >>> 8); + result[7] = (byte) value; return result; } + /** Note: This will truncate the long */ + public static byte[] longToSixBytes(long value) { + byte[] output = new byte[6]; + output[0] = (byte) (value >>> 40); + output[1] = (byte) (value >>> 32); + output[2] = (byte) (value >>> 24); + output[3] = (byte) (value >>> 16); + output[4] = (byte) (value >>> 8); + output[5] = (byte) value; + return output; + } + /** - * Takes a long value and converts it to 4 bytes + * Takes an int value and converts it to 4 bytes * - * @param l long value - * @return long represented by 4 bytes + * @param value int value + * @return int represented by 4 bytes */ - public static byte[] longToUint32Bytes(long l) { + public static byte[] intToFourBytes(int value) { byte[] result = new byte[4]; - result[0] = (byte) (l >>> 24); - result[1] = (byte) (l >>> 16); - result[2] = (byte) (l >>> 8); - result[3] = (byte) (l); + result[0] = (byte) (value >>> 24); + result[1] = (byte) (value >>> 16); + result[2] = (byte) (value >>> 8); + result[3] = (byte) value; return result; } + public static long eigthBytesToLong(byte[] bytes) { + return (long) (bytes[0] & 0xFF) << 56 + | (long) (bytes[1] & 0xFF) << 48 + | (long) (bytes[2] & 0xFF) << 40 + | (long) (bytes[3] & 0xFF) << 32 + | (long) (bytes[4] & 0xFF) << 24 + | (long) (bytes[5] & 0xFF) << 16 + | (long) (bytes[6] & 0xFF) << 8 + | (long) (bytes[7] & 0xFF); + } + + public static int fourBytesToInt(byte[] bytes) { + return (bytes[0] & 0xFF) << 24 + | (bytes[1] & 0xFF) << 16 + | (bytes[2] & 0xFF) << 8 + | bytes[3] & 0xFF; + } + /** * Takes an integer value and stores its last bytes into a byte array * @@ -64,7 +98,7 @@ public static byte[] intToBytes(int value, int size) { } byte[] result = new byte[size]; int shift = 0; - int finalPosition = ((size > Integer.BYTES) ? (size - Integer.BYTES) : 0); + int finalPosition = size > Integer.BYTES ? size - Integer.BYTES : 0; for (int i = size - 1; i >= finalPosition; i--) { result[i] = (byte) (value >>> shift); shift += 8; @@ -87,7 +121,7 @@ public static byte[] longToBytes(long value, int size) { } byte[] result = new byte[size]; int shift = 0; - int finalPosition = ((size > Long.BYTES) ? (size - Long.BYTES) : 0); + int finalPosition = size > Long.BYTES ? size - Long.BYTES : 0; for (int i = size - 1; i >= finalPosition; i--) { result[i] = (byte) (value >>> shift); shift += 8; @@ -119,10 +153,10 @@ public static int bytesToInt(byte[] value) { * @return long */ public static long bytesToLong(byte[] value) { - int result = 0; + long result = 0; int shift = 0; for (int i = value.length - 1; i >= 0; i--) { - result += (value[i] & 0xFF) << shift; + result += (long) (value[i] & 0xFF) << shift; shift += 8; } return result; @@ -132,7 +166,7 @@ public static String bytesToHexString(byte[] array) { if (array == null) { array = new byte[0]; } - boolean usePrettyPrinting = (array.length > 15); + boolean usePrettyPrinting = array.length > 15; return bytesToHexString(array, usePrettyPrinting); } @@ -151,10 +185,10 @@ public static String bytesToHexString( } for (int i = 0; i < array.length; i++) { if (i != 0) { - if (usePrettyPrinting && (i % 16 == 0)) { + if (usePrettyPrinting && i % 16 == 0) { result.append("\n"); } else { - if (usePrettyPrinting && (i % 8 == 0)) { + if (usePrettyPrinting && i % 8 == 0) { result.append(" "); } result.append(" "); @@ -188,47 +222,46 @@ public static String bytesToHexString( */ public static String bytesToRawHexString(byte[] array) { StringBuilder result = new StringBuilder(); - for (int i = 0; i < array.length; i++) { - byte b = array[i]; + for (byte b : array) { result.append(String.format("%02X", b)); } return result.toString(); } @SafeVarargs - public static T[] concatenate(final T[]... arrays) { + public static T[] concatenate(T[]... arrays) { if (arrays == null || arrays.length == 0) { throw new IllegalArgumentException( "The minimal number of parameters for this function is one"); } int length = 0; - for (final T[] a : arrays) { + for (T[] a : arrays) { length += a.length; } @SuppressWarnings("unchecked") T[] result = (T[]) Array.newInstance(arrays[0].getClass().getComponentType(), length); int currentOffset = 0; - for (final T[] a : arrays) { + for (T[] a : arrays) { System.arraycopy(a, 0, result, currentOffset, a.length); currentOffset += a.length; } return result; } - public static byte[] concatenate(final byte[]... arrays) { + public static byte[] concatenate(byte[]... arrays) { if (arrays == null || arrays.length == 0) { throw new IllegalArgumentException( "The minimal number of parameters for this function is one"); } int length = 0; - for (final byte[] a : arrays) { + for (byte[] a : arrays) { if (a != null) { length += a.length; } } byte[] result = new byte[length]; int currentOffset = 0; - for (final byte[] a : arrays) { + for (byte[] a : arrays) { if (a != null) { System.arraycopy(a, 0, result, currentOffset, a.length); currentOffset += a.length; @@ -237,8 +270,7 @@ public static byte[] concatenate(final byte[]... arrays) { return result; } - public static byte[] concatenate( - final byte[] array1, final byte[] array2, int numberOfArray2Bytes) { + public static byte[] concatenate(byte[] array1, byte[] array2, int numberOfArray2Bytes) { int length = array1.length + numberOfArray2Bytes; byte[] result = new byte[length]; System.arraycopy(array1, 0, result, 0, array1.length); @@ -246,7 +278,7 @@ public static byte[] concatenate( return result; } - public static void makeArrayNonZero(final byte[] array) { + public static void makeArrayNonZero(byte[] array) { for (int i = 0; i < array.length; i++) { if (array[i] == 0) { array[i] = 1; @@ -332,7 +364,7 @@ public static BigInteger[] convertListToArray(List list) { * @return byte array */ public static byte[] hexStringToByteArray(String input) { - if ((input == null) || (input.length() % 2 != 0)) { + if (input == null || input.length() % 2 != 0) { throw new IllegalArgumentException( "The input must not be null and " + "shall have an even number of hexadecimal characters. Found: " @@ -384,19 +416,6 @@ public static byte[] bigIntegerToNullPaddedByteArray(BigInteger input, int outpu return output; } - public static byte[] longToUint48Bytes(long input) { - byte[] output = new byte[6]; - - output[0] = (byte) (input >>> 40); - output[1] = (byte) (input >>> 32); - output[2] = (byte) (input >>> 24); - output[3] = (byte) (input >>> 16); - output[4] = (byte) (input >>> 8); - output[5] = (byte) input; - - return output; - } - /** * Reverses the order of a byte array: So, [0x00,0x01,0x02,0x03] will be returned as * [0x03,0x02,0x01,0x00] diff --git a/src/main/java/de/rub/nds/modifiablevariable/util/BadFixedRandom.java b/src/main/java/de/rub/nds/modifiablevariable/util/BadFixedRandom.java index e0711eca..b874a58e 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/util/BadFixedRandom.java +++ b/src/main/java/de/rub/nds/modifiablevariable/util/BadFixedRandom.java @@ -15,9 +15,10 @@ */ public class BadFixedRandom extends Random { - byte retVal; + private final byte retVal; public BadFixedRandom(byte retVal) { + super(); this.retVal = retVal; } diff --git a/src/main/java/de/rub/nds/modifiablevariable/util/BadRandom.java b/src/main/java/de/rub/nds/modifiablevariable/util/BadRandom.java index ef8fc6da..c61b16c4 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/util/BadRandom.java +++ b/src/main/java/de/rub/nds/modifiablevariable/util/BadRandom.java @@ -18,14 +18,17 @@ public class BadRandom extends SecureRandom { private Random random; public BadRandom() { + super(); random = new Random(0); } public BadRandom(Random random, byte[] seed) { + super(); this.random = random; } public BadRandom(Random random, SecureRandomSpi secureRandomSpi, Provider provider) { + super(); this.random = random; } @@ -62,8 +65,8 @@ public int nextInt() { } @Override - public int nextInt(int n) { - return random.nextInt(n); + public int nextInt(int bound) { + return random.nextInt(bound); } @Override diff --git a/src/main/java/de/rub/nds/modifiablevariable/util/ComparableByteArray.java b/src/main/java/de/rub/nds/modifiablevariable/util/ComparableByteArray.java index 4c67566a..018daa1e 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/util/ComparableByteArray.java +++ b/src/main/java/de/rub/nds/modifiablevariable/util/ComparableByteArray.java @@ -14,6 +14,7 @@ public class ComparableByteArray { private byte[] array; public ComparableByteArray(byte[] array) { + super(); this.array = array; } @@ -28,7 +29,7 @@ public void setArray(byte[] array) { @Override public int hashCode() { int hash = 7; - hash = 83 * hash + Arrays.hashCode(this.array); + hash = 83 * hash + Arrays.hashCode(array); return hash; } @@ -43,10 +44,7 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) { return false; } - final ComparableByteArray other = (ComparableByteArray) obj; - if (!Arrays.equals(this.array, other.array)) { - return false; - } - return true; + ComparableByteArray other = (ComparableByteArray) obj; + return Arrays.equals(array, other.array); } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/util/Modifiable.java b/src/main/java/de/rub/nds/modifiablevariable/util/Modifiable.java index 80c0d8f2..cf1e2371 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/util/Modifiable.java +++ b/src/main/java/de/rub/nds/modifiablevariable/util/Modifiable.java @@ -10,8 +10,7 @@ import de.rub.nds.modifiablevariable.VariableModification; import de.rub.nds.modifiablevariable.biginteger.BigIntegerModificationFactory; import de.rub.nds.modifiablevariable.biginteger.ModifiableBigInteger; -import de.rub.nds.modifiablevariable.bool.BooleanExplicitValueModification; -import de.rub.nds.modifiablevariable.bool.BooleanToggleModification; +import de.rub.nds.modifiablevariable.bool.BooleanModificationFactory; import de.rub.nds.modifiablevariable.bool.ModifiableBoolean; import de.rub.nds.modifiablevariable.bytearray.ByteArrayModificationFactory; import de.rub.nds.modifiablevariable.bytearray.ModifiableByteArray; @@ -19,6 +18,8 @@ import de.rub.nds.modifiablevariable.integer.ModifiableInteger; import de.rub.nds.modifiablevariable.longint.LongModificationFactory; import de.rub.nds.modifiablevariable.longint.ModifiableLong; +import de.rub.nds.modifiablevariable.path.ModifiablePath; +import de.rub.nds.modifiablevariable.path.PathModificationFactory; import de.rub.nds.modifiablevariable.singlebyte.ByteModificationFactory; import de.rub.nds.modifiablevariable.singlebyte.ModifiableByte; import de.rub.nds.modifiablevariable.string.ModifiableString; @@ -26,7 +27,11 @@ import java.math.BigInteger; @SuppressWarnings("unused") -public class Modifiable { +public final class Modifiable { + + private Modifiable() { + super(); + } private static ModifiableByteArray getModifiableByteArrayWithModification( VariableModification modification) { @@ -77,100 +82,206 @@ private static ModifiableString getModifiableStringWithModification( return modifiableString; } - public static ModifiableString prepend(final String s) { - return getModifiableStringWithModification(StringModificationFactory.prependValue(s)); + private static ModifiablePath getModifiablePathWithModification( + VariableModification modification) { + ModifiablePath modifiablePath = new ModifiablePath(); + modifiablePath.setModification(modification); + return modifiablePath; } - public static ModifiableString append(final String s) { - return getModifiableStringWithModification(StringModificationFactory.appendValue(s)); + public static ModifiableBigInteger prepend(BigInteger perpendValue) { + return getModifiableBigIntegerWithModification( + BigIntegerModificationFactory.prependValue(perpendValue)); } - public static ModifiableByteArray explicit(byte[] b) { + public static ModifiableByteArray prepend(byte[] perpendValue) { return getModifiableByteArrayWithModification( - ByteArrayModificationFactory.explicitValue(b)); + ByteArrayModificationFactory.prependValue(perpendValue)); + } + + public static ModifiableInteger prepend(Integer perpendValue) { + return getModifiableIntegerWithModification( + IntegerModificationFactory.prependValue(perpendValue)); + } + + public static ModifiableLong prepend(Long perpendValue) { + return getModifiableLongWithModification( + LongModificationFactory.prependValue(perpendValue)); } - public static ModifiableByte explicit(Byte b) { - return getModifiableByteWithModification(ByteModificationFactory.explicitValue(b)); + public static ModifiableString prepend(String perpendValue) { + return getModifiableStringWithModification( + StringModificationFactory.prependValue(perpendValue)); } - public static ModifiableInteger explicit(Integer i) { - return getModifiableIntegerWithModification(IntegerModificationFactory.explicitValue(i)); + public static ModifiablePath prependPath(String perpendValue) { + return getModifiablePathWithModification( + PathModificationFactory.prependValue(perpendValue)); } - public static ModifiableBigInteger explicit(BigInteger i) { + public static ModifiableBigInteger append(BigInteger appendValue) { return getModifiableBigIntegerWithModification( - BigIntegerModificationFactory.explicitValue(i)); + BigIntegerModificationFactory.appendValue(appendValue)); } - public static ModifiableLong explicit(Long l) { - return getModifiableLongWithModification(LongModificationFactory.explicitValue(l)); + public static ModifiableByteArray append(byte[] appendValue) { + return getModifiableByteArrayWithModification( + ByteArrayModificationFactory.appendValue(appendValue)); + } + + public static ModifiableInteger append(Integer appendValue) { + return getModifiableIntegerWithModification( + IntegerModificationFactory.appendValue(appendValue)); + } + + public static ModifiableLong append(Long appendValue) { + return getModifiableLongWithModification(LongModificationFactory.appendValue(appendValue)); } - public static ModifiableBoolean explicit(Boolean b) { - return getModifiableBooleanWithModification(new BooleanExplicitValueModification(b)); + public static ModifiableString append(String appendValue) { + return getModifiableStringWithModification( + StringModificationFactory.appendValue(appendValue)); } - public static ModifiableString explicit(String s) { - return getModifiableStringWithModification(StringModificationFactory.explicitValue(s)); + public static ModifiablePath appendPath(String appendValue) { + return getModifiablePathWithModification(PathModificationFactory.appendValue(appendValue)); } - public static ModifiableByteArray xor(byte[] b, int position) { + public static ModifiableByteArray explicit(byte[] explicitValue) { return getModifiableByteArrayWithModification( - ByteArrayModificationFactory.xor(b, position)); + ByteArrayModificationFactory.explicitValue(explicitValue)); } - public static ModifiableByte xor(Byte b) { - return getModifiableByteWithModification(ByteModificationFactory.xor(b)); + public static ModifiableByte explicit(Byte explicitValue) { + return getModifiableByteWithModification( + ByteModificationFactory.explicitValue(explicitValue)); } - public static ModifiableInteger xor(Integer i) { - return getModifiableIntegerWithModification(IntegerModificationFactory.xor(i)); + public static ModifiableInteger explicit(Integer explicitValue) { + return getModifiableIntegerWithModification( + IntegerModificationFactory.explicitValue(explicitValue)); } - public static ModifiableBigInteger xor(BigInteger i) { - return getModifiableBigIntegerWithModification(BigIntegerModificationFactory.xor(i)); + public static ModifiableBigInteger explicit(BigInteger explicitValue) { + return getModifiableBigIntegerWithModification( + BigIntegerModificationFactory.explicitValue(explicitValue)); } - public static ModifiableLong xor(Long l) { - return getModifiableLongWithModification(LongModificationFactory.xor(l)); + public static ModifiableLong explicit(Long explicitValue) { + return getModifiableLongWithModification( + LongModificationFactory.explicitValue(explicitValue)); } - public static ModifiableByte add(Byte b) { - return getModifiableByteWithModification(ByteModificationFactory.add(b)); + public static ModifiableBoolean explicit(Boolean explicitValue) { + return getModifiableBooleanWithModification( + BooleanModificationFactory.explicitValue(explicitValue)); } - public static ModifiableInteger add(Integer i) { - return getModifiableIntegerWithModification(IntegerModificationFactory.add(i)); + public static ModifiableString explicit(String explicitValue) { + return getModifiableStringWithModification( + StringModificationFactory.explicitValue(explicitValue)); } - public static ModifiableBigInteger add(BigInteger i) { - return getModifiableBigIntegerWithModification(BigIntegerModificationFactory.add(i)); + public static ModifiableBigInteger insert(BigInteger insertValue, int position) { + return getModifiableBigIntegerWithModification( + BigIntegerModificationFactory.insertValue(insertValue, position)); } - public static ModifiableLong add(Long l) { - return getModifiableLongWithModification(LongModificationFactory.add(l)); + public static ModifiableByteArray insert(byte[] insertValue, int position) { + return getModifiableByteArrayWithModification( + ByteArrayModificationFactory.insertValue(insertValue, position)); } - public static ModifiableByte sub(Byte b) { - return getModifiableByteWithModification(ByteModificationFactory.sub(b)); + public static ModifiableInteger insert(Integer insertValue, int position) { + return getModifiableIntegerWithModification( + IntegerModificationFactory.insertValue(insertValue, position)); } - public static ModifiableInteger sub(Integer i) { - return getModifiableIntegerWithModification(IntegerModificationFactory.sub(i)); + public static ModifiableLong insert(Long insertValue, int position) { + return getModifiableLongWithModification( + LongModificationFactory.insertValue(insertValue, position)); } - public static ModifiableBigInteger sub(BigInteger i) { - return getModifiableBigIntegerWithModification(BigIntegerModificationFactory.sub(i)); + public static ModifiableString insert(String insertValue, int position) { + return getModifiableStringWithModification( + StringModificationFactory.insertValue(insertValue, position)); } - public static ModifiableLong sub(Long l) { - return getModifiableLongWithModification(LongModificationFactory.sub(l)); + public static ModifiablePath insertPath(String insertValue, int position) { + return getModifiablePathWithModification( + PathModificationFactory.insertValue(insertValue, position)); } - public static ModifiableByteArray insert(byte[] b, int position) { + public static ModifiablePath insertDirectoryTraversal(int count, int position) { + return getModifiablePathWithModification( + PathModificationFactory.insertDirectoryTraversal(count, position)); + } + + public static ModifiablePath insertDirectorySeperator(int count, int position) { + return getModifiablePathWithModification( + PathModificationFactory.insertDirectorySeperator(count, position)); + } + + public static ModifiableByteArray xor(byte[] xor, int position) { return getModifiableByteArrayWithModification( - ByteArrayModificationFactory.insert(b, position)); + ByteArrayModificationFactory.xor(xor, position)); + } + + public static ModifiableByte xor(Byte xor) { + return getModifiableByteWithModification(ByteModificationFactory.xor(xor)); + } + + public static ModifiableInteger xor(Integer xor) { + return getModifiableIntegerWithModification(IntegerModificationFactory.xor(xor)); + } + + public static ModifiableBigInteger xor(BigInteger xor) { + return getModifiableBigIntegerWithModification(BigIntegerModificationFactory.xor(xor)); + } + + public static ModifiableLong xor(Long xor) { + return getModifiableLongWithModification(LongModificationFactory.xor(xor)); + } + + public static ModifiableInteger swapEndianIntger() { + return getModifiableIntegerWithModification(IntegerModificationFactory.swapEndian()); + } + + public static ModifiableLong swapEndianLong() { + return getModifiableLongWithModification(LongModificationFactory.swapEndian()); + } + + public static ModifiableByte add(Byte summand) { + return getModifiableByteWithModification(ByteModificationFactory.add(summand)); + } + + public static ModifiableInteger add(Integer summand) { + return getModifiableIntegerWithModification(IntegerModificationFactory.add(summand)); + } + + public static ModifiableBigInteger add(BigInteger summand) { + return getModifiableBigIntegerWithModification(BigIntegerModificationFactory.add(summand)); + } + + public static ModifiableLong add(Long summand) { + return getModifiableLongWithModification(LongModificationFactory.add(summand)); + } + + public static ModifiableByte sub(Byte subtrahend) { + return getModifiableByteWithModification(ByteModificationFactory.sub(subtrahend)); + } + + public static ModifiableInteger sub(Integer subtrahend) { + return getModifiableIntegerWithModification(IntegerModificationFactory.sub(subtrahend)); + } + + public static ModifiableBigInteger sub(BigInteger subtrahend) { + return getModifiableBigIntegerWithModification( + BigIntegerModificationFactory.sub(subtrahend)); + } + + public static ModifiableLong sub(Long subtrahend) { + return getModifiableLongWithModification(LongModificationFactory.sub(subtrahend)); } public static ModifiableByteArray delete(int startPosition, int count) { @@ -188,26 +299,49 @@ public static ModifiableByteArray duplicate() { } public static ModifiableBoolean toggle() { - return getModifiableBooleanWithModification(new BooleanToggleModification()); + return getModifiableBooleanWithModification(BooleanModificationFactory.toggle()); + } + + public static ModifiablePath toggleRoot() { + return getModifiablePathWithModification(PathModificationFactory.toggleRoot()); } - public static ModifiableBigInteger shiftLeftBigInteger(Integer i) { - return getModifiableBigIntegerWithModification(BigIntegerModificationFactory.shiftLeft(i)); + public static ModifiableBigInteger shiftLeftBigInteger(Integer shift) { + return getModifiableBigIntegerWithModification( + BigIntegerModificationFactory.shiftLeft(shift)); + } + + public static ModifiableInteger shiftLeft(Integer shift) { + return getModifiableIntegerWithModification(IntegerModificationFactory.shiftLeft(shift)); } - public static ModifiableInteger shiftLeft(Integer i) { - return getModifiableIntegerWithModification(IntegerModificationFactory.shiftLeft(i)); + public static ModifiableLong shiftLeftLong(Integer shift) { + return getModifiableLongWithModification(LongModificationFactory.shiftLeft(shift)); } - public static ModifiableBigInteger shiftRightBigInteger(Integer i) { - return getModifiableBigIntegerWithModification(BigIntegerModificationFactory.shiftRight(i)); + public static ModifiableBigInteger shiftRightBigInteger(Integer shift) { + return getModifiableBigIntegerWithModification( + BigIntegerModificationFactory.shiftRight(shift)); + } + + public static ModifiableInteger shiftRight(Integer shift) { + return getModifiableIntegerWithModification(IntegerModificationFactory.shiftRight(shift)); + } + + public static ModifiableLong shiftRightLong(Integer shift) { + return getModifiableLongWithModification(LongModificationFactory.shiftRight(shift)); + } + + public static ModifiableBigInteger multiplyBigInteger(BigInteger factor) { + return getModifiableBigIntegerWithModification( + BigIntegerModificationFactory.multiply(factor)); } - public static ModifiableBigInteger multiplyBigInteger(BigInteger i) { - return getModifiableBigIntegerWithModification(BigIntegerModificationFactory.multiply(i)); + public static ModifiableInteger multiply(Integer factor) { + return getModifiableIntegerWithModification(IntegerModificationFactory.multiply(factor)); } - public static ModifiableInteger shiftRight(Integer i) { - return getModifiableIntegerWithModification(IntegerModificationFactory.shiftRight(i)); + public static ModifiableLong multiply(Long factor) { + return getModifiableLongWithModification(LongModificationFactory.multiply(factor)); } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/util/ModifiableVariableAnalyzer.java b/src/main/java/de/rub/nds/modifiablevariable/util/ModifiableVariableAnalyzer.java index 2ceead42..e09c6927 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/util/ModifiableVariableAnalyzer.java +++ b/src/main/java/de/rub/nds/modifiablevariable/util/ModifiableVariableAnalyzer.java @@ -16,10 +16,14 @@ import org.apache.logging.log4j.Logger; /** */ -public class ModifiableVariableAnalyzer { +public final class ModifiableVariableAnalyzer { private static final Logger LOGGER = LogManager.getLogger(ModifiableVariableAnalyzer.class); + private ModifiableVariableAnalyzer() { + super(); + } + /** * Lists all the modifiable variables declared in the given class * @@ -67,8 +71,8 @@ public static List getAllModifiableVariableFieldsRecurs getAllModifiableVariableHoldersRecursively(object); List fields = new LinkedList<>(); for (ModifiableVariableListHolder holder : holders) { - for (Field f : holder.getFields()) { - fields.add(new ModifiableVariableField(holder.getObject(), f)); + for (Field field : holder.getFields()) { + fields.add(new ModifiableVariableField(holder.getObject(), field)); } } return fields; @@ -89,16 +93,16 @@ public static List getAllModifiableVariableHolders holders.add(new ModifiableVariableListHolder(object, modFields)); } List allFields = ReflectionHelper.getFieldsUpTo(object.getClass(), null, null); - for (Field f : allFields) { + for (Field field : allFields) { try { HoldsModifiableVariable holdsVariable = - f.getAnnotation(HoldsModifiableVariable.class); - f.setAccessible(true); - Object possibleHolder = f.get(object); + field.getAnnotation(HoldsModifiableVariable.class); + field.setAccessible(true); + Object possibleHolder = field.get(object); if (possibleHolder != null && holdsVariable != null) { if (possibleHolder instanceof List) { @SuppressWarnings("unchecked") - List castedList = List.class.cast(possibleHolder); + List castedList = (List) possibleHolder; holders.addAll(getAllModifiableVariableHoldersFromList(castedList)); } else if (possibleHolder.getClass().isArray()) { holders.addAll( @@ -111,8 +115,8 @@ public static List getAllModifiableVariableHolders } catch (IllegalAccessException | IllegalArgumentException ex) { LOGGER.debug( "Accessing field {} of type {} not possible: {}", - f.getName(), - f.getType(), + field.getName(), + field.getType(), ex.toString()); } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/util/ModifiableVariableField.java b/src/main/java/de/rub/nds/modifiablevariable/util/ModifiableVariableField.java index a6946731..95e3dd4e 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/util/ModifiableVariableField.java +++ b/src/main/java/de/rub/nds/modifiablevariable/util/ModifiableVariableField.java @@ -17,11 +17,14 @@ public class ModifiableVariableField { private Field field; - public ModifiableVariableField() {} + public ModifiableVariableField() { + super(); + } - public ModifiableVariableField(Object o, Field f) { - this.object = o; - this.field = f; + public ModifiableVariableField(Object o, Field field) { + super(); + object = o; + this.field = field; } public Object getObject() { diff --git a/src/main/java/de/rub/nds/modifiablevariable/util/ModifiableVariableListHolder.java b/src/main/java/de/rub/nds/modifiablevariable/util/ModifiableVariableListHolder.java index 84d2a454..732eb483 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/util/ModifiableVariableListHolder.java +++ b/src/main/java/de/rub/nds/modifiablevariable/util/ModifiableVariableListHolder.java @@ -20,11 +20,14 @@ public class ModifiableVariableListHolder { private List fields; - public ModifiableVariableListHolder() {} + public ModifiableVariableListHolder() { + super(); + } - public ModifiableVariableListHolder(Object o, List f) { - this.object = o; - this.fields = f; + public ModifiableVariableListHolder(Object o, List fields) { + super(); + object = o; + this.fields = fields; } public Object getObject() { diff --git a/src/main/java/de/rub/nds/modifiablevariable/util/RandomHelper.java b/src/main/java/de/rub/nds/modifiablevariable/util/RandomHelper.java index b851fccf..96bdb56b 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/util/RandomHelper.java +++ b/src/main/java/de/rub/nds/modifiablevariable/util/RandomHelper.java @@ -10,7 +10,7 @@ import java.util.Random; /** */ -public class RandomHelper { +public final class RandomHelper { private static Random random; @@ -29,5 +29,7 @@ public static void setRandom(Random random) { RandomHelper.random = random; } - private RandomHelper() {} + private RandomHelper() { + super(); + } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/util/ReflectionHelper.java b/src/main/java/de/rub/nds/modifiablevariable/util/ReflectionHelper.java index 23d0498e..699fc39d 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/util/ReflectionHelper.java +++ b/src/main/java/de/rub/nds/modifiablevariable/util/ReflectionHelper.java @@ -14,10 +14,15 @@ import java.util.LinkedList; import java.util.List; -public class ReflectionHelper { +public final class ReflectionHelper { + + private ReflectionHelper() { + super(); + } /** - * Source: http://stackoverflow.com/questions/17451506/list-all-private-fields -of-a-java-object + * Source: ... * Retrieves all fields (all access levels) from all classes up the class hierarchy starting * with {@code startClass} stopping with and not including {@code exclusiveParent}. Generally * {@code Object.class} should be passed as {@code exclusiveParent}. @@ -37,8 +42,7 @@ public static List getFieldsUpTo( Class parentClass = startClass.getSuperclass(); - if ((parentClass != null) - && ((exclusiveParent == null) || !(parentClass.equals(exclusiveParent)))) { + if (parentClass != null && !parentClass.equals(exclusiveParent)) { List parentClassFields = getFieldsUpTo(parentClass, exclusiveParent, filterClass); @@ -52,9 +56,9 @@ public static List getFieldsUpTo( private static List filterFieldList(List fields, Class filterClass) { List filteredFields = new LinkedList<>(); - for (Field f : fields) { - if ((filterClass == null) || filterClass.isAssignableFrom(f.getType())) { - filteredFields.add(f); + for (Field field : fields) { + if (filterClass == null || filterClass.isAssignableFrom(field.getType())) { + filteredFields.add(field); } } @@ -65,47 +69,14 @@ public static List getValuesFromFieldList(Object object, List fie throws IllegalAccessException { List list = new LinkedList<>(); - for (Field f : fields) { - f.setAccessible(true); - list.add(f.get(object)); + for (Field field : fields) { + field.setAccessible(true); + list.add(field.get(object)); } return list; } - // /** - // * - // * @param object - // * @param field - // * @return - // * @throws IllegalAccessException - // * @throws java.lang.reflect.InvocationTargetException - // */ - // public static Object getFieldValue(Object object, Field field) throws - // IllegalAccessException, IllegalArgumentException, - // InvocationTargetException { - // Method[] methods = object.getClass().getMethods(); - // for (Method method : methods) { - // String name = method.getName(); - // if (name.equalsIgnoreCase("get" + field.getName())) { - // return method.invoke(object); - // } - // } - // return null; - // } - // - // public static void setFieldValue(Object object, Field field, Object - // value) throws - // IllegalAccessException, IllegalArgumentException, - // InvocationTargetException { - // Method[] methods = object.getClass().getMethods(); - // for (Method method : methods) { - // String name = method.getName(); - // if (name.equalsIgnoreCase("set" + field.getName())) { - // method.invoke(object, value); - // } - // } - // } public static Type[] getParameterizedTypes(Object object) { Type superclassType = object.getClass().getGenericSuperclass(); diff --git a/src/main/java/de/rub/nds/modifiablevariable/util/StringUtil.java b/src/main/java/de/rub/nds/modifiablevariable/util/StringUtil.java index bc07ffa6..947926b5 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/util/StringUtil.java +++ b/src/main/java/de/rub/nds/modifiablevariable/util/StringUtil.java @@ -7,10 +7,12 @@ */ package de.rub.nds.modifiablevariable.util; -public class StringUtil { +public final class StringUtil { // Private constructor, because this is a utility class that is not meant // to be instantiated. - private StringUtil() {} + private StringUtil() { + super(); + } static final int HI_SURROGATE_START = 0xD800; @@ -21,10 +23,13 @@ private StringUtil() {} * @param value string that may contain non-printable or non-ascii chars * @return string with non-printable or non-ascii characters replaced */ - public static String backslashEscapeString(final String value) { - final StringBuffer buffer = new StringBuffer(value); - for (int i = 0; i < buffer.length(); i++) { - final int codePoint = buffer.codePointAt(i); + public static String backslashEscapeString(String value) { + if (value == null) { + return null; + } + StringBuilder builder = new StringBuilder(value); + for (int i = 0; i < builder.length(); i++) { + int codePoint = builder.codePointAt(i); String replacement; int numCodePoints = 1; switch (codePoint) { @@ -68,10 +73,10 @@ public static String backslashEscapeString(final String value) { } } - buffer.replace(i, i + numCodePoints, replacement); + builder.replace(i, i + numCodePoints, replacement); i += replacement.length() - 1; } - return buffer.toString(); + return builder.toString(); } } diff --git a/src/main/java/de/rub/nds/modifiablevariable/util/SuppressingBooleanAdapter.java b/src/main/java/de/rub/nds/modifiablevariable/util/SuppressingBooleanAdapter.java index 3a9c5dda..f16a0de9 100644 --- a/src/main/java/de/rub/nds/modifiablevariable/util/SuppressingBooleanAdapter.java +++ b/src/main/java/de/rub/nds/modifiablevariable/util/SuppressingBooleanAdapter.java @@ -15,7 +15,7 @@ public abstract class SuppressingBooleanAdapter extends XmlAdapter modifier = + BigIntegerModificationFactory.insertValue(BigInteger.valueOf(7), 4); + start.setModification(modifier); + BigInteger mask = BigInteger.valueOf((1L << 3) - 1).shiftLeft(4); + expectedResult = BigInteger.valueOf(7); + result = start.getValue().and(mask).shiftRight(4); + assertEquals(expectedResult, result); + assertEquals(BigInteger.valueOf(10), start.getOriginalValue()); + + // expect: x111xxx + modifier = BigIntegerModificationFactory.insertValue(BigInteger.valueOf(7), 3); + start.setModification(modifier); + mask = BigInteger.valueOf((1L << 3) - 1).shiftLeft(3); + expectedResult = BigInteger.valueOf(7); + result = start.getValue().and(mask).shiftRight(3); + assertEquals(expectedResult, result); + } + /** Test of add method, of class BigIntegerModificationFactory. */ @Test public void testIsOriginalValueModified() { @@ -131,7 +152,7 @@ public void testExplicitValueFromFile() { result = start.getValue(); assertEquals(expectedResult, result); - modifier = BigIntegerModificationFactory.explicitValueFromFile(26); + modifier = BigIntegerModificationFactory.explicitValueFromFile(27); start.setModification(modifier); expectedResult = BigInteger.valueOf(2147483647); result = start.getValue(); diff --git a/src/test/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerOperationConcatenationTest.java b/src/test/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerOperationConcatenationTest.java index da0d468b..a17cfba0 100644 --- a/src/test/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerOperationConcatenationTest.java +++ b/src/test/java/de/rub/nds/modifiablevariable/biginteger/BigIntegerOperationConcatenationTest.java @@ -39,16 +39,12 @@ protected BigInteger modifyImplementationHook(BigInteger input) { @Override public VariableModification getModifiedCopy() { - throw new UnsupportedOperationException("Not supported yet."); // To - // change - // body - // of - // generated - // methods, - // choose - // Tools - // | - // Templates. + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public VariableModification createCopy() { + throw new UnsupportedOperationException("Not supported yet."); } }); expectedResult = new BigInteger("13"); diff --git a/src/test/java/de/rub/nds/modifiablevariable/biginteger/ModifiableBigIntegerTest.java b/src/test/java/de/rub/nds/modifiablevariable/biginteger/ModifiableBigIntegerTest.java index 2c391030..620d291f 100644 --- a/src/test/java/de/rub/nds/modifiablevariable/biginteger/ModifiableBigIntegerTest.java +++ b/src/test/java/de/rub/nds/modifiablevariable/biginteger/ModifiableBigIntegerTest.java @@ -32,7 +32,7 @@ public void setUp() { /** Test of createRandomModification method, of class ModifiableBigInteger. */ @Disabled("Not yet implemented") @Test - public void testCreateRandomModification() {} + public void testSetRandomModification() {} /** Test of getAssertEquals method, of class ModifiableBigInteger. */ @Disabled("Not yet implemented") diff --git a/src/test/java/de/rub/nds/modifiablevariable/bool/ModifiableBooleanTest.java b/src/test/java/de/rub/nds/modifiablevariable/bool/ModifiableBooleanTest.java index c95fc2c9..994b489c 100644 --- a/src/test/java/de/rub/nds/modifiablevariable/bool/ModifiableBooleanTest.java +++ b/src/test/java/de/rub/nds/modifiablevariable/bool/ModifiableBooleanTest.java @@ -41,7 +41,7 @@ public void testSetOriginalValue() {} /** Test of createRandomModification method, of class ModifiableBoolean. */ @Disabled("Not yet implemented") @Test - public void testCreateRandomModification() {} + public void testSetRandomModification() {} /** Test of isOriginalValueModified method, of class ModifiableBoolean. */ @Disabled("Not yet implemented") diff --git a/src/test/java/de/rub/nds/modifiablevariable/bytearray/ModifiableByteArrayTest.java b/src/test/java/de/rub/nds/modifiablevariable/bytearray/ModifiableByteArrayTest.java index c0305224..37563bf2 100644 --- a/src/test/java/de/rub/nds/modifiablevariable/bytearray/ModifiableByteArrayTest.java +++ b/src/test/java/de/rub/nds/modifiablevariable/bytearray/ModifiableByteArrayTest.java @@ -13,6 +13,7 @@ import de.rub.nds.modifiablevariable.ModifiableVariableFactory; import de.rub.nds.modifiablevariable.VariableModification; import de.rub.nds.modifiablevariable.util.ArrayConverter; +import java.util.Arrays; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.junit.jupiter.api.BeforeEach; @@ -20,7 +21,7 @@ public class ModifiableByteArrayTest { - private static final Logger LOGGER = LogManager.getLogger(ModifiableByteArray.class); + private static final Logger LOGGER = LogManager.getLogger(); private ModifiableByteArray start; @@ -78,9 +79,13 @@ public void testXorFirstBytes() { assertArrayEquals(expResult, start.getValue()); + byte[] expResult2 = originalValue.clone(); + for (int i = 0; i < originalValue.length; i++) { + expResult2[i] = (byte) (originalValue[i] ^ modification2[i]); + } VariableModification modifier2 = ByteArrayModificationFactory.xor(modification2, 0); start.setModification(modifier2); - assertArrayEquals(originalValue, start.getValue()); + assertArrayEquals(expResult2, start.getValue()); } /** Test of setXorLastBytes method, of class ModifiableByteArray. */ @@ -102,10 +107,15 @@ public void testXorLastBytes() { LOGGER.debug("Computed: {}", () -> ArrayConverter.bytesToHexString(start.getValue())); assertArrayEquals(expResult, start.getValue()); + byte[] expResult2 = originalValue.clone(); + for (int i = 0; i < 2; i++) { + expResult2[first + i] = (byte) (originalValue[first + i] ^ modification2[i]); + } + VariableModification modifier2 = ByteArrayModificationFactory.xor(modification2, first); start.setModification(modifier2); - assertArrayEquals(originalValue, start.getValue()); + assertArrayEquals(expResult2, start.getValue()); } /** Test of setPrependBytes method, of class ModifiableByteArray. */ @@ -123,7 +133,7 @@ public void testPrependBytes() { } VariableModification modifier = - ByteArrayModificationFactory.insert(modification1, 0); + ByteArrayModificationFactory.insertValue(modification1, 0); start.setModification(modifier); LOGGER.debug("Expected: {}", expResult); @@ -146,7 +156,7 @@ public void testAppendBytes() { } VariableModification modifier = - ByteArrayModificationFactory.insert(modification1, originalValue.length); + ByteArrayModificationFactory.insertValue(modification1, originalValue.length); start.setModification(modifier); LOGGER.debug("Expected: {}", expResult); @@ -200,6 +210,8 @@ public void testDeleteBytes() { LOGGER.debug("Testing Delete all Bytes"); int len = originalValue.length; byte[] expResult = new byte[0]; + byte[] expResult2 = {(byte) 0, (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5}; + byte[] expResult3 = {(byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6}; VariableModification modifier = ByteArrayModificationFactory.delete(0, len); start.setModification(modifier); @@ -211,7 +223,7 @@ public void testDeleteBytes() { modifier = ByteArrayModificationFactory.delete(0, len + 1); start.setModification(modifier); - assertArrayEquals(start.getValue(), originalValue); + assertArrayEquals(start.getValue(), expResult); start = new ModifiableByteArray(); start.setOriginalValue(originalValue); LOGGER.debug("Testing Delete negative amount"); @@ -227,42 +239,55 @@ public void testDeleteBytes() { start = new ModifiableByteArray(); start.setOriginalValue(originalValue); LOGGER.debug("Testing Delete from negative Start position"); - modifier = ByteArrayModificationFactory.delete(len * -2, modification1.length); + modifier = ByteArrayModificationFactory.delete(len * -2, 1); start.setModification(modifier); - assertArrayEquals(start.getValue(), originalValue); + assertArrayEquals(start.getValue(), expResult2); start = new ModifiableByteArray(); start.setOriginalValue(originalValue); LOGGER.debug("Testing Delete from to big Start Position"); - modifier = ByteArrayModificationFactory.delete(len * 2, modification1.length); + modifier = ByteArrayModificationFactory.delete(len * 2, 2); start.setModification(modifier); - assertArrayEquals(start.getValue(), originalValue); + assertArrayEquals(start.getValue(), expResult3); } /** Test of setInsertBytes method, of class ModifiableByteArray. */ @Test public void testInsertBytes() { LOGGER.info("testInsertBytes"); - // Insert negative position, insert 0 bytes, insert too far + // Insert at negative position -> wrap around assumeTrue(modification1.length < originalValue.length); - LOGGER.debug("Inserting negative Position"); + LOGGER.debug("Inserting negative at position"); VariableModification modifier = - ByteArrayModificationFactory.insert(modification1, -2 * originalValue.length); + ByteArrayModificationFactory.insertValue(modification1, -2 * originalValue.length); start.setModification(modifier); - assertArrayEquals(start.getValue(), originalValue); + byte[] expResult = + ArrayConverter.concatenate( + Arrays.copyOf(originalValue, 1), + modification1, + Arrays.copyOfRange(originalValue, 1, originalValue.length)); + assertArrayEquals(start.getValue(), expResult); start = new ModifiableByteArray(); start.setOriginalValue(originalValue); LOGGER.debug("Inserting empty Array"); byte[] emptyArray = new byte[0]; - modifier = ByteArrayModificationFactory.insert(emptyArray, 0); + modifier = ByteArrayModificationFactory.insertValue(emptyArray, 0); start.setModification(modifier); assertArrayEquals(originalValue, start.getValue()); + // Insert at too positive position -> wrap around start = new ModifiableByteArray(); start.setOriginalValue(originalValue); - LOGGER.debug("Inserting to big Start position"); - modifier = ByteArrayModificationFactory.insert(modification1, originalValue.length * 2); + LOGGER.debug("Inserting at too large position"); + modifier = + ByteArrayModificationFactory.insertValue(modification1, originalValue.length * 2); start.setModification(modifier); - assertArrayEquals(originalValue, start.getValue()); + expResult = + ArrayConverter.concatenate( + Arrays.copyOf(originalValue, originalValue.length - 1), + modification1, + Arrays.copyOfRange( + originalValue, originalValue.length - 1, originalValue.length)); + assertArrayEquals(expResult, start.getValue()); } /** Test of add method, of class BigIntegerModificationFactory. */ @@ -343,15 +368,7 @@ public void toStringTest() { toTest = ModifiableVariableFactory.safelySetValue( toTest, new byte[] {0x00, 0x11, 0x22, 0x33, 0x44}); - assertEquals("Original byte value is: 00 11 22 33 44", toTest.toString()); - - VariableModification modification = - new ByteArrayExplicitValueModification( - new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}); - toTest.setModification(modification); - assertEquals( - "Actual byte value is: 00 01 02 03 04 05 06 07 08\nOriginal value was: 00 11 22 33 44", - toTest.toString()); + assertEquals("ModifiableByteArray{originalValue=00 11 22 33 44}", toTest.toString()); } @Test diff --git a/src/test/java/de/rub/nds/modifiablevariable/integer/IntegerModificationTest.java b/src/test/java/de/rub/nds/modifiablevariable/integer/IntegerModificationTest.java index 05a7c21f..127c4228 100644 --- a/src/test/java/de/rub/nds/modifiablevariable/integer/IntegerModificationTest.java +++ b/src/test/java/de/rub/nds/modifiablevariable/integer/IntegerModificationTest.java @@ -71,6 +71,18 @@ public void testExplicitValue() { assertEquals(Integer.valueOf(10), start.getOriginalValue()); } + @Test + public void testInsertValue() { + // expect: ...xx111xxxxxxxxxx + VariableModification modifier = IntegerModificationFactory.insertValue(7, 10); + start.setModification(modifier); + int mask = ((1 << 3) - 1) << 10; + expectedResult = 7; + result = (start.getValue() & mask) >> 10; + assertEquals(expectedResult, result); + assertEquals(Integer.valueOf(10), start.getOriginalValue()); + } + @Test public void testShiftLeft() { VariableModification modifier = IntegerModificationFactory.shiftLeft(2); diff --git a/src/test/java/de/rub/nds/modifiablevariable/integer/ModifiableIntegerTest.java b/src/test/java/de/rub/nds/modifiablevariable/integer/ModifiableIntegerTest.java index a92f59a3..adc5360a 100644 --- a/src/test/java/de/rub/nds/modifiablevariable/integer/ModifiableIntegerTest.java +++ b/src/test/java/de/rub/nds/modifiablevariable/integer/ModifiableIntegerTest.java @@ -28,9 +28,9 @@ public void setUp() { /** Test of createRandomModification method, of class ModifiableInteger. */ @Test - public void testCreateRandomModification() { + public void testSetRandomModification() { assertNull(integer1.getModification()); - integer1.createRandomModification(); + integer1.setRandomModification(); assertNotNull(integer1.getModification()); } @@ -53,7 +53,7 @@ public void testSetAssertEquals() { @Test public void testIsOriginalValueModified() { assertFalse(integer1.isOriginalValueModified()); - integer1.createRandomModification(); + integer1.setRandomModification(); assertTrue(integer1.isOriginalValueModified()); } diff --git a/src/test/java/de/rub/nds/modifiablevariable/mlong/LongModificationTest.java b/src/test/java/de/rub/nds/modifiablevariable/mlong/LongModificationTest.java index 8de77de3..4b29ce19 100644 --- a/src/test/java/de/rub/nds/modifiablevariable/mlong/LongModificationTest.java +++ b/src/test/java/de/rub/nds/modifiablevariable/mlong/LongModificationTest.java @@ -71,6 +71,18 @@ public void testExplicitValue() { assertEquals(Long.valueOf(10L), start.getOriginalValue()); } + @Test + public void testInsertValue() { + // expect: ...xx111xxxxxxxxxxxx + VariableModification modifier = LongModificationFactory.insertValue(7L, 12); + start.setModification(modifier); + int mask = ((1 << 3) - 1) << 12; + expectedResult = 7L; + result = (start.getValue() & mask) >> 12; + assertEquals(expectedResult, result); + assertEquals(Long.valueOf(10), start.getOriginalValue()); + } + /** Test of explicitValue from file method */ @Test public void testExplicitValueFromFile() { @@ -86,7 +98,7 @@ public void testExplicitValueFromFile() { result = start.getValue(); assertEquals(expectedResult, result); - modifier = LongModificationFactory.explicitValueFromFile(26); + modifier = LongModificationFactory.explicitValueFromFile(27); start.setModification(modifier); expectedResult = 2147483647L; result = start.getValue(); diff --git a/src/test/java/de/rub/nds/modifiablevariable/mlong/ModifiableLongTest.java b/src/test/java/de/rub/nds/modifiablevariable/mlong/ModifiableLongTest.java index f16d6411..7c53baac 100644 --- a/src/test/java/de/rub/nds/modifiablevariable/mlong/ModifiableLongTest.java +++ b/src/test/java/de/rub/nds/modifiablevariable/mlong/ModifiableLongTest.java @@ -32,7 +32,7 @@ public void setUp() { /** Test of createRandomModification method, of class ModifiableLong. */ @Disabled("Not yet implemented") @Test - public void testCreateRandomModification() {} + public void testSetRandomModification() {} /** Test of getAssertEquals method, of class ModifiableLong. */ @Disabled("Not yet implemented") diff --git a/src/test/java/de/rub/nds/modifiablevariable/serialization/ByteArraySerializationTest.java b/src/test/java/de/rub/nds/modifiablevariable/serialization/ByteArraySerializationTest.java index 47e58ca0..ec87a841 100644 --- a/src/test/java/de/rub/nds/modifiablevariable/serialization/ByteArraySerializationTest.java +++ b/src/test/java/de/rub/nds/modifiablevariable/serialization/ByteArraySerializationTest.java @@ -54,7 +54,7 @@ public void setUp() throws JAXBException { ModifiableByteArray.class, ByteArrayDeleteModification.class, ByteArrayExplicitValueModification.class, - ByteArrayInsertModification.class, + ByteArrayInsertValueModification.class, ByteArrayXorModification.class); m = context.createMarshaller(); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); @@ -81,8 +81,7 @@ public void testSerializeDeserializeSimple() throws Exception { @Test public void testSerializeDeserializeWithModification() throws Exception { VariableModification modifier = - ByteArrayModificationFactory.insert(new byte[] {1, 2}, 0); - + ByteArrayModificationFactory.insertValue(new byte[] {1, 2}, 0); start.setModification(modifier); m.marshal(start, writer); diff --git a/src/test/java/de/rub/nds/modifiablevariable/singlebyte/ModifiableByteTest.java b/src/test/java/de/rub/nds/modifiablevariable/singlebyte/ModifiableByteTest.java index 173aef26..0bf0fffb 100644 --- a/src/test/java/de/rub/nds/modifiablevariable/singlebyte/ModifiableByteTest.java +++ b/src/test/java/de/rub/nds/modifiablevariable/singlebyte/ModifiableByteTest.java @@ -30,7 +30,7 @@ public void setUp() { /** Test of createRandomModification method, of class ModifiableByte. */ @Disabled("Not yet implemented") @Test - public void testCreateRandomModification() {} + public void testSetRandomModification() {} /** Test of getAssertEquals method, of class ModifiableByte. */ @Disabled("Not yet implemented") diff --git a/src/test/java/de/rub/nds/modifiablevariable/util/ArrayConverterTest.java b/src/test/java/de/rub/nds/modifiablevariable/util/ArrayConverterTest.java index 429e68db..b9568e10 100644 --- a/src/test/java/de/rub/nds/modifiablevariable/util/ArrayConverterTest.java +++ b/src/test/java/de/rub/nds/modifiablevariable/util/ArrayConverterTest.java @@ -7,8 +7,7 @@ */ package de.rub.nds.modifiablevariable.util; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.*; import de.rub.nds.modifiablevariable.ModifiableVariableFactory; import de.rub.nds.modifiablevariable.bytearray.ModifiableByteArray; @@ -98,7 +97,7 @@ public void testBytesToLong() { /** Test of bytesToHexString method, of class ArrayConverter. */ @Test public void testBytesToHexString_byteArr() { - byte[] toTest = new byte[] {0x00, 0x11, 0x22, 0x33, 0x44}; + byte[] toTest = {0x00, 0x11, 0x22, 0x33, 0x44}; assertEquals("00 11 22 33 44", ArrayConverter.bytesToHexString(toTest)); toTest = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; assertEquals("00 01 02 03 04 05 06 07 08", ArrayConverter.bytesToHexString(toTest)); @@ -126,12 +125,11 @@ public void testBytesToHexString_byteArr() { /** Test of bytesToHexString method, of class ArrayConverter. */ @Test public void testBytesToHexString_byteArr_boolean() { - byte[] toTest = - new byte[] { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, - 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 - }; + byte[] toTest = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }; assertEquals( "00 01 02 03 04 05 06 07 00 01 02 03 04 05 06 07 00 01 02 03 04 05 06 07 00 01 02 03 04 05 06 07", ArrayConverter.bytesToHexString(toTest, false)); @@ -148,12 +146,11 @@ public void testBytesToHexString_3args() {} /** Test ArrayConverter.bytesToRawHexString(). */ @Test public void testBytesToRawHexString() { - byte[] toTest = - new byte[] { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x04, - 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, - 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 - }; + byte[] toTest = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + }; assertEquals( "0001020304050607000102030405060700010203040506070001020304050607", ArrayConverter.bytesToRawHexString(toTest)); @@ -228,22 +225,18 @@ public void testBigIntegerToNullPaddedByteArray() { } @Test - public void testLongToUint48Bytes() { + public void testLongToSixBytes() { long testValue = 0x0000123456789ABCL; byte[] expectedResult = ArrayConverter.hexStringToByteArray("123456789ABC"); assertArrayEquals( - expectedResult, - ArrayConverter.longToUint48Bytes(testValue), - "Assert correct output"); + expectedResult, ArrayConverter.longToSixBytes(testValue), "Assert correct output"); testValue = 0x0000000000000001L; expectedResult = ArrayConverter.hexStringToByteArray("000000000001"); assertArrayEquals( - expectedResult, - ArrayConverter.longToUint48Bytes(testValue), - "Assert correct output"); + expectedResult, ArrayConverter.longToSixBytes(testValue), "Assert correct output"); } /** @@ -298,7 +291,7 @@ public void testBytesToHexString_ModifiableByteArray() { /** Test of reverseByteOrder method, of class ArrayConverter. */ @Test public void testReverseByteOrder() { - byte[] array = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04}; + byte[] array = {0x00, 0x01, 0x02, 0x03, 0x04}; assertArrayEquals( new byte[] {0x04, 0x03, 0x02, 0x01, 0x00}, @@ -337,7 +330,7 @@ public void testIndexOf() { byte[] innerArray3 = ArrayConverter.hexStringToByteArray("FF"); assertEquals(1, ArrayConverter.indexOf(outerArray, innerArray1)); - assertEquals(null, ArrayConverter.indexOf(outerArray, innerArray2)); - assertEquals(null, ArrayConverter.indexOf(outerArray, innerArray3)); + assertNull(ArrayConverter.indexOf(outerArray, innerArray2)); + assertNull(ArrayConverter.indexOf(outerArray, innerArray3)); } }