Branch data Line data Source code
1 : : /*
2 : : * libdpkg - Debian packaging suite library routines
3 : : * fields.c - parsing of all the different fields, when reading in
4 : : *
5 : : * Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
6 : : * Copyright © 2001 Wichert Akkerman
7 : : * Copyright © 2006-2015 Guillem Jover <guillem@debian.org>
8 : : * Copyright © 2009 Canonical Ltd.
9 : : * Copyright © 2011 Linaro Limited
10 : : * Copyright © 2011 Raphaël Hertzog <hertzog@debian.org>
11 : : *
12 : : * This is free software; you can redistribute it and/or modify
13 : : * it under the terms of the GNU General Public License as published by
14 : : * the Free Software Foundation; either version 2 of the License, or
15 : : * (at your option) any later version.
16 : : *
17 : : * This is distributed in the hope that it will be useful,
18 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 : : * GNU General Public License for more details.
21 : : *
22 : : * You should have received a copy of the GNU General Public License
23 : : * along with this program. If not, see <https://www.gnu.org/licenses/>.
24 : : */
25 : :
26 : : #include <config.h>
27 : : #include <compat.h>
28 : :
29 : : #include <string.h>
30 : : #include <stdio.h>
31 : :
32 : : #include <dpkg/i18n.h>
33 : : #include <dpkg/c-ctype.h>
34 : : #include <dpkg/dpkg.h>
35 : : #include <dpkg/dpkg-db.h>
36 : : #include <dpkg/arch.h>
37 : : #include <dpkg/string.h>
38 : : #include <dpkg/path.h>
39 : : #include <dpkg/parsedump.h>
40 : : #include <dpkg/pkg-spec.h>
41 : : #include <dpkg/triglib.h>
42 : :
43 : : /**
44 : : * Flags to parse a name associated to a value.
45 : : */
46 : : enum parse_nv_mode {
47 : : /** Expect no more words (default). */
48 : : PARSE_NV_LAST = 0,
49 : : /** Expect another word after the parsed name. */
50 : : PARSE_NV_NEXT = 1,
51 : : /** Do not fail if there is no name with an associated value found. */
52 : : PARSE_NV_FALLBACK = 2,
53 : : };
54 : :
55 : : /**
56 : : * Parses a name and returns its associated value.
57 : : *
58 : : * Gets a pointer to the string to parse in @a strp, and modifies the pointer
59 : : * to the string to point to the end of the parsed text. If no value is found
60 : : * for the name and @a flags is set to #PARSE_NV_FALLBACK then @a strp is set
61 : : * to NULL and returns -1, otherwise a parse error is emitted.
62 : : */
63 : : static int
64 : 34 : parse_nv(struct parsedb_state *ps, enum parse_nv_mode parse_mode,
65 : : const char **strp, const struct namevalue *nv_head)
66 : : {
67 : 34 : const char *str_start = *strp, *str_end;
68 : : const struct namevalue *nv;
69 : : int value;
70 : :
71 : 34 : dpkg_error_destroy(&ps->err);
72 : :
73 [ - + ]: 34 : if (str_start[0] == '\0')
74 : 0 : return dpkg_put_error(&ps->err, _("is missing a value"));
75 : :
76 : 34 : nv = namevalue_find_by_name(nv_head, str_start);
77 [ - + ]: 34 : if (nv == NULL) {
78 : : /* We got no match, skip further string validation. */
79 [ # # ]: 0 : if (parse_mode != PARSE_NV_FALLBACK)
80 : 0 : return dpkg_put_error(&ps->err, _("has invalid value '%.50s'"), str_start);
81 : :
82 : 0 : str_end = NULL;
83 : 0 : value = -1;
84 : : } else {
85 : 34 : str_end = str_start + nv->length;
86 [ + + ]: 36 : while (c_isspace(str_end[0]))
87 : 2 : str_end++;
88 : 34 : value = nv->value;
89 : :
90 [ + + - + ]: 34 : if (parse_mode != PARSE_NV_NEXT && str_is_set(str_end))
91 : 0 : return dpkg_put_error(&ps->err, _("has trailing junk"));
92 : : }
93 : :
94 : 34 : *strp = str_end;
95 : :
96 : 34 : return value;
97 : : }
98 : :
99 : : void
100 : 32 : f_name(struct pkginfo *pkg, struct pkgbin *pkgbin,
101 : : struct parsedb_state *ps,
102 : : const char *value, const struct fieldinfo *fip)
103 : : {
104 : : const char *e;
105 : :
106 : 32 : e = pkg_name_is_illegal(value);
107 [ - + ]: 32 : if (e != NULL)
108 : 0 : parse_error(ps, _("invalid package name in '%s' field: %s"), fip->name, e);
109 : : /* We use the new name, as pkg_hash_find_set() may have done a tolower for us. */
110 : 32 : pkg->set->name = pkg_hash_find_set(value)->name;
111 : 32 : }
112 : :
113 : : void
114 : 0 : f_archives(struct pkginfo *pkg, struct pkgbin *pkgbin,
115 : : struct parsedb_state *ps,
116 : : const char *value, const struct fieldinfo *fip)
117 : : {
118 : : struct archivedetails *fdp, **fdpp;
119 : : char *cpos, *space;
120 : : int allowextend;
121 : :
122 [ # # ]: 0 : if (!*value)
123 : 0 : parse_error(ps, _("empty archive details '%s' field"), fip->name);
124 [ # # ]: 0 : if (!(ps->flags & pdb_recordavailable))
125 : 0 : parse_error(ps,
126 : 0 : _("archive details '%s' field not allowed in status file"),
127 : 0 : fip->name);
128 : 0 : allowextend = !pkg->archives;
129 : 0 : fdpp = &pkg->archives;
130 : 0 : cpos= nfstrsave(value);
131 [ # # ]: 0 : while (*cpos) {
132 : 0 : space = cpos;
133 [ # # # # ]: 0 : while (*space && !c_isspace(*space))
134 : 0 : space++;
135 [ # # ]: 0 : if (*space)
136 : 0 : *space++ = '\0';
137 : 0 : fdp= *fdpp;
138 [ # # ]: 0 : if (!fdp) {
139 [ # # ]: 0 : if (!allowextend)
140 : 0 : parse_error(ps,
141 : 0 : _("too many values in archive details '%s' field "
142 : 0 : "(compared to others)"), fip->name);
143 : 0 : fdp = nfmalloc(sizeof(*fdp));
144 : 0 : fdp->next= NULL;
145 : 0 : fdp->name= fdp->msdosname= fdp->size= fdp->md5sum= NULL;
146 : 0 : *fdpp= fdp;
147 : : }
148 : 0 : STRUCTFIELD(fdp, fip->integer, const char *) = cpos;
149 : 0 : fdpp= &fdp->next;
150 [ # # # # ]: 0 : while (*space && c_isspace(*space))
151 : 0 : space++;
152 : 0 : cpos= space;
153 : : }
154 [ # # ]: 0 : if (*fdpp)
155 : 0 : parse_error(ps,
156 : 0 : _("too few values in archive details '%s' field "
157 : 0 : "(compared to others)"), fip->name);
158 : 0 : }
159 : :
160 : : void
161 : 64 : f_charfield(struct pkginfo *pkg, struct pkgbin *pkgbin,
162 : : struct parsedb_state *ps,
163 : : const char *value, const struct fieldinfo *fip)
164 : : {
165 [ + - ]: 64 : if (*value)
166 : 64 : STRUCTFIELD(pkgbin, fip->integer, char *) = nfstrsave(value);
167 : 64 : }
168 : :
169 : : void
170 : 0 : f_boolean(struct pkginfo *pkg, struct pkgbin *pkgbin,
171 : : struct parsedb_state *ps,
172 : : const char *value, const struct fieldinfo *fip)
173 : : {
174 : : bool boolean;
175 : :
176 [ # # ]: 0 : if (!*value)
177 : 0 : return;
178 : :
179 : 0 : boolean = parse_nv(ps, PARSE_NV_LAST, &value, booleaninfos);
180 [ # # ]: 0 : if (dpkg_has_error(&ps->err))
181 : 0 : parse_error(ps, _("boolean (yes/no) '%s' field: %s"),
182 : 0 : fip->name, ps->err.str);
183 : :
184 : 0 : STRUCTFIELD(pkgbin, fip->integer, bool) = boolean;
185 : : }
186 : :
187 : : void
188 : 0 : f_multiarch(struct pkginfo *pkg, struct pkgbin *pkgbin,
189 : : struct parsedb_state *ps,
190 : : const char *value, const struct fieldinfo *fip)
191 : : {
192 : : int multiarch;
193 : :
194 [ # # ]: 0 : if (!*value)
195 : 0 : return;
196 : :
197 : 0 : multiarch = parse_nv(ps, PARSE_NV_LAST, &value, multiarchinfos);
198 [ # # ]: 0 : if (dpkg_has_error(&ps->err))
199 : 0 : parse_error(ps, _("quadstate (foreign/allowed/same/no) '%s' field: %s"),
200 : 0 : fip->name, ps->err.str);
201 : 0 : STRUCTFIELD(pkgbin, fip->integer, int) = multiarch;
202 : : }
203 : :
204 : : void
205 : 32 : f_architecture(struct pkginfo *pkg, struct pkgbin *pkgbin,
206 : : struct parsedb_state *ps,
207 : : const char *value, const struct fieldinfo *fip)
208 : : {
209 : 32 : pkgbin->arch = dpkg_arch_find(value);
210 [ - + ]: 32 : if (pkgbin->arch->type == DPKG_ARCH_ILLEGAL)
211 : 0 : parse_warn(ps, _("'%s' is not a valid architecture name in '%s' field: %s"),
212 : 0 : value, fip->name, dpkg_arch_name_is_illegal(value));
213 : 32 : }
214 : :
215 : : void
216 : 31 : f_section(struct pkginfo *pkg, struct pkgbin *pkgbin,
217 : : struct parsedb_state *ps,
218 : : const char *value, const struct fieldinfo *fip)
219 : : {
220 [ - + ]: 31 : if (!*value) return;
221 : 31 : pkg->section = nfstrsave(value);
222 : : }
223 : :
224 : : void
225 : 31 : f_priority(struct pkginfo *pkg, struct pkgbin *pkgbin,
226 : : struct parsedb_state *ps,
227 : : const char *value, const struct fieldinfo *fip)
228 : : {
229 : 31 : const char *str = value;
230 : : int priority;
231 : :
232 [ - + ]: 31 : if (!*value) return;
233 : :
234 : 31 : priority = parse_nv(ps, PARSE_NV_FALLBACK, &str, priorityinfos);
235 [ - + ]: 31 : if (dpkg_has_error(&ps->err))
236 : 0 : parse_error(ps, _("word in '%s' field: %s"), fip->name, ps->err.str);
237 : :
238 [ - + ]: 31 : if (str == NULL) {
239 : 0 : pkg->priority = PKG_PRIO_OTHER;
240 : 0 : pkg->otherpriority = nfstrsave(value);
241 : : } else {
242 : 31 : pkg->priority = priority;
243 : : }
244 : : }
245 : :
246 : : void
247 : 2 : f_obs_class(struct pkginfo *pkg, struct pkgbin *pkgbin,
248 : : struct parsedb_state *ps,
249 : : const char *value, const struct fieldinfo *fip)
250 : : {
251 : 2 : parse_warn(ps, _("obsolete '%s' field used"), fip->name);
252 : 2 : f_priority(pkg, pkgbin, ps, value, fip);
253 : 2 : }
254 : :
255 : : void
256 : 1 : f_status(struct pkginfo *pkg, struct pkgbin *pkgbin,
257 : : struct parsedb_state *ps,
258 : : const char *value, const struct fieldinfo *fip)
259 : : {
260 [ - + ]: 1 : if (ps->flags & pdb_rejectstatus)
261 : 0 : parse_error(ps,
262 : 0 : _("value for '%s' field not allowed in this context"),
263 : 0 : fip->name);
264 [ - + ]: 1 : if (ps->flags & pdb_recordavailable)
265 : 0 : return;
266 : :
267 : 1 : pkg->want = parse_nv(ps, PARSE_NV_NEXT, &value, wantinfos);
268 [ - + ]: 1 : if (dpkg_has_error(&ps->err))
269 : 0 : parse_error(ps, _("first (want) word in '%s' field: %s"),
270 : 0 : fip->name, ps->err.str);
271 : 1 : pkg->eflag = parse_nv(ps, PARSE_NV_NEXT, &value, eflaginfos);
272 [ - + ]: 1 : if (dpkg_has_error(&ps->err))
273 : 0 : parse_error(ps, _("second (error) word in '%s' field: %s"),
274 : 0 : fip->name, ps->err.str);
275 : 1 : pkg->status = parse_nv(ps, PARSE_NV_LAST, &value, statusinfos);
276 [ - + ]: 1 : if (dpkg_has_error(&ps->err))
277 : 0 : parse_error(ps, _("third (status) word in '%s' field: %s"),
278 : 0 : fip->name, ps->err.str);
279 : : }
280 : :
281 : : void
282 : 32 : f_version(struct pkginfo *pkg, struct pkgbin *pkgbin,
283 : : struct parsedb_state *ps,
284 : : const char *value, const struct fieldinfo *fip)
285 : : {
286 [ - + ]: 32 : if (parse_db_version(ps, &pkgbin->version, value) < 0)
287 : 0 : parse_problem(ps, _("'%s' field value '%.250s'"), fip->name, value);
288 : 32 : }
289 : :
290 : : void
291 : 2 : f_obs_revision(struct pkginfo *pkg, struct pkgbin *pkgbin,
292 : : struct parsedb_state *ps,
293 : : const char *value, const struct fieldinfo *fip)
294 : : {
295 : : char *newversion;
296 : :
297 : 2 : parse_warn(ps, _("obsolete '%s' field used"), fip->name);
298 [ - + ]: 2 : if (!*value) return;
299 [ - + ]: 2 : if (str_is_set(pkgbin->version.revision)) {
300 : 0 : newversion = nfmalloc(strlen(pkgbin->version.version) +
301 : 0 : strlen(pkgbin->version.revision) + 2);
302 : 0 : sprintf(newversion, "%s-%s", pkgbin->version.version,
303 : : pkgbin->version.revision);
304 : 0 : pkgbin->version.version = newversion;
305 : : }
306 : 2 : pkgbin->version.revision = nfstrsave(value);
307 : : }
308 : :
309 : : void
310 : 0 : f_configversion(struct pkginfo *pkg, struct pkgbin *pkgbin,
311 : : struct parsedb_state *ps,
312 : : const char *value, const struct fieldinfo *fip)
313 : : {
314 [ # # ]: 0 : if (ps->flags & pdb_rejectstatus)
315 : 0 : parse_error(ps,
316 : 0 : _("value for '%s' field not allowed in this context"),
317 : 0 : fip->name);
318 [ # # ]: 0 : if (ps->flags & pdb_recordavailable)
319 : 0 : return;
320 : :
321 [ # # ]: 0 : if (parse_db_version(ps, &pkg->configversion, value) < 0)
322 : 0 : parse_problem(ps, _("'%s' field value '%.250s'"), fip->name, value);
323 : : }
324 : :
325 : : /*
326 : : * The code in f_conffiles ensures that value[-1] == ' ', which is helpful.
327 : : */
328 : 0 : static void conffvalue_lastword(const char *value, const char *from,
329 : : const char *endent,
330 : : const char **word_start_r, int *word_len_r,
331 : : const char **new_from_r,
332 : : struct parsedb_state *ps)
333 : : {
334 : : const char *lastspc;
335 : :
336 [ # # ]: 0 : if (from <= value+1) goto malformed;
337 [ # # ]: 0 : for (lastspc= from-1; *lastspc != ' '; lastspc--);
338 [ # # # # ]: 0 : if (lastspc <= value+1 || lastspc >= endent-1) goto malformed;
339 : :
340 : 0 : *new_from_r= lastspc;
341 : 0 : *word_start_r= lastspc + 1;
342 : 0 : *word_len_r= (int)(from - *word_start_r);
343 : 0 : return;
344 : :
345 : 0 : malformed:
346 : 0 : parse_error(ps,
347 : 0 : _("value for '%s' field has malformed line '%.*s'"),
348 [ # # ]: 0 : "Conffiles", (int)min(endent - value, 250), value);
349 : : }
350 : :
351 : : void
352 : 0 : f_conffiles(struct pkginfo *pkg, struct pkgbin *pkgbin,
353 : : struct parsedb_state *ps,
354 : : const char *value, const struct fieldinfo *fip)
355 : : {
356 : : static const char obsolete_str[]= "obsolete";
357 : : static const char remove_on_upgrade_str[] = "remove-on-upgrade";
358 : : struct conffile **lastp;
359 : :
360 : 0 : lastp = &pkgbin->conffiles;
361 [ # # ]: 0 : while (*value) {
362 : : struct conffile *newlink;
363 : : const char *endent, *endfn, *hashstart;
364 : : char *newptr;
365 : : int c, namelen, hashlen;
366 : 0 : int flags = CONFFILE_NONE;
367 : :
368 : 0 : c= *value++;
369 [ # # ]: 0 : if (c == '\n') continue;
370 [ # # ]: 0 : if (c != ' ')
371 : 0 : parse_error(ps,
372 : 0 : _("value for '%s' field has line starting with non-space '%c'"),
373 : 0 : fip->name, c);
374 [ # # # # ]: 0 : for (endent = value; (c = *endent) != '\0' && c != '\n'; endent++) ;
375 : 0 : conffvalue_lastword(value, endent, endent,
376 : : &hashstart, &hashlen, &endfn,
377 : : ps);
378 [ # # ]: 0 : if (hashlen == sizeof(remove_on_upgrade_str) - 1 &&
379 [ # # ]: 0 : memcmp(hashstart, remove_on_upgrade_str, hashlen) == 0) {
380 : 0 : flags |= CONFFILE_REMOVE_ON_UPGRADE;
381 : 0 : conffvalue_lastword(value, endfn, endent, &hashstart, &hashlen, &endfn,
382 : : ps);
383 : : }
384 : :
385 [ # # ]: 0 : if (hashlen == sizeof(obsolete_str) - 1 &&
386 [ # # ]: 0 : memcmp(hashstart, obsolete_str, hashlen) == 0) {
387 : 0 : flags |= CONFFILE_OBSOLETE;
388 : 0 : conffvalue_lastword(value, endfn, endent,
389 : : &hashstart, &hashlen, &endfn,
390 : : ps);
391 : : }
392 : :
393 : 0 : newlink = nfmalloc(sizeof(*newlink));
394 : 0 : value = path_skip_slash_dotslash(value);
395 : 0 : namelen= (int)(endfn-value);
396 [ # # ]: 0 : if (namelen <= 0)
397 : 0 : parse_error(ps,
398 : 0 : _("root or empty directory listed as a conffile in '%s' field"),
399 : 0 : fip->name);
400 : 0 : newptr = nfmalloc(namelen+2);
401 : 0 : newptr[0]= '/';
402 : 0 : memcpy(newptr+1,value,namelen);
403 : 0 : newptr[namelen+1] = '\0';
404 : 0 : newlink->name= newptr;
405 : 0 : newptr= nfmalloc(hashlen+1);
406 : 0 : memcpy(newptr, hashstart, hashlen);
407 : 0 : newptr[hashlen] = '\0';
408 : 0 : newlink->hash= newptr;
409 : 0 : newlink->flags = flags;
410 : 0 : newlink->next =NULL;
411 : 0 : *lastp= newlink;
412 : 0 : lastp= &newlink->next;
413 : 0 : value= endent;
414 : : }
415 : 0 : }
416 : :
417 : : void
418 : 4 : f_dependency(struct pkginfo *pkg, struct pkgbin *pkgbin,
419 : : struct parsedb_state *ps,
420 : : const char *value, const struct fieldinfo *fip)
421 : : {
422 : : const char *p, *emsg;
423 : : static struct varbuf depname, version;
424 : :
425 : : struct dependency **ldypp;
426 : :
427 : : /* Empty fields are ignored. */
428 [ - + ]: 4 : if (!*value)
429 : 0 : return;
430 : 4 : p= value;
431 : :
432 : 4 : ldypp = &pkgbin->depends;
433 [ + + ]: 6 : while (*ldypp)
434 : 2 : ldypp = &(*ldypp)->next;
435 : :
436 : : /* Loop creating new struct dependency's. */
437 : 0 : for (;;) {
438 : : struct deppossi **ldopp;
439 : : struct dependency *dyp;
440 : :
441 : 4 : dyp = nfmalloc(sizeof(*dyp));
442 : : /* Set this to NULL for now, as we don't know what our real
443 : : * struct pkginfo address (in the database) is going to be yet. */
444 : 4 : dyp->up = NULL;
445 : 4 : dyp->next= NULL; *ldypp= dyp; ldypp= &dyp->next;
446 : 4 : dyp->list= NULL; ldopp= &dyp->list;
447 : 4 : dyp->type= fip->integer;
448 : :
449 : : /* Loop creating new struct deppossi's. */
450 : 0 : for (;;) {
451 : : const char *depnamestart;
452 : : int depnamelength;
453 : : struct deppossi *dop;
454 : :
455 : 4 : depnamestart= p;
456 : : /* Skip over package name characters. */
457 [ + + + - : 40 : while (*p && !c_isspace(*p) && *p != ':' && *p != '(' && *p != ',' &&
+ - + - +
- ]
458 [ + - ]: 36 : *p != '|')
459 : 36 : p++;
460 : 4 : depnamelength= p - depnamestart ;
461 [ - + ]: 4 : if (depnamelength == 0)
462 : 0 : parse_error(ps,
463 : 0 : _("'%s' field, missing package name, or garbage where "
464 : 0 : "package name expected"), fip->name);
465 : :
466 : 4 : varbuf_set_buf(&depname, depnamestart, depnamelength);
467 : :
468 : 4 : emsg = pkg_name_is_illegal(depname.buf);
469 [ - + ]: 4 : if (emsg)
470 : 0 : parse_error(ps,
471 : 0 : _("'%s' field, invalid package name '%.255s': %s"),
472 : 0 : fip->name, depname.buf, emsg);
473 : 4 : dop = nfmalloc(sizeof(*dop));
474 : 4 : dop->up= dyp;
475 : 4 : dop->ed = pkg_hash_find_set(depname.buf);
476 : 4 : dop->next= NULL; *ldopp= dop; ldopp= &dop->next;
477 : :
478 : : /* Don't link this (which is after all only ‘new_pkg’ from
479 : : * the main parsing loop in parsedb) into the depended on
480 : : * packages' lists yet. This will be done later when we
481 : : * install this (in parse.c). For the moment we do the
482 : : * ‘forward’ links in deppossi (‘ed’) only, and the ‘backward’
483 : : * links from the depended on packages to dop are left undone. */
484 : 4 : dop->rev_next = NULL;
485 : 4 : dop->rev_prev = NULL;
486 : :
487 : 4 : dop->cyclebreak = false;
488 : :
489 : : /* See if we have an architecture qualifier. */
490 [ - + ]: 4 : if (*p == ':') {
491 : : static struct varbuf arch;
492 : : const char *archstart;
493 : : int archlength;
494 : :
495 : 0 : archstart = ++p;
496 [ # # # # : 0 : while (*p && !c_isspace(*p) && *p != '(' && *p != ',' && *p != '|')
# # # # #
# ]
497 : 0 : p++;
498 : 0 : archlength = p - archstart;
499 [ # # ]: 0 : if (archlength == 0)
500 : 0 : parse_error(ps, _("'%s' field, missing architecture name, or garbage "
501 : 0 : "where architecture name expected"), fip->name);
502 : :
503 : 0 : varbuf_set_buf(&arch, archstart, archlength);
504 : :
505 : 0 : dop->arch_is_implicit = false;
506 : 0 : dop->arch = dpkg_arch_find(arch.buf);
507 : :
508 [ # # ]: 0 : if (dop->arch->type == DPKG_ARCH_ILLEGAL)
509 : 0 : emsg = dpkg_arch_name_is_illegal(arch.buf);
510 [ # # ]: 0 : if (emsg)
511 : 0 : parse_error(ps, _("'%s' field, reference to '%.255s': "
512 : : "invalid architecture name '%.255s': %s"),
513 : 0 : fip->name, depname.buf, arch.buf, emsg);
514 [ + - + - ]: 4 : } else if (fip->integer == dep_conflicts || fip->integer == dep_breaks ||
515 [ - + ]: 4 : fip->integer == dep_replaces) {
516 : : /* Conflicts/Breaks/Replaces get an implicit "any" arch qualifier. */
517 : 0 : dop->arch_is_implicit = true;
518 : 0 : dop->arch = dpkg_arch_get(DPKG_ARCH_WILDCARD);
519 : : } else {
520 : : /* Otherwise use the pkgbin architecture, which will be assigned to
521 : : * later on by parse.c, once we can guarantee we have parsed it from
522 : : * the control stanza. */
523 : 4 : dop->arch_is_implicit = true;
524 : 4 : dop->arch = NULL;
525 : : }
526 : :
527 : : /* Skip whitespace after package name. */
528 [ - + ]: 4 : while (c_isspace(*p))
529 : 0 : p++;
530 : :
531 : : /* See if we have a versioned relation. */
532 [ - + ]: 4 : if (*p == '(') {
533 : : char c1;
534 : : const char *versionstart;
535 : : int versionlength;
536 : :
537 : 0 : p++;
538 [ # # ]: 0 : while (c_isspace(*p))
539 : 0 : p++;
540 : 0 : c1= *p;
541 [ # # # # ]: 0 : if (c1 == '<' || c1 == '>') {
542 : : char c2;
543 : :
544 : 0 : c2= *++p;
545 [ # # ]: 0 : dop->verrel = (c1 == '<') ? DPKG_RELATION_LT : DPKG_RELATION_GT;
546 [ # # ]: 0 : if (c2 == '=') {
547 : 0 : dop->verrel |= DPKG_RELATION_EQ;
548 : 0 : p++;
549 [ # # ]: 0 : } else if (c2 == c1) {
550 : : /* Either ‘<<’ or ‘>>’. */
551 : 0 : p++;
552 [ # # # # ]: 0 : } else if (c2 == '<' || c2 == '>') {
553 : 0 : parse_error(ps,
554 : 0 : _("'%s' field, reference to '%.255s':\n"
555 : : " bad version relationship %c%c"),
556 : 0 : fip->name, depname.buf, c1, c2);
557 : : } else {
558 : 0 : parse_warn(ps,
559 : 0 : _("'%s' field, reference to '%.255s':\n"
560 : : " '%c' is obsolete, use '%c=' or '%c%c' instead"),
561 : 0 : fip->name, depname.buf, c1, c1, c1, c1);
562 : 0 : dop->verrel |= DPKG_RELATION_EQ;
563 : : }
564 [ # # ]: 0 : } else if (c1 == '=') {
565 : 0 : dop->verrel = DPKG_RELATION_EQ;
566 : 0 : p++;
567 : : } else {
568 : 0 : parse_warn(ps,
569 : 0 : _("'%s' field, reference to '%.255s':\n"
570 : : " implicit exact match on version number, "
571 : : "suggest using '=' instead"),
572 : 0 : fip->name, depname.buf);
573 : 0 : dop->verrel = DPKG_RELATION_EQ;
574 : : }
575 [ # # # # ]: 0 : if ((dop->verrel != DPKG_RELATION_EQ) && (fip->integer == dep_provides))
576 : 0 : parse_lax_problem(ps, pdb_lax_stanza_parser,
577 : 0 : _("only exact versions may be used for '%s' field"),
578 : 0 : fip->name);
579 : :
580 [ # # # # ]: 0 : if (!c_isspace(*p) && !c_isalnum(*p)) {
581 : 0 : parse_warn(ps,
582 : 0 : _("'%s' field, reference to '%.255s':\n"
583 : : " version value starts with non-alphanumeric, "
584 : : "suggest adding a space"),
585 : 0 : fip->name, depname.buf);
586 : : }
587 : : /* Skip spaces between the relation and the version. */
588 [ # # ]: 0 : while (c_isspace(*p))
589 : 0 : p++;
590 : :
591 : 0 : versionstart= p;
592 [ # # # # : 0 : while (*p && *p != ')' && *p != '(') {
# # ]
593 [ # # ]: 0 : if (c_isspace(*p))
594 : 0 : break;
595 : 0 : p++;
596 : : }
597 : 0 : versionlength= p - versionstart;
598 [ # # ]: 0 : while (c_isspace(*p))
599 : 0 : p++;
600 [ # # ]: 0 : if (*p == '\0')
601 : 0 : parse_error(ps,
602 : 0 : _("'%s' field, reference to '%.255s': "
603 : 0 : "version unterminated"), fip->name, depname.buf);
604 [ # # ]: 0 : else if (*p != ')')
605 : 0 : parse_error(ps,
606 : 0 : _("'%s' field, reference to '%.255s': "
607 : : "version contains '%c' instead of '%c'"),
608 : 0 : fip->name, depname.buf, *p, ')');
609 : 0 : varbuf_set_buf(&version, versionstart, versionlength);
610 [ # # ]: 0 : if (parse_db_version(ps, &dop->version, version.buf) < 0)
611 : 0 : parse_problem(ps,
612 : 0 : _("'%s' field, reference to '%.255s': version '%s'"),
613 : 0 : fip->name, depname.buf, version.buf);
614 : 0 : p++;
615 [ # # ]: 0 : while (c_isspace(*p))
616 : 0 : p++;
617 : : } else {
618 : 4 : dop->verrel = DPKG_RELATION_NONE;
619 : 4 : dpkg_version_blank(&dop->version);
620 : : }
621 [ - + - - ]: 4 : if (!*p || *p == ',') break;
622 [ # # ]: 0 : if (*p != '|')
623 : 0 : parse_error(ps,
624 : 0 : _("'%s' field, syntax error after reference to package '%.255s'"),
625 : 0 : fip->name, dop->ed->name);
626 [ # # ]: 0 : if (fip->integer == dep_conflicts ||
627 [ # # ]: 0 : fip->integer == dep_breaks ||
628 [ # # ]: 0 : fip->integer == dep_provides ||
629 [ # # ]: 0 : fip->integer == dep_replaces)
630 : 0 : parse_error(ps, _("alternatives ('|') not allowed in '%s' field"),
631 : 0 : fip->name);
632 : 0 : p++;
633 [ # # ]: 0 : while (c_isspace(*p))
634 : 0 : p++;
635 : : }
636 [ + - ]: 4 : if (!*p) break;
637 : 0 : p++;
638 [ # # ]: 0 : while (c_isspace(*p))
639 : 0 : p++;
640 : : }
641 : : }
642 : :
643 : : void
644 : 4 : f_obs_dependency(struct pkginfo *pkg, struct pkgbin *pkgbin,
645 : : struct parsedb_state *ps,
646 : : const char *value, const struct fieldinfo *fip)
647 : : {
648 : 4 : parse_warn(ps, _("obsolete '%s' field used"), fip->name);
649 : 4 : f_dependency(pkg, pkgbin, ps, value, fip);
650 : 4 : }
651 : :
652 : : static const char *
653 : 0 : scan_word(const char **valp)
654 : : {
655 : : static struct varbuf word;
656 : : const char *p, *start, *end;
657 : :
658 : 0 : p = *valp;
659 : : for (;;) {
660 [ # # ]: 0 : if (!*p) {
661 : 0 : *valp = p;
662 : 0 : return NULL;
663 : : }
664 [ # # ]: 0 : if (c_iswhite(*p)) {
665 : 0 : p++;
666 : 0 : continue;
667 : : }
668 : 0 : start = p;
669 : 0 : break;
670 : : }
671 : : for (;;) {
672 [ # # # # ]: 0 : if (*p && !c_iswhite(*p)) {
673 : 0 : p++;
674 : 0 : continue;
675 : : }
676 : 0 : end = p;
677 : 0 : break;
678 : : }
679 : :
680 : 0 : varbuf_set_buf(&word, start, end - start);
681 : :
682 : 0 : *valp = p;
683 : :
684 : 0 : return word.buf;
685 : : }
686 : :
687 : : void
688 : 0 : f_trigpend(struct pkginfo *pend, struct pkgbin *pkgbin,
689 : : struct parsedb_state *ps,
690 : : const char *value, const struct fieldinfo *fip)
691 : : {
692 : : const char *word;
693 : :
694 [ # # ]: 0 : if (ps->flags & pdb_rejectstatus)
695 : 0 : parse_error(ps,
696 : 0 : _("value for '%s' field not allowed in this context"),
697 : 0 : fip->name);
698 : :
699 [ # # ]: 0 : while ((word = scan_word(&value))) {
700 : : const char *emsg;
701 : :
702 : 0 : emsg = trig_name_is_illegal(word);
703 [ # # ]: 0 : if (emsg)
704 : 0 : parse_error(ps,
705 : 0 : _("illegal pending trigger name '%.255s': %s"), word, emsg);
706 : :
707 [ # # ]: 0 : if (!trig_note_pend_core(pend, nfstrsave(word)))
708 : 0 : parse_error(ps,
709 : 0 : _("duplicate pending trigger '%.255s'"), word);
710 : : }
711 : 0 : }
712 : :
713 : : void
714 : 0 : f_trigaw(struct pkginfo *aw, struct pkgbin *pkgbin,
715 : : struct parsedb_state *ps,
716 : : const char *value, const struct fieldinfo *fip)
717 : : {
718 : : const char *word;
719 : :
720 [ # # ]: 0 : if (ps->flags & pdb_rejectstatus)
721 : 0 : parse_error(ps,
722 : 0 : _("value for '%s' field not allowed in this context"),
723 : 0 : fip->name);
724 : :
725 [ # # ]: 0 : while ((word = scan_word(&value))) {
726 : : struct pkginfo *pend;
727 : : struct dpkg_error err;
728 : :
729 : 0 : pend = pkg_spec_parse_pkg(word, &err);
730 [ # # ]: 0 : if (pend == NULL)
731 : 0 : parse_error(ps,
732 : 0 : _("illegal package name in awaited trigger '%.255s': %s"),
733 : : word, err.str);
734 : :
735 [ # # ]: 0 : if (!trig_note_aw(pend, aw))
736 : 0 : parse_error(ps,
737 : 0 : _("duplicate awaited trigger package '%.255s'"), word);
738 : :
739 : 0 : trig_awaited_pend_enqueue(pend);
740 : : }
741 : 0 : }
|