Skip to content

Commit

Permalink
Added Joliet level detection
Browse files Browse the repository at this point in the history
  • Loading branch information
indy2kro committed Jan 19, 2025
1 parent 3b39936 commit 3148897
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 18 deletions.
15 changes: 10 additions & 5 deletions src/Cli/IsoTool.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,9 @@ protected function extractAction(string $file, string $extractPath): void
echo 'Extract finished!' . PHP_EOL;
}

protected function extractFiles(Volume $primaryVolume, IsoFile $isoFile, string $destinationDir): void
protected function extractFiles(Volume $volumeDescriptor, IsoFile $isoFile, string $destinationDir): void
{
$pathTable = $primaryVolume->loadTable($isoFile);
$pathTable = $volumeDescriptor->loadTable($isoFile);

if ($pathTable === null) {
return;
Expand All @@ -135,7 +135,7 @@ protected function extractFiles(Volume $primaryVolume, IsoFile $isoFile, string
/** @var PathTableRecord $pathRecord */
foreach ($pathTable as $pathRecord) {
// check extents
$extents = $pathRecord->loadExtents($isoFile, $primaryVolume->blockSize);
$extents = $pathRecord->loadExtents($isoFile, $volumeDescriptor->blockSize, ($volumeDescriptor->getType() === Type::SUPPLEMENTARY_VOLUME_DESC), $volumeDescriptor->jolietLevel);

if ($extents !== false) {
/** @var FileDirectory $extentRecord */
Expand All @@ -153,7 +153,7 @@ protected function extractFiles(Volume $primaryVolume, IsoFile $isoFile, string
$dataLength = $extentRecord->dataLength;
echo $fullPath . ' (location: ' . $location . ') (length: ' . $dataLength . ')' . PHP_EOL;

$pathRecord->extractFile($isoFile, $primaryVolume->blockSize, $location, $dataLength, $fullPath);
$pathRecord->extractFile($isoFile, $volumeDescriptor->blockSize, $location, $dataLength, $fullPath);
} else {
if (! is_dir($fullPath)) {
if (mkdir($fullPath) === false) {
Expand All @@ -172,6 +172,7 @@ protected function infoVolume(Volume $volumeDescriptor): void
echo ' - System ID: ' . $volumeDescriptor->systemId . PHP_EOL;
echo ' - Volume ID: ' . $volumeDescriptor->volumeId . PHP_EOL;
echo ' - App ID: ' . $volumeDescriptor->appId . PHP_EOL;
echo ' - File Structure Version: ' . $volumeDescriptor->fileStructureVersion . PHP_EOL;
echo ' - Volume Space Size: ' . $volumeDescriptor->volumeSpaceSize . PHP_EOL;
echo ' - Volume Set Size: ' . $volumeDescriptor->volumeSetSize . PHP_EOL;
echo ' - Volume SeqNum: ' . $volumeDescriptor->volumeSeqNum . PHP_EOL;
Expand All @@ -186,6 +187,10 @@ protected function infoVolume(Volume $volumeDescriptor): void
echo ' - Modification Date: ' . $volumeDescriptor->modificationDate?->toDateTimeString() . PHP_EOL;
echo ' - Expiration Date: ' . $volumeDescriptor->expirationDate?->toDateTimeString() . PHP_EOL;
echo ' - Effective Date: ' . $volumeDescriptor->effectiveDate?->toDateTimeString() . PHP_EOL;

if ($volumeDescriptor instanceof SupplementaryVolume && $volumeDescriptor->jolietLevel !== 0) {
echo ' - Joliet Level: ' . $volumeDescriptor->jolietLevel . PHP_EOL;
}
}

protected function displayFiles(Volume $volumeDescriptor, IsoFile $isoFile): void
Expand All @@ -201,7 +206,7 @@ protected function displayFiles(Volume $volumeDescriptor, IsoFile $isoFile): voi
/** @var PathTableRecord $pathRecord */
foreach ($pathTable as $pathRecord) {
// check extents
$extents = $pathRecord->loadExtents($isoFile, $volumeDescriptor->blockSize);
$extents = $pathRecord->loadExtents($isoFile, $volumeDescriptor->blockSize, ($volumeDescriptor->getType() === Type::SUPPLEMENTARY_VOLUME_DESC), $volumeDescriptor->jolietLevel);

if ($extents !== false) {
/** @var FileDirectory $extentRecord */
Expand Down
24 changes: 22 additions & 2 deletions src/Descriptor/Volume.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ abstract class Volume extends Descriptor
public ?Carbon $expirationDate = null;
public ?Carbon $effectiveDate = null;
public int $fileStructureVersion;
public int $jolietLevel = 0;

public function init(IsoFile $isoFile, int &$offset): void
{
Expand All @@ -58,8 +59,26 @@ public function init(IsoFile $isoFile, int &$offset): void

$this->volumeSpaceSize = Buffer::readBBO($this->bytes, 8, $offset);

// unused
$unused = Buffer::getBytes($this->bytes, 32, $offset);
// joliet escape sequence
$jolietEscapeSequence = Buffer::getBytes($this->bytes, 32, $offset);

// Joliet Detection - If this is a Supplementary Volume Descriptor
if ($this->type === Type::SUPPLEMENTARY_VOLUME_DESC) {
// Define Joliet escape sequences as their byte values
$jolietLevels = [
1 => '374764', // %/@ in byte format
2 => '374767', // %/C in byte format
3 => '374769', // %/E in byte format
];

// Check for Joliet escape sequences indicating Unicode support
foreach ($jolietLevels as $level => $sequence) {
if (str_contains($jolietEscapeSequence, $sequence)) {
$this->jolietLevel = $level; // Record the Joliet level if found
break;
}
}
}

$this->volumeSetSize = Buffer::readBBO($this->bytes, 4, $offset);
$this->volumeSeqNum = Buffer::readBBO($this->bytes, 4, $offset);
Expand All @@ -72,6 +91,7 @@ public function init(IsoFile $isoFile, int &$offset): void
$this->optMPathTablePos = Buffer::readMSB($this->bytes, 4, $offset);

$this->rootDirectory = new FileDirectory();
$this->rootDirectory->jolietLevel = $this->jolietLevel;
$this->rootDirectory->init($this->bytes, $offset, ($this->type === Type::SUPPLEMENTARY_VOLUME_DESC));

$this->volumeSetId = trim(Buffer::readDString($this->bytes, 128, $offset, ($this->type === Type::SUPPLEMENTARY_VOLUME_DESC)));
Expand Down
29 changes: 21 additions & 8 deletions src/FileDirectory.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ class FileDirectory
*/
public string $fileId;

public int $jolietLevel = 0;

/**
* Load the "Directory Record" from buffer
*
Expand Down Expand Up @@ -149,11 +151,20 @@ public function init(array &$buffer, int &$offset, bool $supplementary = false):
$this->fileId = '..';
$tmp++;
} else {
$this->fileId = Buffer::readDString($buffer, $this->fileIdLength, $tmp, $supplementary);

$pos = strpos($this->fileId, ';1');
if ($pos !== false && $pos === strlen($this->fileId) - 2) {
$this->fileId = substr($this->fileId, 0, strlen($this->fileId) - 2);
if ($this->jolietLevel === 3) {
$this->fileId = Buffer::readAString($buffer, $this->fileIdLength, $tmp, $supplementary);

$pos = strpos($this->fileId, ';1');
if ($pos !== false && $pos === strlen($this->fileId) - 2) {
$this->fileId = substr($this->fileId, 0, strlen($this->fileId) - 2);
}
} else {
$this->fileId = Buffer::readDString($buffer, $this->fileIdLength, $tmp, $supplementary);

$pos = strpos($this->fileId, ';1');
if ($pos !== false && $pos === strlen($this->fileId) - 2) {
$this->fileId = substr($this->fileId, 0, strlen($this->fileId) - 2);
}
}
}

Expand Down Expand Up @@ -238,17 +249,17 @@ public function isParent(): bool
*
* @return array<int, FileDirectory>|false
*/
public function loadExtents(IsoFile $isoFile, int $blockSize, bool $supplementary = false): array|false
public function loadExtents(IsoFile $isoFile, int $blockSize, bool $supplementary = false, int $jolietLevel = 0): array|false
{
return self::loadExtentsSt($isoFile, $blockSize, $this->location, $supplementary);
return self::loadExtentsSt($isoFile, $blockSize, $this->location, $supplementary, $jolietLevel);
}

/**
* Load the "File Directory Descriptors"(extents) from ISO file
*
* @return array<int, FileDirectory>|false
*/
public static function loadExtentsSt(IsoFile $isoFile, int $blockSize, int $location, bool $supplementary = false): array|false
public static function loadExtentsSt(IsoFile $isoFile, int $blockSize, int $location, bool $supplementary = false, int $jolietLevel = 0): array|false
{
if ($isoFile->seek($location * $blockSize, SEEK_SET) === -1) {
return false;
Expand All @@ -268,11 +279,13 @@ public static function loadExtentsSt(IsoFile $isoFile, int $blockSize, int $loca

$offset = 1;
$fdDesc = new self();
$fdDesc->jolietLevel = $jolietLevel;
$extents = [];

while ($fdDesc->init($bytes, $offset, $supplementary) !== false) {
$extents[] = $fdDesc;
$fdDesc = new self();
$fdDesc->jolietLevel = $jolietLevel;
}

return $extents;
Expand Down
4 changes: 2 additions & 2 deletions src/PathTableRecord.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ public function init(array &$bytes, int &$offset, bool $supplementary = false):
*
* @return array<int, FileDirectory>|false
*/
public function loadExtents(IsoFile &$isoFile, int $blockSize, bool $supplementary = false): array|false
public function loadExtents(IsoFile &$isoFile, int $blockSize, bool $supplementary = false, int $jolietLevel = 0): array|false
{
return FileDirectory::loadExtentsSt($isoFile, $blockSize, $this->location, $supplementary);
return FileDirectory::loadExtentsSt($isoFile, $blockSize, $this->location, $supplementary, $jolietLevel);
}

public function extractFile(IsoFile &$isoFile, int $blockSize, int $location, int $dataLength, string $destinationFile): void
Expand Down
4 changes: 3 additions & 1 deletion src/Util/Buffer.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ public static function getString(array &$buffer, int $length, int &$offset = 0,
if (! isset($buffer[$i])) {
throw new Exception('Failed to read buffer entry ' . $i);
}
$string .= chr($buffer[$i]);
if ($supplementary || $buffer[$i] !== 0) {
$string .= chr($buffer[$i]);
}
}

if ($supplementary) {
Expand Down
1 change: 1 addition & 0 deletions tests/IsoFileTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ public function testDescriptorsDosIso(): void
$this->assertSame('DOS4.01', $supplementaryVolumeDescriptor->volumeId);
$this->assertSame(848, $supplementaryVolumeDescriptor->volumeSpaceSize);
$this->assertSame('', $supplementaryVolumeDescriptor->appId);
$this->assertSame(3, $supplementaryVolumeDescriptor->jolietLevel);
$this->assertNull($supplementaryVolumeDescriptor->creationDate);
$this->assertNull($supplementaryVolumeDescriptor->modificationDate);
$this->assertNull($supplementaryVolumeDescriptor->expirationDate);
Expand Down

0 comments on commit 3148897

Please sign in to comment.