~ubuntu-branches/ubuntu/quantal/libarchive/quantal

« back to all changes in this revision

Viewing changes to libarchive/archive_read_support_format_iso9660.c

  • Committer: Package Import Robot
  • Author(s): Andres Mejia
  • Date: 2012-02-23 19:29:24 UTC
  • mfrom: (8.1.10 sid)
  • Revision ID: package-import@ubuntu.com-20120223192924-73n4iedok5fwgsyr
Tags: 3.0.3-5
* Detect if locales or locales-all is installed for use with test suite.
* Bump Standards-Version to 3.9.3.

Show diffs side-by-side

added added

removed removed

Lines of Context:
47
47
#include "archive.h"
48
48
#include "archive_endian.h"
49
49
#include "archive_entry.h"
 
50
#include "archive_entry_locale.h"
50
51
#include "archive_private.h"
51
52
#include "archive_read_private.h"
52
53
#include "archive_string.h"
285
286
        int64_t          number;
286
287
        int              nlinks;
287
288
        struct archive_string name; /* Pathname */
 
289
        unsigned char   *utf16be_name;
 
290
        size_t           utf16be_bytes;
288
291
        char             name_continues; /* Non-zero if name continues */
289
292
        struct archive_string symlink;
290
293
        char             symlink_continues; /* Non-zero if link continues */
357
360
                uint32_t        size;
358
361
        } primary, joliet;
359
362
 
360
 
        off_t   entry_sparse_offset;
 
363
        int64_t entry_sparse_offset;
361
364
        int64_t entry_bytes_remaining;
 
365
        size_t  entry_bytes_unconsumed;
362
366
        struct zisofs    entry_zisofs;
363
367
        struct content  *entry_content;
 
368
        struct archive_string_conv *sconv_utf16be;
 
369
        /*
 
370
         * Buffers for a full pathname in UTF-16BE in Joliet extensions.
 
371
         */
 
372
#define UTF16_NAME_MAX  1024
 
373
        unsigned char *utf16be_path;
 
374
        size_t           utf16be_path_len;
 
375
        unsigned char *utf16be_previous_path;
 
376
        size_t           utf16be_previous_path_len;
364
377
};
365
378
 
366
 
static int      archive_read_format_iso9660_bid(struct archive_read *);
 
379
static int      archive_read_format_iso9660_bid(struct archive_read *, int);
367
380
static int      archive_read_format_iso9660_options(struct archive_read *,
368
381
                    const char *, const char *);
369
382
static int      archive_read_format_iso9660_cleanup(struct archive_read *);
370
383
static int      archive_read_format_iso9660_read_data(struct archive_read *,
371
 
                    const void **, size_t *, off_t *);
 
384
                    const void **, size_t *, int64_t *);
372
385
static int      archive_read_format_iso9660_read_data_skip(struct archive_read *);
373
386
static int      archive_read_format_iso9660_read_header(struct archive_read *,
374
387
                    struct archive_entry *);
375
388
static const char *build_pathname(struct archive_string *, struct file_info *);
 
389
static int      build_pathname_utf16be(unsigned char *, size_t, size_t *,
 
390
                    struct file_info *);
376
391
#if DEBUG
377
392
static void     dump_isodirrec(FILE *, const unsigned char *isodirrec);
378
393
#endif
388
403
static int      isPVD(struct iso9660 *, const unsigned char *);
389
404
static int      next_cache_entry(struct archive_read *, struct iso9660 *,
390
405
                    struct file_info **);
391
 
static int      next_entry_seek(struct archive_read *a, struct iso9660 *iso9660,
392
 
                    struct file_info **pfile);
 
406
static int      next_entry_seek(struct archive_read *, struct iso9660 *,
 
407
                    struct file_info **);
393
408
static struct file_info *
394
409
                parse_file_info(struct archive_read *a,
395
410
                    struct file_info *parent, const unsigned char *isodirrec);
433
448
        struct iso9660 *iso9660;
434
449
        int r;
435
450
 
436
 
        iso9660 = (struct iso9660 *)malloc(sizeof(*iso9660));
 
451
        archive_check_magic(_a, ARCHIVE_READ_MAGIC,
 
452
            ARCHIVE_STATE_NEW, "archive_read_support_format_iso9660");
 
453
 
 
454
        iso9660 = (struct iso9660 *)calloc(1, sizeof(*iso9660));
437
455
        if (iso9660 == NULL) {
438
 
                archive_set_error(&a->archive, ENOMEM, "Can't allocate iso9660 data");
 
456
                archive_set_error(&a->archive, ENOMEM,
 
457
                    "Can't allocate iso9660 data");
439
458
                return (ARCHIVE_FATAL);
440
459
        }
441
 
        memset(iso9660, 0, sizeof(*iso9660));
442
460
        iso9660->magic = ISO9660_MAGIC;
443
461
        iso9660->cache_files.first = NULL;
444
462
        iso9660->cache_files.last = &(iso9660->cache_files.first);
468
486
 
469
487
 
470
488
static int
471
 
archive_read_format_iso9660_bid(struct archive_read *a)
 
