Merge branch 'footer-mimetypes' of https://github.com/mhmdfy/autopsy into predefined-footer-mimetype

This commit is contained in:
momo 2015-10-28 15:37:17 -04:00
commit c93a1ae41e
6 changed files with 78 additions and 71 deletions

View File

@ -46,4 +46,4 @@ FileTypeIdGlobalSettingsPanel.jLabel2.text=MIME Types:
FileTypeIdGlobalSettingsPanel.jLabel3.text=Autopsy can automatically detect many file types. Add your custom file types here. FileTypeIdGlobalSettingsPanel.jLabel3.text=Autopsy can automatically detect many file types. Add your custom file types here.
FileTypeIdGlobalSettingsPanel.startUp.fileTypeDetectorInitializationException.msg=Error initializing the file type detector. FileTypeIdGlobalSettingsPanel.startUp.fileTypeDetectorInitializationException.msg=Error initializing the file type detector.
FileTypeIdIngestModule.startUp.fileTypeDetectorInitializationException.msg=Error initializing the file type detector. FileTypeIdIngestModule.startUp.fileTypeDetectorInitializationException.msg=Error initializing the file type detector.
FileTypeIdGlobalSettingsPanel.isFooterCheckBox.text=This signature is a footer FileTypeIdGlobalSettingsPanel.isTrailingCheckBox.text=This signature is a trailing

View File

