plist.c
1 /*- 2 * Copyright (c) 2013-2020 Baptiste Daroussin <bapt@FreeBSD.org> 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 * in this position and unchanged. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 *~ 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #include <atf-c.h> 28 #include <pkg.h> 29 #include <private/pkg.h> 30 31 ATF_TC_WITHOUT_HEAD(parse_mode); 32 ATF_TC_WITHOUT_HEAD(expand_plist_variables); 33 34 ATF_TC_BODY(parse_mode, tc) 35 { 36 void *set; 37 38 set = parse_mode("u+x"); 39 ATF_REQUIRE(set == NULL); 40 41 set = parse_mode("plop"); 42 ATF_REQUIRE(set == NULL); 43 44 set = parse_mode("0755"); 45 ATF_REQUIRE(set != NULL); 46 47 free(set); 48 49 set = parse_mode("u=r,g=rX"); 50 ATF_REQUIRE(set != NULL); 51 52 free(set); 53 } 54 55 ATF_TC(parse_keyword_attributes); 56 57 ATF_TC_HEAD(parse_keyword_attributes, tc) 58 { 59 atf_tc_set_md_var(tc, "descr", 60 "parse_keyword_attributes()"); 61 } 62 63 ATF_TC_BODY(parse_keyword_attributes, tc) 64 { 65 char buf[BUFSIZ]; 66 struct file_attr *a; 67 68 strlcpy(buf, "()", BUFSIZ); 69 ATF_REQUIRE(parse_keyword_args(buf, "plop") == NULL); 70 71 strlcpy(buf, "(root, wheel)", BUFSIZ); 72 ATF_REQUIRE((a = parse_keyword_args(buf, "plop")) != NULL); 73 ATF_REQUIRE_STREQ(a->owner, "root"); 74 ATF_REQUIRE_STREQ(a->group, "wheel"); 75 free_file_attr(a); 76 77 strlcpy(buf, "(root, wheel, 0755)", BUFSIZ); 78 ATF_REQUIRE((a = parse_keyword_args(buf, "plop")) != NULL); 79 ATF_REQUIRE_STREQ(a->owner, "root"); 80 ATF_REQUIRE_STREQ(a->group, "wheel"); 81 free_file_attr(a); 82 83 strlcpy(buf, "(root, wheel, 0755,)", BUFSIZ); 84 ATF_REQUIRE((a = parse_keyword_args(buf, "plop")) != NULL); 85 ATF_REQUIRE_STREQ(a->owner, "root"); 86 ATF_REQUIRE_STREQ(a->group, "wheel"); 87 free_file_attr(a); 88 } 89 90 ATF_TC(parse_keyword); 91 92 ATF_TC_HEAD(parse_keyword, tc) 93 { 94 atf_tc_set_md_var(tc, "descr", 95 "parse_keyword()"); 96 } 97 98 ATF_TC_BODY(parse_keyword, tc) 99 { 100 char *keyword; 101 struct file_attr *attr; 102 char buf[BUFSIZ]; 103 104 strlcpy(buf, "something", BUFSIZ); 105 keyword = NULL; 106 attr = NULL; 107 ATF_REQUIRE_STREQ(extract_keywords(buf, &keyword, &attr), ""); 108 ATF_REQUIRE_STREQ(keyword, "something"); 109 ATF_REQUIRE_EQ(attr, NULL); 110 111 /* empty keyword */ 112 strlcpy(buf, "", BUFSIZ); 113 keyword = NULL; 114 attr = NULL; 115 ATF_REQUIRE_STREQ(extract_keywords(buf, &keyword, &attr), ""); 116 ATF_REQUIRE_STREQ(keyword, ""); 117 ATF_REQUIRE_EQ(attr, NULL); 118 119 /* bad keyword */ 120 strlcpy(buf, "(", BUFSIZ); 121 keyword = NULL; 122 attr = NULL; 123 ATF_REQUIRE_EQ(extract_keywords(buf, &keyword, &attr), NULL); 124 ATF_REQUIRE_EQ(keyword, NULL); 125 ATF_REQUIRE_EQ(attr, NULL); 126 127 /* bad: empty keyword */ 128 strlcpy(buf, "()", BUFSIZ); 129 keyword = NULL; 130 attr = NULL; 131 ATF_REQUIRE_EQ(extract_keywords(buf, &keyword, &attr), NULL); 132 ATF_REQUIRE_EQ(keyword, NULL); 133 ATF_REQUIRE_EQ(attr, NULL); 134 135 /* ok only user keyword */ 136 strlcpy(buf, "(root) that", BUFSIZ); 137 keyword = NULL; 138 attr = NULL; 139 ATF_REQUIRE_STREQ(extract_keywords(buf, &keyword, &attr), "that"); 140 ATF_REQUIRE_STREQ(keyword, ""); 141 ATF_REQUIRE(attr != NULL); 142 ATF_REQUIRE_STREQ(attr->owner, "root"); 143 144 /* ok only group keyword */ 145 strlcpy(buf, "(,wheel) that", BUFSIZ); 146 keyword = NULL; 147 attr = NULL; 148 ATF_REQUIRE_STREQ(extract_keywords(buf, &keyword, &attr), "that"); 149 ATF_REQUIRE_STREQ(keyword, ""); 150 ATF_REQUIRE(attr != NULL); 151 ATF_REQUIRE_STREQ(attr->group, "wheel"); 152 153 /* ok only group with space keyword */ 154 strlcpy(buf, "( , wheel ,) that", BUFSIZ); 155 keyword = NULL; 156 attr = NULL; 157 ATF_REQUIRE_STREQ(extract_keywords(buf, &keyword, &attr), "that"); 158 ATF_REQUIRE_STREQ(keyword, ""); 159 ATF_REQUIRE(attr != NULL); 160 ATF_REQUIRE_STREQ(attr->group, "wheel"); 161 ATF_REQUIRE_EQ(attr->owner, NULL); 162 163 strlcpy(buf, "(, wheel ,perm,ffags,)", BUFSIZ); 164 ATF_REQUIRE_EQ(parse_keyword_args(buf, "plop"), NULL); 165 } 166 167 ATF_TC(parse_plist); 168 169 ATF_TC_HEAD(parse_plist, tc) 170 { 171 atf_tc_set_md_var(tc, "descr", 172 "parse_plist()"); 173 } 174 175 ATF_TC_BODY(parse_plist, tc) 176 { 177 struct pkg *p; 178 struct plist *plist; 179 char buf[BUFSIZ]; 180 181 ATF_REQUIRE_EQ(EPKG_OK, pkg_new(&p, PKG_INSTALLED)); 182 183 /* On a non existing directory this should not work */ 184 plist = plist_new(p, "/nonexist"); 185 ATF_REQUIRE(plist == NULL); 186 187 plist = plist_new(p, NULL); 188 ATF_REQUIRE(plist != NULL); 189 plist_free(plist); 190 191 plist = plist_new(p, "/tmp"); 192 ATF_REQUIRE(plist != NULL); 193 194 ATF_REQUIRE(plist->pkg == p); 195 ATF_REQUIRE_EQ(plist->prefix[0], '\0'); 196 197 strlcpy(buf, "@name name1", BUFSIZ); 198 ATF_REQUIRE_EQ(EPKG_FATAL, plist_parse_line(plist, buf)); 199 200 strlcpy(buf, "@name name1-1", BUFSIZ); 201 ATF_REQUIRE_EQ(EPKG_OK, plist_parse_line(plist, buf)); 202 ATF_REQUIRE_STREQ(p->name, "name1"); 203 ATF_REQUIRE_STREQ(p->version, "1"); 204 205 /* if already set, name should not change */ 206 strlcpy(buf, "@name name2-2", BUFSIZ); 207 ATF_REQUIRE_EQ(EPKG_OK, plist_parse_line(plist, buf)); 208 ATF_REQUIRE_STREQ(p->name, "name1"); 209 ATF_REQUIRE_STREQ(p->version, "1"); 210 211 strlcpy(buf, "@cwd /myprefix", BUFSIZ); 212 ATF_REQUIRE_EQ(EPKG_OK, plist_parse_line(plist, buf)); 213 ATF_REQUIRE_STREQ(p->prefix, "/myprefix"); 214 215 ATF_REQUIRE_STREQ(plist->prefix, "/myprefix"); 216 217 ATF_REQUIRE_STREQ(plist->uname, "root"); 218 ATF_REQUIRE_STREQ(plist->gname, "wheel"); 219 220 strlcpy(buf, "@owner bob", BUFSIZ); 221 ATF_REQUIRE_EQ(EPKG_OK, plist_parse_line(plist, buf)); 222 ATF_REQUIRE_STREQ(plist->uname, "bob"); 223 224 strlcpy(buf, "@group sponge", BUFSIZ); 225 ATF_REQUIRE_EQ(EPKG_OK, plist_parse_line(plist, buf)); 226 ATF_REQUIRE_STREQ(plist->gname, "sponge"); 227 228 strlcpy(buf, "@group", BUFSIZ); 229 ATF_REQUIRE_EQ(EPKG_OK, plist_parse_line(plist, buf)); 230 ATF_REQUIRE_STREQ(plist->gname, "wheel"); 231 232 strlcpy(buf, "@owner", BUFSIZ); 233 ATF_REQUIRE_EQ(EPKG_OK, plist_parse_line(plist, buf)); 234 ATF_REQUIRE_STREQ(plist->uname, "root"); 235 236 strlcpy(buf, "@cwd plop", BUFSIZ); 237 ATF_REQUIRE_EQ(EPKG_OK, plist_parse_line(plist, buf)); 238 ATF_REQUIRE_STREQ(plist->prefix, "plop"); 239 240 strlcpy(buf, "@cwd", BUFSIZ); 241 ATF_REQUIRE_EQ(EPKG_OK, plist_parse_line(plist, buf)); 242 ATF_REQUIRE_STREQ(plist->prefix, "/myprefix"); 243 ATF_REQUIRE_STREQ(plist->slash, "/"); 244 245 strlcpy(buf, "@cwd /another/prefix/", BUFSIZ); 246 ATF_REQUIRE_EQ(EPKG_OK, plist_parse_line(plist, buf)); 247 ATF_REQUIRE_STREQ(plist->prefix, "/another/prefix/"); 248 ATF_REQUIRE_STREQ(plist->slash, ""); 249 250 ATF_REQUIRE_EQ(0, plist->perm); 251 strlcpy(buf, "@mode 0755", BUFSIZ); 252 ATF_REQUIRE_EQ(EPKG_OK, plist_parse_line(plist, buf)); 253 ATF_REQUIRE_EQ(0755, plist->perm); 254 255 strlcpy(buf, "@mode", BUFSIZ); 256 ATF_REQUIRE_EQ(EPKG_OK, plist_parse_line(plist, buf)); 257 ATF_REQUIRE_EQ(0, plist->perm); 258 259 strlcpy(buf, "@blabla", BUFSIZ); 260 ATF_REQUIRE_EQ(EPKG_FATAL, plist_parse_line(plist, buf)); 261 262 strlcpy(buf, "nonexisting/file", BUFSIZ); 263 ATF_REQUIRE_EQ(EPKG_FATAL, plist_parse_line(plist, buf)); 264 265 strlcpy(buf, "@dir nonexisting", BUFSIZ); 266 ATF_REQUIRE_EQ(EPKG_FATAL, plist_parse_line(plist, buf)); 267 268 strlcpy(buf, "@dirrm nonexisting", BUFSIZ); 269 ATF_REQUIRE_EQ(EPKG_FATAL, plist_parse_line(plist, buf)); 270 271 pkg_free(p); 272 plist_free(plist); 273 } 274 275 ATF_TC_BODY(expand_plist_variables, tc) 276 { 277 char *plop; 278 kvlist_t kv = vec_init(); 279 280 plop = expand_plist_variables("%%this%% is a line", &kv); 281 ATF_REQUIRE_STREQ(plop, "%%this%% is a line"); 282 free(plop); 283 284 struct pkg_kv *keyval = pkg_kv_new("this", "@comment "); 285 vec_push(&kv, keyval); 286 287 plop = expand_plist_variables("%%this%% is a line", &kv); 288 ATF_REQUIRE_STREQ(plop, "@comment is a line"); 289 free(plop); 290 291 plop = expand_plist_variables("%%thos%% is a line", &kv); 292 ATF_REQUIRE_STREQ(plop, "%%thos%% is a line"); 293 free(plop); 294 295 plop = expand_plist_variables("%F is a line", &kv); 296 ATF_REQUIRE_STREQ(plop, "%F is a line"); 297 free(plop); 298 299 struct pkg_kv *kv2 = pkg_kv_new("new", "var"); 300 vec_push(&kv, kv2); 301 302 plop = expand_plist_variables("%%this%% %F is a %%new%% line", &kv); 303 ATF_REQUIRE_STREQ(plop, "@comment %F is a var line"); 304 free(plop); 305 306 plop = expand_plist_variables("%%this%% %F is %% a %%new%% line", &kv); 307 ATF_REQUIRE_STREQ(plop, "@comment %F is %% a var line"); 308 free(plop); 309 310 plop = expand_plist_variables("%%this%% %F is %%kof a %%new%% line", &kv); 311 ATF_REQUIRE_STREQ(plop, "@comment %F is %%kof a var line"); 312 free(plop); 313 314 plop = expand_plist_variables("%%this%% %F is %%kof a %%new%% line %f", &kv); 315 ATF_REQUIRE_STREQ(plop, "@comment %F is %%kof a var line %f"); 316 free(plop); 317 318 plop = expand_plist_variables("%%this%% %F is %%kof a %%new%% line %", &kv); 319 ATF_REQUIRE_STREQ(plop, "@comment %F is %%kof a var line %"); 320 free(plop); 321 322 vec_free_and_free(&kv, pkg_kv_free); 323 } 324 325 ATF_TP_ADD_TCS(tp) 326 { 327 ATF_TP_ADD_TC(tp, parse_mode); 328 ATF_TP_ADD_TC(tp, parse_plist); 329 ATF_TP_ADD_TC(tp, parse_keyword_attributes); 330 ATF_TP_ADD_TC(tp, parse_keyword); 331 ATF_TP_ADD_TC(tp, expand_plist_variables); 332 333 return (atf_no_error()); 334 }