489
archive_read_format_iso9660_bid(struct archive_read *a, int best_bid)
472
490
{
473
491
        struct iso9660 *iso9660;
474
492
        ssize_t bytes_read;
475
 
        const void *h;
476
493
        const unsigned char *p;
477
494
        int seenTerminator;
478
495
 
 
496
        /* If there's already a better bid than we can ever
 
497
           make, don't bother testing. */
 
498
        if (best_bid > 48)
 
499
                return (-1);
 
500
 
479
501
        iso9660 = (struct iso9660 *)(a->format->data);
480
502
 
481
503
        /*
484
506
         * if the I/O layer gives us more, we'll take it.
485
507
         */
486
508
#define RESERVED_AREA   (SYSTEM_AREA_BLOCK * LOGICAL_BLOCK_SIZE)
487
 
        h = __archive_read_ahead(a,
 
509
        p = __archive_read_ahead(a,
488
510
            RESERVED_AREA + 8 * LOGICAL_BLOCK_SIZE,
489
511
            &bytes_read);
490
 
        if (h == NULL)
 
512
        if (p == NULL)
491
513
            return (-1);
492
 
        p = (const unsigned char *)h;
493
514
 
494
515
        /* Skip the reserved area. */
495
516
        bytes_read -= RESERVED_AREA;
505
526
                /* Standard Identifier must be "CD001" */
506
527
                if (memcmp(p + 1, "CD001", 5) != 0)
507
528
                        return (0);
508
 
                if (!iso9660->primary.location) {
509
 
                        if (isPVD(iso9660, p))
510
 
                                continue;
511
 
                }
 
529
                if (isPVD(iso9660, p))
 
530
                        continue;
512
531
                if (!iso9660->joliet.location) {
513
532
                        if (isJolietSVD(iso9660, p))
514
533
                                continue;
564
583
 
565
584
        /* Note: The "warn" return is just to inform the options
566
585
         * supervisor that we didn't handle it.  It will generate
567
 
         * a suitable error if noone used this option. */
 
586
         * a suitable error if no one used this option. */
568
587
        return (ARCHIVE_WARN);
569
588
}
570
589
 
893
912
                return (0);
894
913
 
895
914
        /* Reserved field must be 0. */
 
915
        /* But accept NetBSD/FreeBSD "makefs" images with 0x20 here. */
896
916
        for (i = 0; i < PVD_reserved4_size; ++i)
897
 
                if (h[PVD_reserved4_offset + i] != 0)
 
917
                if (h[PVD_reserved4_offset + i] != 0
 
918
                    && h[PVD_reserved4_offset + i] != 0x20)
898
919
                        return (0);
899
920
 
900
921
        /* Reserved field must be 0. */
910
931
        if (p[DR_length_offset] != 34)
911
932
                return (0);
912
933
 
913
 
        iso9660->logical_block_size = logical_block_size;
914
 
        iso9660->volume_block = volume_block;
915
 
        iso9660->volume_size = logical_block_size * (uint64_t)volume_block;
916
 
        iso9660->primary.location = archive_le32dec(p + DR_extent_offset);
917
 
        iso9660->primary.size = archive_le32dec(p + DR_size_offset);
 
934
        if (!iso9660->primary.location) {
 
935
                iso9660->logical_block_size = logical_block_size;
 
936
                iso9660->volume_block = volume_block;
 
937
                iso9660->volume_size = logical_block_size * (uint64_t)volume_block;
 
938
                iso9660->primary.location = archive_le32dec(p + DR_extent_offset);
 
939
                iso9660->primary.size = archive_le32dec(p + DR_size_offset);
 
940
        }
918
941
 
919
942
        return (48);
920
943
}
925
948
        struct iso9660 *iso9660;
926
949
        const unsigned char *b, *p;
927
950
        struct file_info *multi;
928
 
        size_t step;
 
951
        size_t step, skip_size;
929
952
 
930
953
        iso9660 = (struct iso9660 *)(a->format->data);
931
954
        if (iso9660->current_position > parent->offset) {
946
969
                int64_t skipsize;
947
970
 
948
971
                skipsize = parent->offset - iso9660->current_position;
949
 
                skipsize = __archive_read_skip(a, skipsize);
 
972
                skipsize = __archive_read_consume(a, skipsize);
950
973
                if (skipsize < 0)
951
974
                        return ((int)skipsize);
952
975
                iso9660->current_position = parent->offset;
961
984
                    "ISO9660 directory list");
962
985
                return (ARCHIVE_FATAL);
963
986
        }
964
 
        __archive_read_consume(a, step);
965
987
        iso9660->current_position += step;
966
988
        multi = NULL;
 
989
        skip_size = step;
967
990
        while (step) {
968
991
                p = b;
969
992
                b += iso9660->logical_block_size;
985
1008
                            && *(p + DR_name_offset) == '\001')
986
1009
                                continue;
987
1010
                        child = parse_file_info(a, parent, p);
988
 
                        if (child == NULL)
 
1011
                        if (child == NULL) {
 
1012
                                __archive_read_consume(a, skip_size);
989
1013
                                return (ARCHIVE_FATAL);
 
1014
                        }
990
1015
                        if (child->cl_offset == 0 &&
991
1016
                            (child->multi_extent || multi != NULL)) {
992
1017
                                struct content *con;
1001
1026
                                if (con == NULL) {
1002
1027
                                        archive_set_error(
1003
1028
                                            &a->archive, ENOMEM,
1004
 
                                            "No memory for "
1005
 
                                            "multi extent");
 
1029
                                            "No memory for multi extent");
 
1030
                                        __archive_read_consume(a, skip_size);
1006
1031
                                        return (ARCHIVE_FATAL);
1007
1032
                                }
1008
1033
                                con->offset = child->offset;
1010
1035
                                con->next = NULL;
1011
1036
                                *multi->contents.last = con;
1012
1037
                                multi->contents.last = &(con->next);
1013
 
                                        if (multi == child) {
1014
 
                                                if (add_entry(a, iso9660, child)
1015
 
                                                    != ARCHIVE_OK)
1016
 
                                                        return (ARCHIVE_FATAL);
1017
 
                                        } else {
 
1038
                                if (multi == child) {
 
1039
                                        if (add_entry(a, iso9660, child)
 
1040
                                            != ARCHIVE_OK)
 
1041
                                                return (ARCHIVE_FATAL);
 
1042
                                } else {
1018
1043
                                        multi->size += child->size;
1019
1044
                                        if (!child->multi_extent)
1020
1045
                                                multi = NULL;
1021
1046
                                }
1022
1047
                        } else
1023
 
                                        if (add_entry(a, iso9660, child)
1024
 
                                            != ARCHIVE_OK)
1025
 
                                                return (ARCHIVE_FATAL);
 
1048
                                if (add_entry(a, iso9660, child) != ARCHIVE_OK)
 
1049
                                        return (ARCHIVE_FATAL);
1026
1050
                }
1027
1051
        }
1028
1052
 
 
1053
        __archive_read_consume(a, skip_size);
 
1054
 
