The MinGW.org Installation Manager Tool
リビジョン | e393b0f2b62da39cd796d30cdc349484fee339b1 (tree) |
---|---|
日時 | 2013-06-28 00:50:26 |
作者 | Keith Marshall <keithmarshall@user...> |
コミッター | Keith Marshall |
Improve diagnostics for tar archive processing faults.
@@ -1,3 +1,21 @@ | ||
1 | +2013-06-27 Keith Marshall <keithmarshall@users.sourceforge.net> | |
2 | + | |
3 | + Improve diagnostics for tar archive processing faults. | |
4 | + | |
5 | + * src/pkgproc.h (TAR_ARCHIVE_FORMAT_ERROR): New constant; define it. | |
6 | + (TAR_ARCHIVE_DATA_READ_ERROR, TAR_ARCHIVE_DATA_WRITE_ERROR): Likewise. | |
7 | + | |
8 | + * src/tarproc.cpp (dmh_notify_archive_data_exhausted): New static | |
9 | + inline function; implement it. | |
10 | + (pkgTarArchiveProcessor::GetArchiveEntry) [short header]: Use it. | |
11 | + (pkgArchiveProcessor::ExtractFile) [TAR_ARCHIVE_DATA_READ_ERROR]: | |
12 | + Likewise, use it here; also explicitlycheck for, and diagnose... | |
13 | + [TAR_ARCHIVE_DATA_WRITE_ERROR]: ...this; also add a further catch all | |
14 | + case, to diagnose any other unexpected condition. | |
15 | + (pkgTarArchiveProcessor::GetArchiveEntry) [bad checksum]: Diagnose it. | |
16 | + (pkgTarArchiveProcessor::Process): Return appropriate status codes. | |
17 | + (pkgTarArchiveProcessor::ProcessEntityData): Likewise. | |
18 | + | |
1 | 19 | 2013-06-24 Keith Marshall <keithmarshall@users.sourceforge.net> |
2 | 20 | |
3 | 21 | Facilitate version synchronisation for mingw-get-setup. |
@@ -137,7 +137,7 @@ union tar_archive_header | ||
137 | 137 | */ |
138 | 138 | #define TAR_ENTITY_TYPE_FILE '0' |
139 | 139 | #define TAR_ENTITY_TYPE_LINK '1' |
140 | -#define TAR_ENTITY_TYPE_SYMLINK '2' | |
140 | +#define TAR_ENTITY_TYPE_SYMLINK '2' | |
141 | 141 | #define TAR_ENTITY_TYPE_CHRDEV '3' |
142 | 142 | #define TAR_ENTITY_TYPE_BLKDEV '4' |
143 | 143 | #define TAR_ENTITY_TYPE_DIRECTORY '5' |
@@ -146,7 +146,13 @@ union tar_archive_header | ||
146 | 146 | /* Some older style tar archives may use '\0' as an alternative to '0', |
147 | 147 | * to identify an archive entry representing a regular file. |
148 | 148 | */ |
149 | -#define TAR_ENTITY_TYPE_ALTFILE '\0' | |
149 | +#define TAR_ENTITY_TYPE_ALTFILE '\0' | |
150 | + | |
151 | +/* Specify classification codes for tar archive processing errors. | |
152 | + */ | |
153 | +#define TAR_ARCHIVE_DATA_READ_ERROR -1 | |
154 | +#define TAR_ARCHIVE_DATA_WRITE_ERROR -2 | |
155 | +#define TAR_ARCHIVE_FORMAT_ERROR -3 | |
150 | 156 | |
151 | 157 | class pkgTarArchiveProcessor : public pkgArchiveProcessor |
152 | 158 | { |
@@ -68,6 +68,15 @@ int pkgArchiveProcessor::CreateExtractionDirectory( const char *pathname ) | ||
68 | 68 | return status; |
69 | 69 | } |
70 | 70 | |
71 | +static inline int dmh_notify_archive_data_exhausted( const char *context ) | |
72 | +{ | |
73 | + /* Helper function to emit "premature end of archive" diagnostics. | |
74 | + */ | |
75 | + return dmh_notify( DMH_ERROR, | |
76 | + "unexpected end of archive reading %s record\n", context | |
77 | + ); | |
78 | +} | |
79 | + | |
71 | 80 | inline int pkgArchiveProcessor::SetOutputStream( const char *name, int mode ) |
72 | 81 | { |
73 | 82 | /* Wrapper method to facilitate the set up of output streams |
@@ -98,6 +107,19 @@ int pkgArchiveProcessor::ExtractFile( int fd, const char *pathname, int status ) | ||
98 | 107 | */ |
99 | 108 | unlink( pathname ); |
100 | 109 | dmh_notify( DMH_ERROR, "%s: extraction failed\n", pathname ); |
110 | + switch( status ) | |
111 | + { | |
112 | + case TAR_ARCHIVE_DATA_READ_ERROR: | |
113 | + dmh_notify_archive_data_exhausted( "content" ); | |
114 | + break; | |
115 | + | |
116 | + case TAR_ARCHIVE_DATA_WRITE_ERROR: | |
117 | + dmh_notify( DMH_ERROR, "write error extracting file content\n" ); | |
118 | + break; | |
119 | + | |
120 | + default: | |
121 | + dmh_notify( DMH_ERROR, "unexpected fault; status = %d\n", status ); | |
122 | + } | |
101 | 123 | } |
102 | 124 | } |
103 | 125 | /* Finally, we pass the original status value back to the caller. |
@@ -249,9 +271,10 @@ int pkgTarArchiveProcessor::GetArchiveEntry() | ||
249 | 271 | |
250 | 272 | if( count < sizeof( header ) ) |
251 | 273 | { |
252 | - /* Failed to read a complete header; return error code. | |
274 | + /* Failed to read a complete header; diagnose and return error code. | |
253 | 275 | */ |
254 | - return -1; | |
276 | + dmh_notify_archive_data_exhausted( "header" ); | |
277 | + return TAR_ARCHIVE_DATA_READ_ERROR; | |
255 | 278 | } |
256 | 279 | |
257 | 280 | while( count-- ) |
@@ -280,9 +303,16 @@ int pkgTarArchiveProcessor::GetArchiveEntry() | ||
280 | 303 | } |
281 | 304 | /* After computing the checksum for a non-zero header, |
282 | 305 | * verify it against the value recorded in the checksum field; |
283 | - * return +1 for a successful match, or -2 for failure. | |
306 | + * return +1 for a successful match... | |
307 | + */ | |
308 | + if( sum == octval( header.field.chksum ) ) | |
309 | + return 1; | |
310 | + | |
311 | + /* ...otherwise diagnose checksum validation failure, and | |
312 | + * return the fault status. | |
284 | 313 | */ |
285 | - return (sum == octval( header.field.chksum )) ? 1 : -2; | |
314 | + dmh_notify( DMH_ERROR, "checksum validation failed\n" ); | |
315 | + return TAR_ARCHIVE_FORMAT_ERROR; | |
286 | 316 | } |
287 | 317 | |
288 | 318 | /* If we get to here, then the inner loop was never entered; |
@@ -297,7 +327,8 @@ int pkgTarArchiveProcessor::Process() | ||
297 | 327 | /* Generic method for reading tar archives, and extracting their |
298 | 328 | * content; loops over each archive entry in turn... |
299 | 329 | */ |
300 | - while( GetArchiveEntry() > 0 ) | |
330 | + int status; | |
331 | + while( (status = GetArchiveEntry()) > 0 ) | |
301 | 332 | { |
302 | 333 | char *prefix = *header.field.prefix ? header.field.prefix : NULL; |
303 | 334 | char *name = header.field.name; |
@@ -312,14 +343,19 @@ int pkgTarArchiveProcessor::Process() | ||
312 | 343 | { |
313 | 344 | /* Extract the full pathname from the data of this entry. |
314 | 345 | */ |
315 | - longname = EntityDataAsString(); | |
316 | - if( !longname ) | |
346 | + if( (longname = EntityDataAsString()) == NULL ) | |
347 | + { | |
317 | 348 | dmh_notify( DMH_ERROR, "Unable to read a long name entry\n" ); |
349 | + return TAR_ARCHIVE_FORMAT_ERROR; | |
350 | + } | |
318 | 351 | |
319 | 352 | /* Read the entry for which this long name is intended. |
320 | 353 | */ |
321 | 354 | if( GetArchiveEntry() <= 0 ) |
355 | + { | |
322 | 356 | dmh_notify( DMH_ERROR, "Expected a new entry after a long name entry\n" ); |
357 | + return TAR_ARCHIVE_FORMAT_ERROR; | |
358 | + } | |
323 | 359 | |
324 | 360 | /* Use the previously determined long name as the pathname for this entry. |
325 | 361 | */ |
@@ -448,7 +484,7 @@ int pkgTarArchiveProcessor::ProcessEntityData( int fd ) | ||
448 | 484 | * Failure to fully populate the transfer buffer, (i.e. a short |
449 | 485 | * read), indicates a corrupt archive; bail out immediately. |
450 | 486 | */ |
451 | - return -1; | |
487 | + return TAR_ARCHIVE_DATA_READ_ERROR; | |
452 | 488 | |
453 | 489 | /* When the number of actual data bytes expected is fewer than the |
454 | 490 | * total number of bytes in the transfer buffer... |
@@ -470,7 +506,7 @@ int pkgTarArchiveProcessor::ProcessEntityData( int fd ) | ||
470 | 506 | * An extraction error occurred; set the status code to |
471 | 507 | * indicate failure. |
472 | 508 | */ |
473 | - status = -2; | |
509 | + status = TAR_ARCHIVE_DATA_WRITE_ERROR; | |
474 | 510 | |
475 | 511 | /* Adjust the count of remaining unprocessed data bytes, and begin |
476 | 512 | * a new processing cycle, to capture any which may be present. |