@ -51,7 +51,7 @@ class FileType {
*/ */
FileType(String mimeType, final Signature signature, String filesSetName, boolean alert) { FileType(String mimeType, final Signature signature, String filesSetName, boolean alert) {
this.mimeType = mimeType; this.mimeType = mimeType;
this.signature = new Signature(signature.getSignatureBytes(), signature.getOffset(), signature.getType()); this.signature = new Signature(signature.getSignatureBytes(), signature.getOffset(), signature.getType(), signature.isTrailing());
this.interestingFilesSetName = filesSetName; this.interestingFilesSetName = filesSetName;
this.alert = alert; this.alert = alert;
} }
@ -71,7 +71,7 @@ class FileType {
* @return The signature. * @return The signature.
*/ */
Signature getSignature() { Signature getSignature() {
return new Signature(signature.getSignatureBytes(), signature.getOffset(), signature.getType()); return new Signature(signature.getSignatureBytes(), signature.getOffset(), signature.getType(), signature.isTrailing());
} }
/** /**
@ -148,6 +148,7 @@ class FileType {
private final byte[] signatureBytes; private final byte[] signatureBytes;
private final long offset; private final long offset;
private final Type type; private final Type type;
private final boolean trailing;
/** /**
* Creates a file signature consisting of a sequence of bytes at a * Creates a file signature consisting of a sequence of bytes at a
@ -162,6 +163,7 @@ class FileType {
this.signatureBytes = Arrays.copyOf(signatureBytes, signatureBytes.length); this.signatureBytes = Arrays.copyOf(signatureBytes, signatureBytes.length);
this.offset = offset; this.offset = offset;
this.type = type; this.type = type;
this.trailing = false;
} }
/** /**
@ -175,6 +177,7 @@ class FileType {
this.signatureBytes = signatureString.getBytes(StandardCharsets.US_ASCII); this.signatureBytes = signatureString.getBytes(StandardCharsets.US_ASCII);
this.offset = offset; this.offset = offset;
this.type = Type.ASCII; this.type = Type.ASCII;
this.trailing = false;
} }
/** /**
@ -190,49 +193,56 @@ class FileType {
this.signatureBytes = Arrays.copyOf(signatureBytes, signatureBytes.length); this.signatureBytes = Arrays.copyOf(signatureBytes, signatureBytes.length);
this.offset = offset; this.offset = offset;
this.type = Type.RAW; this.type = Type.RAW;
this.trailing = false;
} }
/** /**
* Creates a file signature consisting of a sequence of bytes at a * Creates a file signature consisting of a sequence of bytes at a
* specific offset within a file with default offset. * specific offset within a file.
* *
* @param signatureBytes The signature bytes. * @param signatureBytes The signature bytes.
* @param isFooter Whether this is a footer or not * @param offset The offset of the signature bytes.
* @param type The type of data in the byte array. Impacts * @param type The type of data in the byte array. Impacts
* how it is displayed to the user in the UI. * how it is displayed to the user in the UI.
* @param trailing Determines whether this signature is trailing.
*/ */
Signature(final byte[] signatureBytes, boolean isFooter, Type type) { Signature(final byte[] signatureBytes, long offset, Type type, boolean trailing) {
this.signatureBytes = Arrays.copyOf(signatureBytes, signatureBytes.length); this.signatureBytes = Arrays.copyOf(signatureBytes, signatureBytes.length);
this.offset = isFooter ? -1 : 0; this.offset = offset;
this.type = type; this.type = type;
this.trailing = trailing;
} }
/** /**
* Creates a file signature consisting of an ASCII string at a * Creates a file signature consisting of an ASCII string at a
* specific offset within a file with default offset. * specific offset within a file.
* *
* @param signatureString The ASCII string * @param signatureString The ASCII string
* @param isFooter Whether this is a footer or not * @param offset The offset of the signature bytes.
* @param trailing Determines whether this signature is trailing.
*/ */
Signature(String signatureString, boolean isFooter) { Signature(String signatureString, long offset, boolean trailing) {
this.signatureBytes = signatureString.getBytes(StandardCharsets.US_ASCII); this.signatureBytes = signatureString.getBytes(StandardCharsets.US_ASCII);
this.offset = isFooter ? -1 : 0; this.offset = offset;
this.type = Type.ASCII; this.type = Type.ASCII;
this.trailing = trailing;
} }
/** /**
* Creates a file signature consisting of a sequence of bytes at a * Creates a file signature consisting of a sequence of bytes at a
* specific offset within a file with default offset. If bytes * specific offset within a file. If bytes correspond to an ASCII
* correspond to an ASCII string, use one of the other constructors * string, use one of the other constructors so that the string is
* so that the string is displayed to the user instead of the raw bytes. * displayed to the user instead of the raw bytes.
* *
* @param signatureBytes The signature bytes. * @param signatureBytes The signature bytes.
* @param isFooter Whether this is a footer or not * @param offset The offset of the signature bytes.
* @param trailing Determines whether this signature is trailing.
*/ */
Signature(final byte[] signatureBytes, boolean isFooter) { Signature(final byte[] signatureBytes, long offset, boolean trailing) {
this.signatureBytes = Arrays.copyOf(signatureBytes, signatureBytes.length); this.signatureBytes = Arrays.copyOf(signatureBytes, signatureBytes.length);
this.offset = isFooter ? -1 : 0; this.offset = offset;
this.type = Type.RAW; this.type = Type.RAW;
this.trailing = trailing;
} }
/** /**
@ -262,6 +272,10 @@ class FileType {
return type; return type;
} }
boolean isTrailing() {
return trailing;
}
/** /**
* Determines whether or not the signature is contained within a given * Determines whether or not the signature is contained within a given
* file. * file.
@ -271,14 +285,15 @@ class FileType {
* @return True or false. * @return True or false.
*/ */
boolean containedIn(final AbstractFile file) { boolean containedIn(final AbstractFile file) {
if(offset == -1) long actualOffset = offset;
return containedAsFooter(file); if(trailing)
if (file.getSize() < (offset + signatureBytes.length)) { actualOffset = file.getSize() - signatureBytes.length - offset;
if (file.getSize() < (actualOffset + signatureBytes.length)) {
return false; /// too small, can't contain this signature return false; /// too small, can't contain this signature
} }
try { try {
byte[] buffer = new byte[signatureBytes.length]; byte[] buffer = new byte[signatureBytes.length];
int bytesRead = file.read(buffer, offset, signatureBytes.length); int bytesRead = file.read(buffer, actualOffset, signatureBytes.length);
return ((bytesRead == signatureBytes.length) && (Arrays.equals(buffer, signatureBytes))); return ((bytesRead == signatureBytes.length) && (Arrays.equals(buffer, signatureBytes)));
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
/** /**
@ -291,14 +306,6 @@ class FileType {
} }
} }
private boolean containedAsFooter(final AbstractFile file) {
if(file.getSize() < signatureBytes.length)
return false;
long newOffset = file.getSize() - signatureBytes.length;
Signature newSignature = new Signature(signatureBytes, newOffset);
return newSignature.containedIn(file);
}
@Override @Override
public boolean equals(Object other) { public boolean equals(Object other) {
if (other != null && other instanceof Signature) { if (other != null && other instanceof Signature) {

View File

@ -83,7 +83,7 @@
<Component id="saveTypeButton" min="-2" max="-2" attributes="0"/> <Component id="saveTypeButton" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/> <EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
</Group> </Group>
<Component id="isFooterCheckBox" min="-2" max="-2" attributes="0"/> <Component id="isTrailingCheckBox" min="-2" max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
<Component id="jLabel1" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="jLabel1" alignment="0" min="-2" max="-2" attributes="0"/>
@ -140,7 +140,7 @@
<Component id="signatureLabel" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="signatureLabel" alignment="0" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="isFooterCheckBox" min="-2" max="-2" attributes="0"/> <Component id="isTrailingCheckBox" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
<Component id="offsetTextField" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="offsetTextField" alignment="3" min="-2" max="-2" attributes="0"/>
@ -353,14 +353,14 @@
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
<Component class="javax.swing.JCheckBox" name="isFooterCheckBox"> <Component class="javax.swing.JCheckBox" name="isTrailingCheckBox">
<Properties> <Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties" key="FileTypeIdGlobalSettingsPanel.isFooterCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/modules/filetypeid/Bundle.properties" key="FileTypeIdGlobalSettingsPanel.isTrailingCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
</Properties> </Properties>
<Events> <Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="isFooterCheckBoxActionPerformed"/> <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="isTrailingCheckBoxActionPerformed"/>
</Events> </Events>
</Component> </Component>
</SubComponents> </SubComponents>

View File

@ -203,7 +203,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
boolean requiredFieldsPopulated boolean requiredFieldsPopulated
= !mimeTypeTextField.getText().isEmpty() = !mimeTypeTextField.getText().isEmpty()
&& (isFooterCheckBox.isSelected() ? true : !offsetTextField.getText().isEmpty()) && !offsetTextField.getText().isEmpty()
&& !signatureTextField.getText().isEmpty() && !signatureTextField.getText().isEmpty()
&& (postHitCheckBox.isSelected() ? !filesSetNameTextField.getText().isEmpty() : true); && (postHitCheckBox.isSelected() ? !filesSetNameTextField.getText().isEmpty() : true);
saveTypeButton.setEnabled(!ingestIsRunning && requiredFieldsPopulated); saveTypeButton.setEnabled(!ingestIsRunning && requiredFieldsPopulated);
@ -270,16 +270,8 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
} }
} }
signatureTextField.setText(signatureBytes); signatureTextField.setText(signatureBytes);
if(signature.getOffset() == -1) { isTrailingCheckBox.setSelected(signature.isTrailing());
isFooterCheckBox.setSelected(true); offsetTextField.setText(Long.toString(signature.getOffset()));
offsetTextField.setEnabled(false);
offsetTextField.setText("");
}
else {
isFooterCheckBox.setSelected(false);
offsetTextField.setEnabled(true);
offsetTextField.setText(Long.toString(signature.getOffset()));
}
postHitCheckBox.setSelected(fileType.alertOnMatch()); postHitCheckBox.setSelected(fileType.alertOnMatch());
filesSetNameTextField.setEnabled(postHitCheckBox.isSelected()); filesSetNameTextField.setEnabled(postHitCheckBox.isSelected());
filesSetNameTextField.setText(fileType.getFilesSetName()); filesSetNameTextField.setText(fileType.getFilesSetName());
@ -298,8 +290,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
signatureTypeComboBox.setSelectedItem(FileTypeIdGlobalSettingsPanel.RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM); signatureTypeComboBox.setSelectedItem(FileTypeIdGlobalSettingsPanel.RAW_SIGNATURE_TYPE_COMBO_BOX_ITEM);
hexPrefixLabel.setVisible(true); hexPrefixLabel.setVisible(true);
signatureTextField.setText("0000"); //NON-NLS signatureTextField.setText("0000"); //NON-NLS
isFooterCheckBox.setSelected(false); isTrailingCheckBox.setSelected(false);
offsetTextField.setEnabled(true);
offsetTextField.setText(""); //NON-NLS offsetTextField.setText(""); //NON-NLS
postHitCheckBox.setSelected(false); postHitCheckBox.setSelected(false);
filesSetNameTextField.setText(""); //NON-NLS filesSetNameTextField.setText(""); //NON-NLS
@ -371,7 +362,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
jLabel1 = new javax.swing.JLabel(); jLabel1 = new javax.swing.JLabel();
jLabel2 = new javax.swing.JLabel(); jLabel2 = new javax.swing.JLabel();
jLabel3 = new javax.swing.JLabel(); jLabel3 = new javax.swing.JLabel();
isFooterCheckBox = new javax.swing.JCheckBox(); isTrailingCheckBox = new javax.swing.JCheckBox();
setMaximumSize(new java.awt.Dimension(500, 300)); setMaximumSize(new java.awt.Dimension(500, 300));
setPreferredSize(new java.awt.Dimension(500, 300)); setPreferredSize(new java.awt.Dimension(500, 300));
@ -451,10 +442,10 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
org.openide.awt.Mnemonics.setLocalizedText(jLabel3, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.jLabel3.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(jLabel3, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.jLabel3.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(isFooterCheckBox, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.isFooterCheckBox.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(isTrailingCheckBox, org.openide.util.NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.isTrailingCheckBox.text")); // NOI18N
isFooterCheckBox.addActionListener(new java.awt.event.ActionListener() { isTrailingCheckBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
isFooterCheckBoxActionPerformed(evt); isTrailingCheckBoxActionPerformed(evt);
} }
}); });
@ -511,7 +502,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(saveTypeButton) .addComponent(saveTypeButton)
.addGap(8, 8, 8)) .addGap(8, 8, 8))
.addComponent(isFooterCheckBox))) .addComponent(isTrailingCheckBox)))
.addComponent(jLabel1) .addComponent(jLabel1)
.addComponent(jLabel3)) .addComponent(jLabel3))
.addContainerGap(50, Short.MAX_VALUE)))) .addContainerGap(50, Short.MAX_VALUE))))
@ -553,7 +544,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
.addComponent(signatureTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(signatureTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(signatureLabel)) .addComponent(signatureLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(isFooterCheckBox) .addComponent(isTrailingCheckBox)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(offsetTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(offsetTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
@ -635,7 +626,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
*/ */
long offset; long offset;
try { try {
offset = isFooterCheckBox.isSelected() ? -1 : Long.parseUnsignedLong(offsetTextField.getText()); offset = Long.parseUnsignedLong(offsetTextField.getText());
} catch (NumberFormatException ex) { } catch (NumberFormatException ex) {
JOptionPane.showMessageDialog(null, JOptionPane.showMessageDialog(null,
NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.message"), NbBundle.getMessage(FileTypeIdGlobalSettingsPanel.class, "FileTypeIdGlobalSettingsPanel.JOptionPane.invalidOffset.message"),
@ -662,7 +653,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
/** /**
* Put it all together and reset the file types list component. * Put it all together and reset the file types list component.
*/ */
FileType.Signature signature = new FileType.Signature(signatureBytes, offset, sigType); FileType.Signature signature = new FileType.Signature(signatureBytes, offset, sigType, isTrailingCheckBox.isSelected());
FileType fileType = new FileType(typeName, signature, filesSetName, postHitCheckBox.isSelected()); FileType fileType = new FileType(typeName, signature, filesSetName, postHitCheckBox.isSelected());
FileType selected = typesList.getSelectedValue(); FileType selected = typesList.getSelectedValue();
if (selected != null) { if (selected != null) {
@ -692,10 +683,9 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
// TODO add your handling code here: // TODO add your handling code here:
}//GEN-LAST:event_signatureTextFieldActionPerformed }//GEN-LAST:event_signatureTextFieldActionPerformed
private void isFooterCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_isFooterCheckBoxActionPerformed private void isTrailingCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_isTrailingCheckBoxActionPerformed
offsetTextField.setEnabled(!isFooterCheckBox.isSelected());
enableButtons(); }//GEN-LAST:event_isTrailingCheckBoxActionPerformed
}//GEN-LAST:event_isFooterCheckBoxActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton deleteTypeButton; private javax.swing.JButton deleteTypeButton;
@ -703,7 +693,7 @@ final class FileTypeIdGlobalSettingsPanel extends IngestModuleGlobalSettingsPane
private javax.swing.JTextField filesSetNameTextField; private javax.swing.JTextField filesSetNameTextField;
private javax.swing.JLabel hexPrefixLabel; private javax.swing.JLabel hexPrefixLabel;
private javax.swing.JLabel ingestRunningWarningLabel; private javax.swing.JLabel ingestRunningWarningLabel;
private javax.swing.JCheckBox isFooterCheckBox; private javax.swing.JCheckBox isTrailingCheckBox;
private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3; private javax.swing.JLabel jLabel3;

View File

@ -22,16 +22,11 @@
</xs:restriction> </xs:restriction>
</xs:simpleType> </xs:simpleType>
<xs:simpleType name="nonNegativeMinus1">
<xs:restriction base="xs:integer">
<xs:minInclusive value="-1"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="signatureType"> <xs:complexType name="signatureType">
<xs:sequence> <xs:sequence>
<xs:element name="Bytes" type="stringType"/> <xs:element name="Bytes" type="stringType"/>
<xs:element name="Offset" type="nonNegativeMinus1"/> <xs:element name="Offset" type="xs:nonNegativeInteger"/>
<xs:element name="Trailing" type="xs:boolean" minOccurs="0" maxOccurs="1" />
</xs:sequence> </xs:sequence>
<xs:attribute name="type" type="sigInterpretationType" use="required"/> <xs:attribute name="type" type="sigInterpretationType" use="required"/>
</xs:complexType> </xs:complexType>

View File

@ -38,6 +38,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.PlatformUtil; import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.coreutils.XMLUtil; import org.sleuthkit.autopsy.coreutils.XMLUtil;
import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature; import org.sleuthkit.autopsy.modules.filetypeid.FileType.Signature;
import org.w3c.dom.Node;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
/** /**
@ -67,6 +68,7 @@ final class UserDefinedFileTypesManager {
private static final String SIGNATURE_TYPE_ATTRIBUTE = "type"; //NON-NLS private static final String SIGNATURE_TYPE_ATTRIBUTE = "type"; //NON-NLS
private static final String BYTES_TAG_NAME = "Bytes"; //NON-NLS private static final String BYTES_TAG_NAME = "Bytes"; //NON-NLS
private static final String OFFSET_TAG_NAME = "Offset"; //NON-NLS private static final String OFFSET_TAG_NAME = "Offset"; //NON-NLS
private static final String TRAILING_TAG_NAME = "Trailing";
private static final String INTERESTING_FILES_SET_TAG_NAME = "InterestingFileSset"; //NON-NLS private static final String INTERESTING_FILES_SET_TAG_NAME = "InterestingFileSset"; //NON-NLS
private static final String ALERT_ATTRIBUTE = "alert"; //NON-NLS private static final String ALERT_ATTRIBUTE = "alert"; //NON-NLS
private static final String ENCODING_FOR_XML_FILE = "UTF-8"; //NON-NLS private static final String ENCODING_FOR_XML_FILE = "UTF-8"; //NON-NLS
@ -379,6 +381,10 @@ final class UserDefinedFileTypesManager {
offsetElem.setTextContent(DatatypeConverter.printLong(signature.getOffset())); offsetElem.setTextContent(DatatypeConverter.printLong(signature.getOffset()));
signatureElem.appendChild(offsetElem); signatureElem.appendChild(offsetElem);
Element trailingElem = doc.createElement(TRAILING_TAG_NAME);
trailingElem.setTextContent(DatatypeConverter.printBoolean(signature.isTrailing()));
signatureElem.appendChild(trailingElem);
signatureElem.setAttribute(SIGNATURE_TYPE_ATTRIBUTE, signature.getType().toString()); signatureElem.setAttribute(SIGNATURE_TYPE_ATTRIBUTE, signature.getType().toString());
fileTypeElem.appendChild(signatureElem); fileTypeElem.appendChild(signatureElem);
} }
@ -489,7 +495,13 @@ final class UserDefinedFileTypesManager {
String offsetString = getChildElementTextContent(signatureElem, OFFSET_TAG_NAME); String offsetString = getChildElementTextContent(signatureElem, OFFSET_TAG_NAME);
long offset = DatatypeConverter.parseLong(offsetString); long offset = DatatypeConverter.parseLong(offsetString);
return new Signature(signatureBytes, offset, signatureType); String trailingString = getChildElementTextContent(signatureElem, TRAILING_TAG_NAME);
if(trailingString == null)
return new Signature(signatureBytes, offset, signatureType);
boolean trailing = DatatypeConverter.parseBoolean(trailingString);
return new Signature(signatureBytes, offset, signatureType, trailing);
} }
/** /**
@ -531,7 +543,10 @@ final class UserDefinedFileTypesManager {
*/ */
private static String getChildElementTextContent(Element elem, String tagName) { private static String getChildElementTextContent(Element elem, String tagName) {
NodeList childElems = elem.getElementsByTagName(tagName); NodeList childElems = elem.getElementsByTagName(tagName);
Element childElem = (Element) childElems.item(0); Node childNode = childElems.item(0);
if(childNode == null)
return null;
Element childElem = (Element) childNode;
return childElem.getTextContent(); return childElem.getTextContent();
} }