1029
1055
        /* Read data which recorded by RRIP "CE" extension. */
1030
1056
        if (read_CE(a, iso9660) != ARCHIVE_OK)
1031
1057
                return (ARCHIVE_FATAL);
1063
1089
                        vd = &(iso9660->joliet);
1064
1090
 
1065
1091
                skipsize = LOGICAL_BLOCK_SIZE * vd->location;
1066
 
                skipsize = __archive_read_skip(a, skipsize);
 
1092
                skipsize = __archive_read_consume(a, skipsize);
1067
1093
                if (skipsize < 0)
1068
1094
                        return ((int)skipsize);
1069
1095
                iso9660->current_position = skipsize;
1101
1127
                        vd = &(iso9660->joliet);
1102
1128
                        skipsize = LOGICAL_BLOCK_SIZE * vd->location;
1103
1129
                        skipsize -= iso9660->current_position;
1104
 
                        skipsize = __archive_read_skip(a, skipsize);
 
1130
                        skipsize = __archive_read_consume(a, skipsize);
1105
1131
                        if (skipsize < 0)
1106
1132
                                return ((int)skipsize);
1107
1133
                        iso9660->current_position += skipsize;
1114
1140
                                    "ISO9660 directory list");
1115
1141
                                return (ARCHIVE_FATAL);
1116
1142
                        }
1117
 
                        seenJoliet = iso9660->seenJoliet;/* Save flag. */
1118
1143
                        iso9660->seenJoliet = 0;
1119
1144
                        file = parse_file_info(a, NULL, block);
1120
1145
                        if (file == NULL)
1132
1157
                }
1133
1158
        }
1134
1159
 
 
1160
        file = NULL;/* Eliminate a warning. */
1135
1161
        /* Get the next entry that appears after the current offset. */
1136
1162
        r = next_entry_seek(a, iso9660, &file);
1137
1163
        if (r != ARCHIVE_OK)
1138
1164
                return (r);
1139
1165
 
 
1166
        if (iso9660->seenJoliet) {
 
1167
                /*
 
1168
                 * Convert UTF-16BE of a filename to local locale MBS
 
1169
                 * and store the result into a filename field.
 
1170
                 */
 
1171
                if (iso9660->sconv_utf16be == NULL) {
 
1172
                        iso9660->sconv_utf16be =
 
1173
                            archive_string_conversion_from_charset(
 
1174
                                &(a->archive), "UTF-16BE", 1);
 
1175
                        if (iso9660->sconv_utf16be == NULL)
 
1176
                                /* Coundn't allocate memory */
 
1177
                                return (ARCHIVE_FATAL);
 
1178
                }
 
1179
                if (iso9660->utf16be_path == NULL) {
 
1180
                        iso9660->utf16be_path = malloc(UTF16_NAME_MAX);
 
1181
                        if (iso9660->utf16be_path == NULL) {
 
1182
                                archive_set_error(&a->archive, ENOMEM,
 
1183
                                    "No memory");
 
1184
                                return (ARCHIVE_FATAL);
 
1185
                        }
 
1186
                }
 
1187
                if (iso9660->utf16be_previous_path == NULL) {
 
1188
                        iso9660->utf16be_previous_path = malloc(UTF16_NAME_MAX);
 
1189
                        if (iso9660->utf16be_previous_path == NULL) {
 
1190
                                archive_set_error(&a->archive, ENOMEM,
 
1191
                                    "No memory");
 
1192
                                return (ARCHIVE_FATAL);
 
1193
                        }
 
1194
                }
 
1195
 
 
1196
                iso9660->utf16be_path_len = 0;
 
1197
                if (build_pathname_utf16be(iso9660->utf16be_path,
 
1198
                    UTF16_NAME_MAX, &(iso9660->utf16be_path_len), file) != 0) {
 
1199
                        archive_set_error(&a->archive,
 
1200
                            ARCHIVE_ERRNO_FILE_FORMAT,
 
1201
                            "Pathname is too long");
 
1202
                }
 
1203
 
 
1204
                r = archive_entry_copy_pathname_l(entry,
 
1205
                    (const char *)iso9660->utf16be_path,
 
1206
                    iso9660->utf16be_path_len,
 
1207
                    iso9660->sconv_utf16be);
 
1208
                if (r != 0) {
 
1209
                        if (errno == ENOMEM) {
 
1210
                                archive_set_error(&a->archive, ENOMEM,
 
1211
                                    "No memory for Pathname");
 
1212
                                return (ARCHIVE_FATAL);
 
1213
                        }
 
1214
                        archive_set_error(&a->archive,
 
1215
                            ARCHIVE_ERRNO_FILE_FORMAT,
 
1216
                            "Pathname cannot be converted "
 
1217
                            "from %s to current locale.",
 
1218
                            archive_string_conversion_charset_name(
 
1219
                              iso9660->sconv_utf16be));
 
1220
 
 
1221
                        rd_r = ARCHIVE_WARN;
 
1222
                }
 
1223
        } else {
 
1224
                archive_string_empty(&iso9660->pathname);
 
1225
                archive_entry_set_pathname(entry,
 
1226
                    build_pathname(&iso9660->pathname, file));
 
1227
        }
 
1228
 
1140
1229
        iso9660->entry_bytes_remaining = file->size;
1141
1230
        iso9660->entry_sparse_offset = 0; /* Offset for sparse-file-aware clients. */
1142
1231
 
1143
1232
        if (file->offset + file->size > iso9660->volume_size) {
1144
1233
                archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1145
 
                    "File is beyond end-of-media: %s", file->name.s);
 
1234
                    "File is beyond end-of-media: %s",
 
1235
                    archive_entry_pathname(entry));
1146
1236
                iso9660->entry_bytes_remaining = 0;
1147
1237
                iso9660->entry_sparse_offset = 0;
1148
1238
                return (ARCHIVE_WARN);
1163
1253
        /* N.B.: Rock Ridge supports 64-bit device numbers. */
1164
1254
        archive_entry_set_rdev(entry, (dev_t)file->rdev);
