Display proper volume descriptor timestamp.

This commit is contained in:
Alessandro Gatti 2020-01-14 19:43:55 +01:00
parent cfba0064f6
commit 42b4e6653b

View file

@ -20,6 +20,8 @@ import ghidra.program.model.data.*;
import ghidra.util.exception.DuplicateNameException;
import java.io.IOException;
import java.time.DateTimeException;
import java.time.LocalDateTime;
public class ISO9660VolumeDescriptor extends ISO9660BaseVolume {
private byte unused; // Always 0x00
@ -192,7 +194,7 @@ public class ISO9660VolumeDescriptor extends ISO9660BaseVolume {
@Override
public String toString() {
StringBuffer buff = new StringBuffer();
StringBuilder buff = new StringBuilder();
buff.append("Type Code: 0x" + Integer.toHexString(super.getTypeCode()) + " => " +
getTypeCodeString() + "\n");
@ -246,16 +248,47 @@ public class ISO9660VolumeDescriptor extends ISO9660BaseVolume {
}
/**
* Creates a formatted date/time string based on the byteArray passed in.
* @param byteArray the array containing the bytes to format into date/time
* @return The formatted date/time string
* Checks whether the given string is entirely made up of ASCII digits.
*
* @param string the string to check.
* @return true if all characters in the string are ASCII digits, false
* otherwise.
*/
private boolean isDigitsStringValid(String string) {
for (int i = 0; i < string.length(); i++) {
char c = string.charAt(i);
if (c < '0' || c > '9') {
return false;
}
}
return true;
}
/**
* Parses the given buffer as an ISO9660 timestamp and returns it as a
* human readable string representation.
*
* Invalid buffers that are still big enough to hold a timestamp are
* still parsed and converted, albeit they are marked as invalid when
* presented to the user.
*
* @param byteArray the buffer to parse (only extended timestamp format
* is handled).
* @return a string with the human readable timestamp.
*/
protected String createDateTimeString(byte[] byteArray) {
if (byteArray == null || byteArray.length < 17) {
return "INVALID (truncated or missing)";
}
if (byteArray != null) {
String s1, s2, s3, s4, s5, s6, s7;
// Time zone offset from GMT in 15 minute intervals,
// starting at interval -48 (west) and running up to
// interval 52 (east)
int timeOffset = byteArray[byteArray.length - 1];
String bString = new String(byteArray);
s1 = bString.substring(0, 4); //year 1 to 9999
s2 = bString.substring(4, 6); //month 1 to 12
@ -265,19 +298,44 @@ public class ISO9660VolumeDescriptor extends ISO9660BaseVolume {
s6 = bString.substring(12, 14); //second 0 to 59
s7 = bString.substring(14, 16); //ms 0 to 99
// Validate strings first.
boolean validBuffer = isDigitsStringValid(s1) && isDigitsStringValid(s2) && isDigitsStringValid(s3) &&
isDigitsStringValid(s4) && isDigitsStringValid(s5) && isDigitsStringValid(s6) && isDigitsStringValid(s7);
try {
// The buffer contains an invalid date/time.
LocalDateTime.of(Integer.parseInt(s1), Integer.parseInt(s2), Integer.parseInt(s3),
Integer.parseInt(s4), Integer.parseInt(s5), Integer.parseInt(s6));
} catch (NumberFormatException | DateTimeException e) {
validBuffer = false;
}
// The buffer contains an invalid timezone offset.
if (timeOffset < -48 || timeOffset > 52) {
validBuffer = false;
}
/*
* Time zone offset from GMT in 15 minute intervals,
* starting at interval -48 (west) and running up to
* interval 52 (east).
*/
int timeZone = (-48 + timeOffset) / 4; //GMT offset
String dateTime =
String.format("%s-%s-%s %s:%s:%s.%s GMT%d", s1, s2, s3, s4, s5, s6, s7, timeZone);
int timezoneIntegral = timeOffset / 4;
int timezoneFractional = (Math.abs(timeOffset) % 4) * 15;
return dateTime;
StringBuilder builder = new StringBuilder();
if (!validBuffer) {
builder.append("INVALID(");
}
return "";
builder.append(String.format("%s-%s-%s %s:%s:%s.%s GMT%c%02d%02d", s1, s2, s3, s4, s5, s6, s7,
timezoneIntegral < 0 ? '-' : '+', timezoneIntegral, timezoneFractional));
if (!validBuffer) {
builder.append(")");
}
return builder.toString();
}
public byte getUnused() {