Skip to content

Commit 3148897

Browse files
committed
Added Joliet level detection
1 parent 3b39936 commit 3148897

File tree

6 files changed

+59
-18
lines changed

6 files changed

+59
-18
lines changed

src/Cli/IsoTool.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,9 @@ protected function extractAction(string $file, string $extractPath): void
122122
echo 'Extract finished!' . PHP_EOL;
123123
}
124124

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

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

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

156-
$pathRecord->extractFile($isoFile, $primaryVolume->blockSize, $location, $dataLength, $fullPath);
156+
$pathRecord->extractFile($isoFile, $volumeDescriptor->blockSize, $location, $dataLength, $fullPath);
157157
} else {
158158
if (! is_dir($fullPath)) {
159159
if (mkdir($fullPath) === false) {
@@ -172,6 +172,7 @@ protected function infoVolume(Volume $volumeDescriptor): void
172172
echo ' - System ID: ' . $volumeDescriptor->systemId . PHP_EOL;
173173
echo ' - Volume ID: ' . $volumeDescriptor->volumeId . PHP_EOL;
174174
echo ' - App ID: ' . $volumeDescriptor->appId . PHP_EOL;
175+
echo ' - File Structure Version: ' . $volumeDescriptor->fileStructureVersion . PHP_EOL;
175176
echo ' - Volume Space Size: ' . $volumeDescriptor->volumeSpaceSize . PHP_EOL;
176177
echo ' - Volume Set Size: ' . $volumeDescriptor->volumeSetSize . PHP_EOL;
177178
echo ' - Volume SeqNum: ' . $volumeDescriptor->volumeSeqNum . PHP_EOL;
@@ -186,6 +187,10 @@ protected function infoVolume(Volume $volumeDescriptor): void
186187
echo ' - Modification Date: ' . $volumeDescriptor->modificationDate?->toDateTimeString() . PHP_EOL;
187188
echo ' - Expiration Date: ' . $volumeDescriptor->expirationDate?->toDateTimeString() . PHP_EOL;
188189
echo ' - Effective Date: ' . $volumeDescriptor->effectiveDate?->toDateTimeString() . PHP_EOL;
190+
191+
if ($volumeDescriptor instanceof SupplementaryVolume && $volumeDescriptor->jolietLevel !== 0) {
192+
echo ' - Joliet Level: ' . $volumeDescriptor->jolietLevel . PHP_EOL;
193+
}
189194
}
190195

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

206211
if ($extents !== false) {
207212
/** @var FileDirectory $extentRecord */

src/Descriptor/Volume.php

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ abstract class Volume extends Descriptor
3838
public ?Carbon $expirationDate = null;
3939
public ?Carbon $effectiveDate = null;
4040
public int $fileStructureVersion;
41+
public int $jolietLevel = 0;
4142

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

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

61-
// unused
62-
$unused = Buffer::getBytes($this->bytes, 32, $offset);
62+
// joliet escape sequence
63+
$jolietEscapeSequence = Buffer::getBytes($this->bytes, 32, $offset);
64+
65+
// Joliet Detection - If this is a Supplementary Volume Descriptor
66+
if ($this->type === Type::SUPPLEMENTARY_VOLUME_DESC) {
67+
// Define Joliet escape sequences as their byte values
68+
$jolietLevels = [
69+
1 => '374764', // %/@ in byte format
70+
2 => '374767', // %/C in byte format
71+
3 => '374769', // %/E in byte format
72+
];
73+
74+
// Check for Joliet escape sequences indicating Unicode support
75+
foreach ($jolietLevels as $level => $sequence) {
76+
if (str_contains($jolietEscapeSequence, $sequence)) {
77+
$this->jolietLevel = $level; // Record the Joliet level if found
78+
break;
79+
}
80+
}
81+
}
6382

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

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

7797
$this->volumeSetId = trim(Buffer::readDString($this->bytes, 128, $offset, ($this->type === Type::SUPPLEMENTARY_VOLUME_DESC)));

src/FileDirectory.php

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ class FileDirectory
107107
*/
108108
public string $fileId;
109109

110+
public int $jolietLevel = 0;
111+
110112
/**
111113
* Load the "Directory Record" from buffer
112114
*
@@ -149,11 +151,20 @@ public function init(array &$buffer, int &$offset, bool $supplementary = false):
149151
$this->fileId = '..';
150152
$tmp++;
151153
} else {
152-
$this->fileId = Buffer::readDString($buffer, $this->fileIdLength, $tmp, $supplementary);
153-
154-
$pos = strpos($this->fileId, ';1');
155-
if ($pos !== false && $pos === strlen($this->fileId) - 2) {
156-
$this->fileId = substr($this->fileId, 0, strlen($this->fileId) - 2);
154+
if ($this->jolietLevel === 3) {
155+
$this->fileId = Buffer::readAString($buffer, $this->fileIdLength, $tmp, $supplementary);
156+
157+
$pos = strpos($this->fileId, ';1');
158+
if ($pos !== false && $pos === strlen($this->fileId) - 2) {
159+
$this->fileId = substr($this->fileId, 0, strlen($this->fileId) - 2);
160+
}
161+
} else {
162+
$this->fileId = Buffer::readDString($buffer, $this->fileIdLength, $tmp, $supplementary);
163+
164+
$pos = strpos($this->fileId, ';1');
165+
if ($pos !== false && $pos === strlen($this->fileId) - 2) {
166+
$this->fileId = substr($this->fileId, 0, strlen($this->fileId) - 2);
167+
}
157168
}
158169
}
159170

@@ -238,17 +249,17 @@ public function isParent(): bool
238249
*
239250
* @return array<int, FileDirectory>|false
240251
*/
241-
public function loadExtents(IsoFile $isoFile, int $blockSize, bool $supplementary = false): array|false
252+
public function loadExtents(IsoFile $isoFile, int $blockSize, bool $supplementary = false, int $jolietLevel = 0): array|false
242253
{
243-
return self::loadExtentsSt($isoFile, $blockSize, $this->location, $supplementary);
254+
return self::loadExtentsSt($isoFile, $blockSize, $this->location, $supplementary, $jolietLevel);
244255
}
245256

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

269280
$offset = 1;
270281
$fdDesc = new self();
282+
$fdDesc->jolietLevel = $jolietLevel;
271283
$extents = [];
272284

273285
while ($fdDesc->init($bytes, $offset, $supplementary) !== false) {
274286
$extents[] = $fdDesc;
275287
$fdDesc = new self();
288+
$fdDesc->jolietLevel = $jolietLevel;
276289
}
277290

278291
return $extents;

src/PathTableRecord.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,9 @@ public function init(array &$bytes, int &$offset, bool $supplementary = false):
8181
*
8282
* @return array<int, FileDirectory>|false
8383
*/
84-
public function loadExtents(IsoFile &$isoFile, int $blockSize, bool $supplementary = false): array|false
84+
public function loadExtents(IsoFile &$isoFile, int $blockSize, bool $supplementary = false, int $jolietLevel = 0): array|false
8585
{
86-
return FileDirectory::loadExtentsSt($isoFile, $blockSize, $this->location, $supplementary);
86+
return FileDirectory::loadExtentsSt($isoFile, $blockSize, $this->location, $supplementary, $jolietLevel);
8787
}
8888

8989
public function extractFile(IsoFile &$isoFile, int $blockSize, int $location, int $dataLength, string $destinationFile): void

src/Util/Buffer.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ public static function getString(array &$buffer, int $length, int &$offset = 0,
3333
if (! isset($buffer[$i])) {
3434
throw new Exception('Failed to read buffer entry ' . $i);
3535
}
36-
$string .= chr($buffer[$i]);
36+
if ($supplementary || $buffer[$i] !== 0) {
37+
$string .= chr($buffer[$i]);
38+
}
3739
}
3840

3941
if ($supplementary) {

tests/IsoFileTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ public function testDescriptorsDosIso(): void
311311
$this->assertSame('DOS4.01', $supplementaryVolumeDescriptor->volumeId);
312312
$this->assertSame(848, $supplementaryVolumeDescriptor->volumeSpaceSize);
313313
$this->assertSame('', $supplementaryVolumeDescriptor->appId);
314+
$this->assertSame(3, $supplementaryVolumeDescriptor->jolietLevel);
314315
$this->assertNull($supplementaryVolumeDescriptor->creationDate);
315316
$this->assertNull($supplementaryVolumeDescriptor->modificationDate);
316317
$this->assertNull($supplementaryVolumeDescriptor->expirationDate);

0 commit comments

Comments
 (0)