1165
1255
        archive_entry_set_size(entry, iso9660->entry_bytes_remaining);
1166
 
        archive_string_empty(&iso9660->pathname);
1167
 
        archive_entry_set_pathname(entry,
1168
 
            build_pathname(&iso9660->pathname, file));
1169
1256
        if (file->symlink.s != NULL)
1170
1257
                archive_entry_copy_symlink(entry, file->symlink.s);
1171
1258
 
1175
1262
         * original entry. */
1176
1263
        if (file->number != -1 &&
1177
1264
            file->number == iso9660->previous_number) {
1178
 
                archive_entry_set_hardlink(entry,
1179
 
                    iso9660->previous_pathname.s);
 
1265
                if (iso9660->seenJoliet) {
 
1266
                        r = archive_entry_copy_hardlink_l(entry,
 
1267
                            (const char *)iso9660->utf16be_previous_path,
 
1268
                            iso9660->utf16be_previous_path_len,
 
1269
                            iso9660->sconv_utf16be);
 
1270
                        if (r != 0) {
 
1271
                                if (errno == ENOMEM) {
 
1272
                                        archive_set_error(&a->archive, ENOMEM,
 
1273
                                            "No memory for Linkname");
 
1274
                                        return (ARCHIVE_FATAL);
 
1275
                                }
 
1276
                                archive_set_error(&a->archive,
 
1277
                                    ARCHIVE_ERRNO_FILE_FORMAT,
 
1278
                                    "Linkname cannot be converted "
 
1279
                                    "from %s to current locale.",
 
1280
                                    archive_string_conversion_charset_name(
 
1281
                                      iso9660->sconv_utf16be));
 
1282
                                rd_r = ARCHIVE_WARN;
 
1283
                        }
 
1284
                } else
 
1285
                        archive_entry_set_hardlink(entry,
 
1286
                            iso9660->previous_pathname.s);
1180
1287
                archive_entry_unset_size(entry);
1181
1288
                iso9660->entry_bytes_remaining = 0;
1182
1289
                iso9660->entry_sparse_offset = 0;
1183
 
                return (ARCHIVE_OK);
 
1290
                return (rd_r);
1184
1291
        }
1185
1292
 
1186
1293
        /* Except for the hardlink case above, if the offset of the
1201
1308
        if ((file->mode & AE_IFMT) != AE_IFDIR &&
1202
1309
            file->offset < iso9660->current_position) {
1203
1310
                archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1204
 
                    "Ignoring out-of-order file (%s) %jd < %jd",
 
1311
                    "Ignoring out-of-order file @%jx (%s) %jd < %jd",
 
1312
                    (intmax_t)file->number,
1205
1313
                    iso9660->pathname.s,
1206
1314
                    (intmax_t)file->offset,
1207
1315
                    (intmax_t)iso9660->current_position);
1229
1337
        }
1230
1338
 
1231
1339
        iso9660->previous_number = file->number;
1232
 
        archive_strcpy(&iso9660->previous_pathname, iso9660->pathname.s);
 
1340
        if (iso9660->seenJoliet) {
 
1341
                memcpy(iso9660->utf16be_previous_path, iso9660->utf16be_path,
 
1342
                    iso9660->utf16be_path_len);
 
1343
                iso9660->utf16be_previous_path_len = iso9660->utf16be_path_len;
 
1344
        } else
 
1345
                archive_strcpy(
 
1346
                    &iso9660->previous_pathname, iso9660->pathname.s);
1233
1347
 
1234
1348
        /* Reset entry_bytes_remaining if the file is multi extent. */
1235
1349
        iso9660->entry_content = file->contents.first;
1263
1377
 
1264
1378
static int
1265
1379
zisofs_read_data(struct archive_read *a,
1266
 
    const void **buff, size_t *size, off_t *offset)
 
1380
    const void **buff, size_t *size, int64_t *offset)
1267
1381
{
1268
1382
        struct iso9660 *iso9660;
1269
1383
        struct zisofs  *zisofs;
1385
1499
                }
1386
1500
 
1387
1501
                if (!zisofs->initialized)
1388
 
                        goto next_data; /* We need more datas. */
 
1502
                        goto next_data; /* We need more data. */
1389
1503
        }
1390
1504
 
1391
1505
        /*
1396
1510
 
1397
1511
                if (zisofs->block_off + 4 >= zisofs->block_pointers_size) {
1398
1512
                        /* There isn't a pair of offsets. */
1399
 
                        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
 
1513
                        archive_set_error(&a->archive,
 
1514
                            ARCHIVE_ERRNO_FILE_FORMAT,
1400
1515
                            "Illegal zisofs block pointers");
1401
1516
                        return (ARCHIVE_FATAL);
1402
1517
                }
1403
 
                bst = archive_le32dec(zisofs->block_pointers + zisofs->block_off);
 
1518
                bst = archive_le32dec(
 
1519
                    zisofs->block_pointers + zisofs->block_off);
1404
1520
                if (bst != zisofs->pz_offset + (bytes_read - avail)) {
1405
 
                        /* TODO: Should we seek offset of current file by bst ? */
1406
 
                        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
 
1521
                        /* TODO: Should we seek offset of current file
 
1522
                         * by bst ? */
 
1523
                        archive_set_error(&a->archive,
 
1524
                            ARCHIVE_ERRNO_FILE_FORMAT,
1407
1525
                            "Illegal zisofs block pointers(cannot seek)");
1408
1526
                        return (ARCHIVE_FATAL);
1409
1527
                }
1410
1528
                bed = archive_le32dec(
1411
1529
                    zisofs->block_pointers + zisofs->block_off + 4);
1412
1530
                if (bed < bst) {
1413
 
                        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
 
1531
                        archive_set_error(&a->archive,
 
1532
                            ARCHIVE_ERRNO_FILE_FORMAT,
1414
1533
                            "Illegal zisofs block pointers");
1415
1534
                        return (ARCHIVE_FATAL);
1416
1535
                }
1433
1552
        }
1434
1553
 
1435
1554
        /*
1436
 
         * Make uncompressed datas.
 
1555
         * Make uncompressed data.
1437
1556
         */
