/ tests / lib / plist.c
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  }