1 /*-
2 * Copyright (c) 2026 Kaif Khan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25 #include "test.h"
26
27 #define __LIBARCHIVE_TEST
28 #include "archive_acl_private.h"
29
30 /*
31 * archive_acl_from_text_nl() takes a pointer and a length and does not
32 * require the buffer to be NUL terminated. An entry that is only
33 * whitespace, or trailing whitespace after a valid entry, must not make
34 * the parser read past the end of the buffer.
35 *
36 * Each input is copied into a buffer sized to exactly its length so that
37 * a read past the end is out of bounds.
38 */
39 static void
parse_nl(const char * text,int type)40 parse_nl(const char *text, int type)
41 {
42 size_t len = strlen(text);
43 char *buf = malloc(len);
44 struct archive_acl acl;
45
46 assert(buf != NULL);
47 memcpy(buf, text, len);
48 memset(&acl, 0, sizeof(acl));
49 /* Must not read buf[len]. */
50 archive_acl_from_text_nl(&acl, buf, len, type, NULL);
51 archive_acl_clear(&acl);
52 free(buf);
53 }
54
DEFINE_TEST(test_acl_from_text_overread)55 DEFINE_TEST(test_acl_from_text_overread)
56 {
57 static const char *whitespace[] = {
58 " ", " ", "\t", "\n\n", "user::rwx, "
59 };
60 size_t i;
61
62 for (i = 0; i < sizeof(whitespace) / sizeof(whitespace[0]); i++) {
63 parse_nl(whitespace[i], ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
64 parse_nl(whitespace[i], ARCHIVE_ENTRY_ACL_TYPE_NFS4);
65 }
66
67 /*
68 * Trailing whitespace after a valid entry must not change the parse:
69 * the count matches the same text without the trailing spaces.
70 */
71 {
72 static const char clean[] = "user:100:rwx";
73 static const char padded[] = "user:100:rwx ";
74 struct archive_acl acl1, acl2;
75 char *b1 = malloc(sizeof(clean) - 1);
76 char *b2 = malloc(sizeof(padded) - 1);
77
78 assert(b1 != NULL);
79 assert(b2 != NULL);
80 memcpy(b1, clean, sizeof(clean) - 1);
81 memcpy(b2, padded, sizeof(padded) - 1);
82 memset(&acl1, 0, sizeof(acl1));
83 memset(&acl2, 0, sizeof(acl2));
84 archive_acl_from_text_nl(&acl1, b1, sizeof(clean) - 1,
85 ARCHIVE_ENTRY_ACL_TYPE_ACCESS, NULL);
86 archive_acl_from_text_nl(&acl2, b2, sizeof(padded) - 1,
87 ARCHIVE_ENTRY_ACL_TYPE_ACCESS, NULL);
88 assertEqualInt(
89 archive_acl_count(&acl1, ARCHIVE_ENTRY_ACL_TYPE_ACCESS),
90 archive_acl_count(&acl2, ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
91 assert(archive_acl_count(&acl2,
92 ARCHIVE_ENTRY_ACL_TYPE_ACCESS) > 0);
93 archive_acl_clear(&acl1);
94 archive_acl_clear(&acl2);
95 free(b1);
96 free(b2);
97 }
98 }
99