1438
1557
        if (zisofs->block_avail == 0) {
1439
1558
                memset(zisofs->uncompressed_buffer, 0,
1472
1591
        iso9660->entry_bytes_remaining -= bytes_read;
1473
1592
        iso9660->current_position += bytes_read;
1474
1593
        zisofs->pz_offset += bytes_read;
1475
 
        __archive_read_consume(a, bytes_read);
 
1594
        iso9660->entry_bytes_unconsumed += bytes_read;
1476
1595
 
1477
1596
        return (ARCHIVE_OK);
1478
1597
}
1481
1600
 
1482
1601
static int
1483
1602
zisofs_read_data(struct archive_read *a,
1484
 
    const void **buff, size_t *size, off_t *offset)
 
1603
    const void **buff, size_t *size, int64_t *offset)
1485
1604
{
1486
1605
 
1487
1606
        (void)buff;/* UNUSED */
1496
1615
 
1497
1616
static int
1498
1617
archive_read_format_iso9660_read_data(struct archive_read *a,
1499
 
    const void **buff, size_t *size, off_t *offset)
 
1618
    const void **buff, size_t *size, int64_t *offset)
1500
1619
{
1501
1620
        ssize_t bytes_read;
1502
1621
        struct iso9660 *iso9660;
1503
1622
 
1504
1623
        iso9660 = (struct iso9660 *)(a->format->data);
 
1624
 
 
1625
        if (iso9660->entry_bytes_unconsumed) {
 
1626
                __archive_read_consume(a, iso9660->entry_bytes_unconsumed);
 
1627
                iso9660->entry_bytes_unconsumed = 0;
 
1628
        }
 
1629
 
1505
1630
        if (iso9660->entry_bytes_remaining <= 0) {
1506
1631
                if (iso9660->entry_content != NULL)
1507
1632
                        iso9660->entry_content = iso9660->entry_content->next;
1517
1642
 
1518
1643
                        step = iso9660->entry_content->offset -
1519
1644
                            iso9660->current_position;
1520
 
                        step = __archive_read_skip(a, step);
 
1645
                        step = __archive_read_consume(a, step);
1521
1646
                        if (step < 0)
1522
1647
                                return ((int)step);
1523
1648
                        iso9660->current_position =
1551
1676
        *offset = iso9660->entry_sparse_offset;
1552
1677
        iso9660->entry_sparse_offset += bytes_read;
1553
1678
        iso9660->entry_bytes_remaining -= bytes_read;
 
1679
        iso9660->entry_bytes_unconsumed = bytes_read;
1554
1680
        iso9660->current_position += bytes_read;
1555
 
        __archive_read_consume(a, bytes_read);
1556
1681
        return (ARCHIVE_OK);
1557
1682
}
1558
1683
 
1580
1705
                }
1581
1706
        }
1582
1707
#endif
 
1708
        free(iso9660->utf16be_path);
 
1709
        free(iso9660->utf16be_previous_path);
1583
1710
        free(iso9660);
1584
1711
        (a->format->data) = NULL;
1585
1712
        return (r);
1634
1761
                    "Invalid location of extent of file");
1635
1762
                return (NULL);
1636
1763
        }
 
1764
        /* Sanity check that location doesn't have a negative value
 
1765
         * when the file is not empty. it's too large. */
 
1766
        if (fsize != 0 && location < 0) {
 
1767
                archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 
1768
                    "Invalid location of extent of file");
 
1769
                return (NULL);
 
1770
        }
1637
1771
 
1638
1772
        /* Create a new file entry and copy data from the ISO dir record. */
1639
 
        file = (struct file_info *)malloc(sizeof(*file));
 
1773
        file = (struct file_info *)calloc(1, sizeof(*file));
1640
1774
        if (file == NULL) {
1641
1775
                archive_set_error(&a->archive, ENOMEM,
1642
1776
                    "No memory for file entry");
1643
1777
                return (NULL);
1644
1778
        }
1645
 
        memset(file, 0, sizeof(*file));
1646
1779
        file->parent = parent;
1647
1780
        file->offset = iso9660->logical_block_size * (uint64_t)location;
1648
1781
        file->size = fsize;
1663
1796
                 * names which are 103 UCS2 characters(206 bytes) by their
1664
1797
                 * option '-joliet-long'.
1665
1798
                 */
1666
 
                wchar_t wbuff[103+1], *wp;
1667
 
                const unsigned char *c;
1668
 
 
1669
1799
                if (name_len > 206)
1670
1800
                        name_len = 206;
1671
 
                /* convert BE UTF-16 to wchar_t */
1672
 
                for (c = p, wp = wbuff;
1673
 
                                c < (p + name_len) &&
1674
 
                                wp < (wbuff + sizeof(wbuff)/sizeof(*wbuff) - 1);
1675
 
                                c += 2) {
1676
 
                        *wp++ = (((255 & (int)c[0]) << 8) | (255 & (int)c[1]));
1677
 
                }
1678
 
                *wp = L'\0';
 
1801
                name_len &= ~1;
1679
1802
 
1680
1803
                /* trim trailing first version and dot from filename.
1681
1804
                 *
1682
 
                 * Remember we where in UTF-16BE land!
 
1805
                 * Remember we were in UTF-16BE land!
1683
1806
                 * SEPARATOR 1 (.) and SEPARATOR 2 (;) are both
1684
1807
                 * 16 bits big endian characters on Joliet.
1685
1808
                 *
1688
1811
                 *       *, /, :, ;, ? and \.
1689
1812
                 */
1690
1813
                /* Chop off trailing ';1' from files. */
1691
 
                if (*(wp-2) == L';' && *(wp-1) == L'1') {
1692
 
                        wp-=2;
1693
 
                        *wp = L'\0';
1694
 
                }
1695
 
 
 
1814
                if (name_len > 4 && p[name_len-4] == 0 && p[name_len-3] == ';'
 
1815
                    && p[name_len-2] == 0 && p[name_len-1] == '1')
 
1816
                        name_len -= 4;
