mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
Display proper volume descriptor timestamp.
This commit is contained in:
parent
cfba0064f6
commit
42b4e6653b
1 changed files with 88 additions and 30 deletions
|
@ -20,6 +20,8 @@ import ghidra.program.model.data.*;
|
||||||
import ghidra.util.exception.DuplicateNameException;
|
import ghidra.util.exception.DuplicateNameException;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.time.DateTimeException;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
public class ISO9660VolumeDescriptor extends ISO9660BaseVolume {
|
public class ISO9660VolumeDescriptor extends ISO9660BaseVolume {
|
||||||
private byte unused; // Always 0x00
|
private byte unused; // Always 0x00
|
||||||
|
@ -192,7 +194,7 @@ public class ISO9660VolumeDescriptor extends ISO9660BaseVolume {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuffer buff = new StringBuffer();
|
StringBuilder buff = new StringBuilder();
|
||||||
|
|
||||||
buff.append("Type Code: 0x" + Integer.toHexString(super.getTypeCode()) + " => " +
|
buff.append("Type Code: 0x" + Integer.toHexString(super.getTypeCode()) + " => " +
|
||||||
getTypeCodeString() + "\n");
|
getTypeCodeString() + "\n");
|
||||||
|
@ -246,16 +248,47 @@ public class ISO9660VolumeDescriptor extends ISO9660BaseVolume {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a formatted date/time string based on the byteArray passed in.
|
* Checks whether the given string is entirely made up of ASCII digits.
|
||||||
* @param byteArray the array containing the bytes to format into date/time
|
*
|
||||||
* @return The formatted date/time string
|
* @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) {
|
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;
|
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];
|
int timeOffset = byteArray[byteArray.length - 1];
|
||||||
|
|
||||||
String bString = new String(byteArray);
|
String bString = new String(byteArray);
|
||||||
s1 = bString.substring(0, 4); //year 1 to 9999
|
s1 = bString.substring(0, 4); //year 1 to 9999
|
||||||
s2 = bString.substring(4, 6); //month 1 to 12
|
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
|
s6 = bString.substring(12, 14); //second 0 to 59
|
||||||
s7 = bString.substring(14, 16); //ms 0 to 99
|
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,
|
* Time zone offset from GMT in 15 minute intervals,
|
||||||
* starting at interval -48 (west) and running up to
|
* starting at interval -48 (west) and running up to
|
||||||
* interval 52 (east).
|
* interval 52 (east).
|
||||||
*/
|
*/
|
||||||
int timeZone = (-48 + timeOffset) / 4; //GMT offset
|
int timezoneIntegral = timeOffset / 4;
|
||||||
String dateTime =
|
int timezoneFractional = (Math.abs(timeOffset) % 4) * 15;
|
||||||
String.format("%s-%s-%s %s:%s:%s.%s GMT%d", s1, s2, s3, s4, s5, s6, s7, timeZone);
|
|
||||||
|
|
||||||
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() {
|
public byte getUnused() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue