]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Fix ACL parsing bug that would erroneously set the mode bits for
authorTim Kientzle <kientzle@gmail.com>
Fri, 13 Nov 2009 07:04:35 +0000 (02:04 -0500)
committerTim Kientzle <kientzle@gmail.com>
Fri, 13 Nov 2009 07:04:35 +0000 (02:04 -0500)
the last ACL entry to 0.  Also, fix the test that was verifying
the wrong results.

Thanks to Michihiro Nakajima and Clang static analyzer for
finding this.

SVN-Revision: 1651

libarchive/archive_entry.c
libarchive/test/test_compat_solaris_tar_acl.c

index bd2c4469e0302476cda19b8435935bee5eb79807..03dda1af52076fe2993fb69343b9d635d6dc54d1 100644 (file)
@@ -1615,7 +1615,7 @@ __archive_entry_acl_parse_w(struct archive_entry *entry,
                const wchar_t *end;
        } field[4], name;
 
-       int fields;
+       int fields, n;
        int type, tag, permset, id;
        wchar_t sep;
 
@@ -1635,6 +1635,10 @@ __archive_entry_acl_parse_w(struct archive_entry *entry,
                        ++fields;
                } while (sep == L':');
 
+               /* Set remaining fields to blank. */
+               for (n = fields; n < 4; ++n)
+                       field[n].start = field[n].end = NULL;
+
                /* Check for a numeric ID in field 1 or 3. */
                id = -1;
                isint_w(field[1].start, field[1].end, &id);
@@ -1646,7 +1650,7 @@ __archive_entry_acl_parse_w(struct archive_entry *entry,
                 * Solaris extension:  "defaultuser::rwx" is the
                 * default ACL corresponding to "user::rwx", etc.
                 */
-               if (field[0].end-field[0].start > 7
+               if (field[0].end - field[0].start > 7
                    && wmemcmp(field[0].start, L"default", 7) == 0) {
                        type = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT;
                        field[0].start += 7;
@@ -1673,7 +1677,7 @@ __archive_entry_acl_parse_w(struct archive_entry *entry,
                } else if (prefix_w(field[0].start, field[0].end, L"other")) {
                        if (fields == 2
                            && field[1].start < field[1].end
-                           && ismode_w(field[1].start, field[2].end, &permset)) {
+                           && ismode_w(field[1].start, field[1].end, &permset)) {
                                /* This is Solaris-style "other:rwx" */
                        } else if (fields == 3
                            && field[1].start == field[1].end
@@ -1742,6 +1746,8 @@ ismode_w(const wchar_t *start, const wchar_t *end, int *permset)
 {
        const wchar_t *p;
 
+       if (start >= end)
+               return (0);
        p = start;
        *permset = 0;
        while (p < end) {
index ec3955ecd7fe6d1b43c8c53da4cd594c042046bf..af4f9d3825dfd639a52861dde33306e0dd2de7a1 100644 (file)
@@ -50,9 +50,9 @@ DEFINE_TEST(test_compat_solaris_tar_acl)
 
        /* Archive has 1 entry with some ACLs set on it. */
        assertA(0 == archive_read_next_header(a, &ae));
-       failure("Basic ACLs should set mode to 0640, not %04o",
+       failure("Basic ACLs should set mode to 0644, not %04o",
            archive_entry_mode(ae)&0777);
-       assertEqualInt((archive_entry_mode(ae) & 0777), 0640);
+       assertEqualInt((archive_entry_mode(ae) & 0777), 0644);
        assertEqualInt(7, archive_entry_acl_reset(ae,
                ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
        assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
@@ -77,7 +77,7 @@ DEFINE_TEST(test_compat_solaris_tar_acl)
                ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
                &type, &permset, &tag, &qual, &name));
        assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
-       assertEqualInt(000, permset);
+       assertEqualInt(004, permset);
        assertEqualInt(ARCHIVE_ENTRY_ACL_OTHER, tag);
        assertEqualInt(-1, qual);
        assert(name == NULL);