1696
1817
#if 0 /* XXX: this somehow manages to strip of single-character file extensions, like '.c'. */
1697
1818
                /* Chop off trailing '.' from filenames. */
1698
 
                if (*(wp-1) == L'.')
1699
 
                        *(--wp) = L'\0';
 
1819
                if (name_len > 2 && p[name_len-2] == 0 && p[name_len-1] == '.')
 
1820
                        name_len -= 2;
1700
1821
#endif
1701
 
 
1702
 
                /* store the result in the file name field. */
1703
 
                archive_strappend_w_utf8(&file->name, wbuff);
 
1822
                if ((file->utf16be_name = malloc(name_len)) == NULL) {
 
1823
                        archive_set_error(&a->archive, ENOMEM,
 
1824
                            "No memory for file name");
 
1825
                        return (NULL);
 
1826
                }
 
1827
                memcpy(file->utf16be_name, p, name_len);
 
1828
                file->utf16be_bytes = name_len;
1704
1829
        } else {
1705
1830
                /* Chop off trailing ';1' from files. */
1706
1831
                if (name_len > 2 && p[name_len - 2] == ';' &&
1723
1848
        else
1724
1849
                file->multi_extent = 0;
1725
1850
        /*
1726
 
         * Use location for file number.
1727
 
         * File number is treated as inode number to find out harlink
1728
 
         * target. If Rockridge extensions is being used, file number
1729
 
         * will be overwritten by FILE SERIAL NUMBER of RRIP "PX"
1730
 
         * extension.
1731
 
         * NOTE: Old mkisofs did not record that FILE SERIAL NUMBER
 
1851
         * Use a location for the file number, which is treated as an inode
 
1852
         * number to find out hardlink target. If Rockridge extensions is
 
1853
         * being used, the file number will be overwritten by FILE SERIAL
 
1854
         * NUMBER of RRIP "PX" extension.
 
1855
         * Note: Old mkisofs did not record that FILE SERIAL NUMBER
1732
1856
         * in ISO images.
 
1857
         * Note2: xorriso set 0 to the location of a symlink file. 
1733
1858
         */
1734
1859
        if (file->size == 0 && location >= 0) {
1735
 
                /* If file->size is zero, its location points wrong place.
1736
 
                 * Dot not use it for file number.
1737
 
                 * When location has negative value, it can be used
1738
 
                 * for file number.
 
1860
                /* If file->size is zero, its location points wrong place,
 
1861
                 * and so we should not use it for the file number.
 
1862
                 * When the location has negative value, it can be used
 
1863
                 * for the file number.
1739
1864
                 */
1740
1865
                file->number = -1;
1741
 
                /* Do not appear before any directoy entries. */
1742
 
                if (file->offset == 0)
1743
 
                        file->offset = -1;
 
1866
                /* Do not appear before any directory entries. */
 
1867
                file->offset = -1;
1744
1868
        } else
1745
1869
                file->number = (int64_t)(uint32_t)location;
1746
1870
 
1805
1929
                        file->re = 0;
1806
1930
                        parent->subdirs--;
1807
1931
                } else if (file->re) {
1808
 
                        /* This file's parent is not rr_moved, clear invalid
1809
 
                         * "RE" mark. */
1810
 
                        if (parent == NULL || parent->rr_moved == 0)
1811
 
                                file->re = 0;
1812
 
                        else if ((flags & 0x02) == 0) {
1813
 
                                file->rr_moved_has_re_only = 0;
1814
 
                                file->re = 0;
 
1932
                        /*
 
1933
                         * Sanity check: file's parent is rr_moved.
 
1934
                         */
 
1935
                        if (parent == NULL || parent->rr_moved == 0) {
 
1936
                                archive_set_error(&a->archive,
 
1937
                                    ARCHIVE_ERRNO_MISC,
 
1938
                                    "Invalid Rockridge RE");
 
1939
                                return (NULL);
 
1940
                        }
 
1941
                        /*
 
1942
                         * Sanity check: file does not have "CL" extension.
 
1943
                         */
 
1944
                        if (file->cl_offset) {
 
1945
                                archive_set_error(&a->archive,
 
1946
                                    ARCHIVE_ERRNO_MISC,
 
1947
                                    "Invalid Rockridge RE and CL");
 
1948
                                return (NULL);
 
1949
                        }
 
1950
                        /*
 
1951
                         * Sanity check: The file type must be a directory.
 
1952
                         */
 
1953
                        if ((flags & 0x02) == 0) {
 
1954
                                archive_set_error(&a->archive,
 
1955
                                    ARCHIVE_ERRNO_MISC,
 
1956
                                    "Invalid Rockridge RE");
 
1957
                                return (NULL);
1815
1958
                        }
1816
1959
                } else if (parent != NULL && parent->rr_moved)
1817
1960
                        file->rr_moved_has_re_only = 0;
1818
1961
                else if (parent != NULL && (flags & 0x02) &&
1819
1962
                    (parent->re || parent->re_descendant))
1820
1963
                        file->re_descendant = 1;
1821
 
                if (file->cl_offset != 0) {
 
1964
                if (file->cl_offset) {
 
1965
                        struct file_info *r;
 
1966
 
 
1967
                        if (parent == NULL || parent->parent == NULL) {
 
1968
                                archive_set_error(&a->archive,
 
1969
                                    ARCHIVE_ERRNO_MISC,
 
1970
                                    "Invalid Rockridge CL");
 
1971
                                return (NULL);
 
1972
                        }
 
1973
                        /*
 
1974
                         * Sanity check: The file type must be a regular file.
 
1975
                         */
 
1976
                        if ((flags & 0x02) != 0) {
 
1977
                                archive_set_error(&a->archive,
 
1978
                                    ARCHIVE_ERRNO_MISC,
 
1979
                                    "Invalid Rockridge CL");
 
1980
                                return (NULL);
 
1981
                        }
1822
1982
                        parent->subdirs++;
1823
1983
                        /* Overwrite an offset and a number of this "CL" entry
1824
1984
                         * to appear before other dirs. "+1" to those is to
1825
1985
                         * make sure to appear after "RE" entry which this
1826
1986
                         * "CL" entry should be connected with. */
1827
1987
                        file->offset = file->number = file->cl_offset + 1;
 
1988
 
 
1989
                        /*
 
1990
                         * Sanity check: cl_offset does not point at its
 
1991
                         * the parents or itself.
 
1992
                         */
 
1993
                        for (r = parent; r; r = r->parent) {
 
1994
                                if (r->offset == file->cl_offset) {
 
1995
                                        archive_set_error(&a->archive,
 
1996
                                            ARCHIVE_ERRNO_MISC,
 
1997
                                            "Invalid Rockridge CL");
 
1998
                                        return (NULL);
 
1999
                                }
 
2000
                        }
 
2001
                        if (file->cl_offset == file->offset ||
 
2002
                            parent->rr_moved) {
 
2003
                                archive_set_error(&a->archive,
 
2004
                                    ARCHIVE_ERRNO_MISC,
 
2005
                                    "Invalid Rockridge CL");
 
2006
                                return (NULL);
 
2007
                        }
1828
2008
                }
1829
2009
        }
1830
2010
 
1928
2108
                                 */
1929
2109
                                break;
1930
2110
                        }
 
2111
                        if (p[0] == 'P' && p[1] == 'L') {
 
2112
                                /*
 
2113
                                 * PL extension won't appear;
 
2114
                                 * contents are always ignored.
 
2115
                                 */
 
2116
                                break;
 
2117
                        }
1931
2118
                        if (p[0] == 'P' && p[1] == 'N') {
1932
2119
                                if (version == 1 && data_length == 16) {
1933
2120
                                        file->rdev = toi(data,4);
2052
2239
        offset = ((uint64_t)location) * (uint64_t)iso9660->logical_block_size;
2053
2240
        if (((file->mode & AE_IFMT) == AE_IFREG &&
2054
2241
            offset >= file->offset) ||
2055
 
            offset < iso9660->current_position) {
 
2242
            offset < iso9660->current_position ||
 
2243
            (((uint64_t)file->ce_offset) + file->ce_size)
 
2244
              > iso9660->logical_block_size ||
 
2245
            offset + file->ce_offset + file->ce_size
 
2246
                  > iso9660->volume_size) {
2056
2247
                archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
2057
 
                    "Invalid location in SUSP \"CE\" extension");
 
2248
                    "Invalid parameter in SUSP \"CE\" extension");
2058
2249
                return (ARCHIVE_FATAL);
2059
2250
        }
2060
2251
 
2068
2259
                else
2069
2260
                        new_size = heap->allocated * 2;
2070
2261
                /* Overflow might keep us from growing the list. */
2071
 
                if (new_size <= heap->allocated)
2072
 
                        __archive_errx(1, "Out of memory");
 
2262
                if (new_size <= heap->allocated) {
 
2263
                        archive_set_error(&a->archive, ENOMEM, "Out of memory");
 
2264
                        return (ARCHIVE_FATAL);
 
2265
                }
2073
2266
                p = malloc(new_size * sizeof(p[0]));
2074
 
                if (p == NULL)
2075
 
                        __archive_errx(1, "Out of memory");
 
2267
                if (p == NULL) {
 
2268
                        archive_set_error(&a->archive, ENOMEM, "Out of memory");
 
2269
                        return (ARCHIVE_FATAL);
 
2270
                }
2076
2271
                if (heap->reqs != NULL) {
2077
2272
                        memcpy(p, heap->reqs, heap->cnt * sizeof(*p));
2078
2273
                        free(heap->reqs);
2093
2288
                        heap->reqs[hole].file = file;
2094
2289
                        return (ARCHIVE_OK);
2095
2290
                }
2096
 
                // Move parent into hole <==> move hole up tree.
 
2291
                /* Move parent into hole <==> move hole up tree. */
2097
2292
                heap->reqs[hole] = heap->reqs[parent];
2098
2293
                hole = parent;
2099
2294
        }
