47
47
48
48
#if PHYSFS_SUPPORTS_WAD
49
49
50
+ #define MAX_DEPTH 16
51
+
50
52
static int wadLoadEntries (PHYSFS_Io * io , const PHYSFS_uint32 count , void * arc )
51
53
{
54
+ PHYSFS_sint32 depth ;
55
+ char path [(MAX_DEPTH - 1 ) * 2 + 8 + MAX_DEPTH + 8 + 1 ];
56
+ PHYSFS_uint32 parent_positions [MAX_DEPTH + 1 ];
57
+ int parent_is_label = 0 ;
52
58
PHYSFS_uint32 i ;
59
+
60
+ depth = 0 ;
61
+ path [0 ] = '\0' ;
62
+ parent_positions [0 ] = 0 ;
63
+
53
64
for (i = 0 ; i < count ; i ++ )
54
65
{
55
66
PHYSFS_uint32 pos ;
56
67
PHYSFS_uint32 size ;
68
+ int is_directory ;
57
69
char name [9 ];
58
70
59
71
BAIL_IF_ERRPASS (!__PHYSFS_readAll (io , & pos , 4 ), 0 );
@@ -63,9 +75,48 @@ static int wadLoadEntries(PHYSFS_Io *io, const PHYSFS_uint32 count, void *arc)
63
75
name [8 ] = '\0' ; /* name might not be null-terminated in file. */
64
76
size = PHYSFS_swapULE32 (size );
65
77
pos = PHYSFS_swapULE32 (pos );
66
- BAIL_IF_ERRPASS (!UNPK_addEntry (arc , name , 0 , -1 , -1 , pos , size ), 0 );
78
+ is_directory = 0 ;
79
+
80
+ if (size == 0 ) {
81
+ size_t len = strlen (name );
82
+
83
+ if (parent_is_label ) {
84
+ BAIL_IF_ERRPASS (depth <= 0 , 0 );
85
+ depth -= 1 ;
86
+ parent_is_label = 0 ;
87
+ }
88
+
89
+ if (len > 6 && strcmp (name + len - 6 , "_START" ) == 0 ) {
90
+ BAIL_IF_ERRPASS (depth > MAX_DEPTH , 0 );
91
+ is_directory = 1 ;
92
+
93
+ strncpy (path + parent_positions [depth ], name , len - 6 );
94
+ strcpy (path + parent_positions [depth ] + len - 6 , "/" );
95
+ depth += 1 ;
96
+ parent_positions [depth ] = parent_positions [depth - 1 ] + len - 5 ;
97
+ } else if (len > 4 && strcmp (name + len - 4 , "_END" ) == 0 ) {
98
+ BAIL_IF_ERRPASS (depth <= 0 , 0 );
99
+
100
+ depth -= 1 ;
101
+ } else {
102
+ BAIL_IF_ERRPASS (depth > MAX_DEPTH , 0 );
103
+ is_directory = 1 ;
104
+ parent_is_label = 1 ;
105
+
106
+ strncpy (path + parent_positions [depth ], name , len );
107
+ strcpy (path + parent_positions [depth ] + len , "/" );
108
+ depth += 1 ;
109
+ parent_positions [depth ] = parent_positions [depth - 1 ] + len + 1 ;
110
+ }
111
+ continue ;
112
+ } else {
113
+ strcpy (path + parent_positions [depth ], name );
114
+ }
115
+ BAIL_IF_ERRPASS (!UNPK_addEntry (arc , path , is_directory , -1 , -1 , pos , size ), 0 );
67
116
} /* for */
68
117
118
+ BAIL_IF_ERRPASS (depth != 0 , 0 );
119
+
69
120
return 1 ;
70
121
} /* wadLoadEntries */
71
122
@@ -90,10 +141,10 @@ static void *WAD_openArchive(PHYSFS_Io *io, const char *name,
90
141
BAIL_IF_ERRPASS (!__PHYSFS_readAll (io , & count , sizeof (count )), NULL );
91
142
count = PHYSFS_swapULE32 (count );
92
143
93
- BAIL_IF_ERRPASS (!__PHYSFS_readAll (io , & directoryOffset , 4 ), 0 );
144
+ BAIL_IF_ERRPASS (!__PHYSFS_readAll (io , & directoryOffset , 4 ), NULL );
94
145
directoryOffset = PHYSFS_swapULE32 (directoryOffset );
95
146
96
- BAIL_IF_ERRPASS (!io -> seek (io , directoryOffset ), 0 );
147
+ BAIL_IF_ERRPASS (!io -> seek (io , directoryOffset ), NULL );
97
148
98
149
unpkarc = UNPK_openArchive (io , 0 , 1 );
99
150
BAIL_IF_ERRPASS (!unpkarc , NULL );
0 commit comments