2120
2315
        /*
2121
2316
         * Rebalance the heap.
2122
2317
         */
2123
 
        a = 0; // Starting element and its offset
 
2318
        a = 0; /* Starting element and its offset */
2124
2319
        a_offset = heap->reqs[a].offset;
2125
2320
        for (;;) {
2126
 
                b = a + a + 1; // First child
 
2321
                b = a + a + 1; /* First child */
2127
2322
                if (b >= heap->cnt)
2128
2323
                        return;
2129
2324
                b_offset = heap->reqs[b].offset;
2130
 
                c = b + 1; // Use second child if it is smaller.
 
2325
                c = b + 1; /* Use second child if it is smaller. */
2131
2326
                if (c < heap->cnt) {
2132
2327
                        c_offset = heap->reqs[c].offset;
2133
2328
                        if (c_offset < b_offset) {
2169
2364
                }
2170
2365
                do {
2171
2366
                        file = heap->reqs[0].file;
 
2367
                        if (file->ce_offset + file->ce_size > step) {
 
2368
                                archive_set_error(&a->archive,
 
2369
                                    ARCHIVE_ERRNO_FILE_FORMAT,
 
2370
                                    "Malformed CE information");
 
2371
                                return (ARCHIVE_FATAL);
 
2372
                        }
2172
2373
                        p = b + file->ce_offset;
2173
2374
                        end = p + file->ce_size;
2174
2375
                        next_CE(heap);
2209
2410
        case 0:
2210
2411
                if (data_length < 2)
2211
2412
                        return;
2212
 
                archive_strncat(&file->name, (const char *)data + 1, data_length - 1);
 
2413
                archive_strncat(&file->name,
 
2414
                    (const char *)data + 1, data_length - 1);
2213
2415
                break;
2214
2416
        case 1:
2215
2417
                if (data_length < 2)
2216
2418
                        return;
2217
 
                archive_strncat(&file->name, (const char *)data + 1, data_length - 1);
 
2419
                archive_strncat(&file->name,
 
2420
                    (const char *)data + 1, data_length - 1);
2218
2421
                file->name_continues = 1;
2219
2422
                break;
2220
2423
        case 2:
2425
2628
 
2426
2629
                archive_string_free(&file->name);
2427
2630
                archive_string_free(&file->symlink);
 
2631
                free(file->utf16be_name);
2428
2632
                con = file->contents.first;
2429
2633
                while (con != NULL) {
2430
2634
                        connext = con->next;
2452
2656
        if (file->size == 0)
2453
2657
                file->offset = iso9660->current_position;
2454
2658
 
 
2659
        /* flush any remaining bytes from the last round to ensure
 
2660
         * we're positioned */
 
2661
        if (iso9660->entry_bytes_unconsumed) {
 
2662
                __archive_read_consume(a, iso9660->entry_bytes_unconsumed);
 
2663
                iso9660->entry_bytes_unconsumed = 0;
 
2664
        }
 
2665
 
2455
2666
        /* Seek forward to the start of the entry. */
2456
2667
        if (iso9660->current_position < file->offset) {
2457
2668
                int64_t step;
2458
2669
 
2459
2670
                step = file->offset - iso9660->current_position;
2460
 
                step = __archive_read_skip(a, step);
 
2671
                step = __archive_read_consume(a, step);
2461
2672
                if (step < 0)
2462
2673
                        return ((int)step);
2463
2674
                iso9660->current_position = file->offset;
2703
2914
{
2704
2915
        struct file_info *re;
2705
2916
 
 
2917
        /*
 
2918
         * Find "RE" entry.
 
2919
         */
2706
2920
        re = file->parent;
2707
2921
        while (re != NULL && !re->re)
2708
2922
                re = re->parent;
2745
2959
        if ((file = iso9660->cache_files.first) != NULL) {
2746
2960
                iso9660->cache_files.first = file->next;
2747
2961
                if (iso9660->cache_files.first == NULL)
2748
 
                        iso9660->cache_files.last = &(iso9660->cache_files.first);
 
2962
                        iso9660->cache_files.last =
 
2963
                            &(iso9660->cache_files.first);
2749
2964
        }
2750
2965
        return (file);
2751
2966
}
2752
2967
 
2753
2968
static int
2754
 
heap_add_entry(struct archive_read *a, struct heap_queue *heap, struct file_info *file, uint64_t key)
 
2969
heap_add_entry(struct archive_read *a, struct heap_queue *heap,
 
2970
    struct file_info *file, uint64_t key)
2755
2971
{
2756
2972
        uint64_t file_key, parent_key;
2757
2973
        int hole, parent;
2797
3013
                        heap->files[hole] = file;
2798
3014
                        return (ARCHIVE_OK);
2799
3015
                }
2800
 
                // Move parent into hole <==> move hole up tree.
 
3016
                /* Move parent into hole <==> move hole up tree. */
2801
3017
                heap->files[hole] = heap->files[parent];
2802
3018
                hole = parent;
2803
3019
        }
2829
3045
        /*
2830
3046
         * Rebalance the heap.
2831
3047
         */
2832
 
        a = 0; // Starting element and its heap key
 
3048
        a = 0; /* Starting element and its heap key */
2833
3049
        a_key = heap->files[a]->key;
2834
3050
        for (;;) {
2835
 
                b = a + a + 1; // First child
 
3051
                b = a + a + 1; /* First child */
2836
3052
                if (b >= heap->used)
2837
3053
                        return (r);
2838
3054
                b_key = heap->files[b]->key;
2839
 
                c = b + 1; // Use second child if it is smaller.
 
3055
                c = b + 1; /* Use second child if it is smaller. */
2840
3056
                if (c < heap->used) {
2841
3057
                        c_key = heap->files[c]->key;
2842
3058
                        if (c_key < b_key) {
2914
3130
#if HAVE_TIMEGM
2915
3131
        /* Use platform timegm() if available. */
2916
3132
        return (timegm(t));
 
3133
#elif HAVE__MKGMTIME64
 
3134
        return (_mkgmtime64(t));
2917
3135
#else
2918
3136
        /* Else use direct calculation using POSIX assumptions. */
2919
3137
        /* First, fix up tm_yday based on the year/month/day. */
2941
3159
        return (as->s);
2942
3160
}
2943
3161
 
 
3162
static int
 
3163
build_pathname_utf16be(unsigned char *p, size_t max, size_t *len,
 
3164
    struct file_info *file)
 
3165
{
 
3166
        if (file->parent != NULL && file->parent->utf16be_bytes > 0) {
 
3167
                if (build_pathname_utf16be(p, max, len, file->parent) != 0)
 
3168
                        return (-1);
 
3169
                p[*len] = 0;
 
3170
                p[*len + 1] = '/';
 
3171
                *len += 2;
 
3172
        }
 
3173
        if (file->utf16be_bytes == 0) {
 
3174
                if (*len + 2 > max)
 
3175
                        return (-1);/* Path is too long! */
 
3176
                p[*len] = 0;
 
3177
                p[*len + 1] = '.';
 
3178
                *len += 2;
 
3179
        } else {
 
3180
                if (*len + file->utf16be_bytes > max)
 
3181
                        return (-1);/* Path is too long! */
 
3182
                memcpy(p + *len, file->utf16be_name, file->utf16be_bytes);
 
3183
                *len += file->utf16be_bytes;
 
3184
        }
 
3185
        return (0);
 
3186
}
 
3187
 
2944
3188
#if DEBUG
2945
3189
static void
2946
3190
dump_isodirrec(FILE *out, const unsigned char *isodirrec)
2953
3197
            toi(isodirrec + DR_extent_offset, DR_extent_size));
2954
3198
        fprintf(out, " s %d,",
2955
3199
            toi(isodirrec + DR_size_offset, DR_extent_size));
2956
 
        fprintf(out, " f 0x%02x,",
 
3200
        fprintf(out, " f 0x%x,",
2957
3201
            toi(isodirrec + DR_flags_offset, DR_flags_size));
2958
3202
        fprintf(out, " u %d,",
2959
3203
            toi(isodirrec + DR_file_unit_size_offset, DR_file_unit_size_size));