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_flags {
47 : : /** Expect no more words (default). */
48 : : PARSE_NV_LAST = 0,
49 : : /** Expect another word after the parsed name. */
50 : : PARSE_NV_NEXT = DPKG_BIT(0),
51 : : /** Do not fail if there is no name with an associated value found. */
52 : : PARSE_NV_FALLBACK = DPKG_BIT(1),
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 #PARSE_NV_FALLBACK is set in @a flags then @a strp is set
61 : : * to NULL and returns -1, otherwise a parse error is emitted.
62 : : */
63 : : static int
64 : 26 : parse_nv(struct parsedb_state *ps, enum parse_nv_flags flags,
65 : : const char **strp, const struct namevalue *nv_head)
66 : : {
67 : 26 : const char *str_start = *strp, *str_end;
68 : : const struct namevalue *nv;
69 : : int value;
70 : :
71 : 26 : dpkg_error_destroy(&ps->err);
72 : :
73 [ - + ]: 26 : if (str_start[0] == '\0')
74 : 0 : return dpkg_put_error(&ps->err, _("is missing a value"));
75 : :
76 : 26 : nv = namevalue_find_by_name(nv_head, str_start);
77 [ - + ]: 26 : if (nv == NULL) {
78 : : /* We got no match, skip further string validation. */
79 [ # # ]: 0 : if (!(flags & 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 : 26 : str_end = str_start + nv->length;
86 [ + + ]: 28 : while (c_isspace(str_end[0]))
87 : 2 : str_end++;
88 : 26 : value = nv->value;
89 : : }
90 : :
91 [ + + - + ]: 26 : if (!(flags & PARSE_NV_NEXT) && str_is_set(str_end))
92 : 0 : return dpkg_put_error(&ps->err, _("has trailing junk"));
93 : :
94 : 26 : *strp = str_end;
95 : :
96 : 26 : return value;
97 : : }
98 : :
99 : : void
100 : 24 : 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 : 24 : e = pkg_name_is_illegal(value);
107 [ - + ]: 24 : 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 : 24 : pkg->set->name = pkg_hash_find_set(value)->name;
111 : 24 : }
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 : 48 : f_charfield(struct pkginfo *pkg, struct pkgbin *pkgbin,
162 : : struct parsedb_state *ps,
163 : : const char *value, const struct fieldinfo *fip)
164 : : {
165 [ + - ]: 48 : if (*value)
166 : 48 : STRUCTFIELD(pkgbin, fip->integer, char *) = nfstrsave(value);
167 : 48 : }
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 : 24 : f_architecture(struct pkginfo *pkg, struct pkgbin *pkgbin,
206 : : struct parsedb_state *ps,
207 : : const char *value, const struct fieldinfo *fip)
208 : : {
209 : 24 : pkgbin->arch = dpkg_arch_find(value);
210 [ - + ]: 24 : 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 : 24 : }
214 : :
215 : : void
216 : 23 : f_section(struct pkginfo *pkg, struct pkgbin *pkgbin,
217 : : struct parsedb_state *ps,
218 : : const char *value, const struct fieldinfo *fip)
219 : : {
220 [ - + ]: 23 : if (!*value) return;
221 : 23 : pkg->section = nfstrsave(value);
222 : : }
223 : :
224 : : void
225 : 23 : f_priority(struct pkginfo *pkg, struct pkgbin *pkgbin,
226 : : struct parsedb_state *ps,
227 : : const char *value, const struct fieldinfo *fip)
228 : : {
229 : 23 : const char *str = value;
230 : : int priority;
231 : :
232 [ - + ]: 23 : if (!*value) return;
233 : :
234 : 23 : priority = parse_nv(ps, PARSE_NV_LAST | PARSE_NV_FALLBACK, &str,
235 : : priorityinfos);
236 [ - + ]: 23 : if (dpkg_has_error(&ps->err))
237 : 0 : parse_error(ps, _("word in '%s' field: %s"), fip->name, ps->err.str);
238 : :
239 [ - + ]: 23 : if (str == NULL) {
240 : 0 : pkg->priority = PKG_PRIO_OTHER;
241 : 0 : pkg->otherpriority = nfstrsave(value);
242 : : } else {
243 : 23 : pkg->priority = priority;
244 : : }
245 : : }
246 : :
247 : : void
248 : 2 : f_obs_class(struct pkginfo *pkg, struct pkgbin *pkgbin,
249 : : struct parsedb_state *ps,
250 : : const char *value, const struct fieldinfo *fip)
251 : : {
252 : 2 : parse_warn(ps, _("obsolete '%s' field used"), fip->name);
253 : 2 : f_priority(pkg, pkgbin, ps, value, fip);
254 : 2 : }
255 : :
256 : : void
257 : 1 : f_status(struct pkginfo *pkg, struct pkgbin *pkgbin,
258 : : struct parsedb_state *ps,
259 : : const char *value, const struct fieldinfo *fip)
260 : : {
261 [ - + ]: 1 : if (ps->flags & pdb_rejectstatus)
262 : 0 : parse_error(ps,
263 : 0 : _("value for '%s' field not allowed in this context"),
264 : 0 : fip->name);
265 [ - + ]: 1 : if (ps->flags & pdb_recordavailable)
266 : 0 : return;
267 : :
268 : 1 : pkg->want = parse_nv(ps, PARSE_NV_NEXT, &value, wantinfos);
269 [ - + ]: 1 : if (dpkg_has_error(&ps->err))
270 : 0 : parse_error(ps, _("first (want) word in '%s' field: %s"),
271 : 0 : fip->name, ps->err.str);
272 : 1 : pkg->eflag = parse_nv(ps, PARSE_NV_NEXT, &value, eflaginfos);
273 [ - + ]: 1 : if (dpkg_has_error(&ps->err))
274 : 0 : parse_error(ps, _("second (error) word in '%s' field: %s"),
275 : 0 : fip->name, ps->err.str);
276 : 1 : pkg->status = parse_nv(ps, PARSE_NV_LAST, &value, statusinfos);
277 [ - + ]: 1 : if (dpkg_has_error(&ps->err))
278 : 0 : parse_error(ps, _("third (status) word in '%s' field: %s"),
279 : 0 : fip->name, ps->err.str);
280 : : }
281 : :
282 : : void
283 : 24 : f_version(struct pkginfo *pkg, struct pkgbin *pkgbin,
284 : : struct parsedb_state *ps,
285 : : const char *value, const struct fieldinfo *fip)
286 : : {
287 [ - + ]: 24 : if (parse_db_version(ps, &pkgbin->version, value) < 0)
288 : 0 : parse_problem(ps, _("'%s' field value '%.250s'"), fip->name, value);
289 : 24 : }
290 : :
291 : : void
292 : 2 : f_obs_revision(struct pkginfo *pkg, struct pkgbin *pkgbin,
293 : : struct parsedb_state *ps,
294 : : const char *value, const struct fieldinfo *fip)
295 : : {
296 : : char *newversion;
297 : :
298 : 2 : parse_warn(ps, _("obsolete '%s' field used"), fip->name);
299 [ - + ]: 2 : if (!*value) return;
300 [ - + ]: 2 : if (str_is_set(pkgbin->version.revision)) {
301 : 0 : newversion = nfmalloc(strlen(pkgbin->version.version) +
302 : 0 : strlen(pkgbin->version.revision) + 2);
303 : 0 : sprintf(newversion, "%s-%s", pkgbin->version.version,
304 : : pkgbin->version.revision);
305 : 0 : pkgbin->version.version = newversion;
306 : : }
307 : 2 : pkgbin->version.revision = nfstrsave(value);
308 : : }
309 : :
310 : : void
311 : 0 : f_configversion(struct pkginfo *pkg, struct pkgbin *pkgbin,
312 : : struct parsedb_state *ps,
313 : : const char *value, const struct fieldinfo *fip)
314 : : {
315 [ # # ]: 0 : if (ps->flags & pdb_rejectstatus)
316 : 0 : parse_error(ps,
317 : 0 : _("value for '%s' field not allowed in this context"),
318 : 0 : fip->name);
319 [ # # ]: 0 : if (ps->flags & pdb_recordavailable)
320 : 0 : return;
321 : :
322 [ # # ]: 0 : if (parse_db_version(ps, &pkg->configversion, value) < 0)
323 : 0 : parse_problem(ps, _("'%s' field value '%.250s'"), fip->name, value);
324 : : }
325 : :
326 : : /*
327 : : * The code in f_conffiles ensures that value[-1] == ' ', which is helpful.
328 : : */
329 : 0 : static void conffvalue_lastword(const char *value, const char *from,
330 : : const char *endent,
331 : : const char **word_start_r, int *word_len_r,
332 : : const char **new_from_r,
333 : : struct parsedb_state *ps)
334 : : {
335 : : const char *lastspc;
336 : :
337 [ # # ]: 0 : if (from <= value+1) goto malformed;
338 [ # # ]: 0 : for (lastspc= from-1; *lastspc != ' '; lastspc--);
339 [ # # # # ]: 0 : if (lastspc <= value+1 || lastspc >= endent-1) goto malformed;
340 : :
341 : 0 : *new_from_r= lastspc;
342 : 0 : *word_start_r= lastspc + 1;
343 : 0 : *word_len_r= (int)(from - *word_start_r);
344 : 0 : return;
345 : :
346 : 0 : malformed:
347 : 0 : parse_error(ps,
348 : 0 : _("value for '%s' field has malformed line '%.*s'"),
349 [ # # ]: 0 : "Conffiles", (int)min(endent - value, 250), value);
350 : : }
351 : :
352 : : void
353 : 0 : f_conffiles(struct pkginfo *pkg, struct pkgbin *pkgbin,
354 : : struct parsedb_state *ps,
355 : : const char *value, const struct fieldinfo *fip)
356 : : {
357 : : static const char obsolete_str[]= "obsolete";
358 : : static const char remove_on_upgrade_str[] = "remove-on-upgrade";
359 : : struct conffile **lastp, *newlink;
360 : : const char *endent, *endfn, *hashstart;
361 : : int c, namelen, hashlen;
362 : : bool obsolete, remove_on_upgrade;
363 : : char *newptr;
364 : :
365 : 0 : lastp = &pkgbin->conffiles;
366 [ # # ]: 0 : while (*value) {
367 : 0 : c= *value++;
368 [ # # ]: 0 : if (c == '\n') continue;
369 [ # # ]: 0 : if (c != ' ')
370 : 0 : parse_error(ps,
371 : 0 : _("value for '%s' field has line starting with non-space '%c'"),
372 : 0 : fip->name, c);
373 [ # # # # ]: 0 : for (endent = value; (c = *endent) != '\0' && c != '\n'; endent++) ;
374 : 0 : conffvalue_lastword(value, endent, endent,
375 : : &hashstart, &hashlen, &endfn,
376 : : ps);
377 [ # # ]: 0 : remove_on_upgrade = (hashlen == sizeof(remove_on_upgrade_str) - 1 &&
378 [ # # ]: 0 : memcmp(hashstart, remove_on_upgrade_str, hashlen) == 0);
379 [ # # ]: 0 : if (remove_on_upgrade)
380 : 0 : conffvalue_lastword(value, endfn, endent, &hashstart, &hashlen, &endfn,
381 : : ps);
382 : :
383 [ # # ]: 0 : obsolete= (hashlen == sizeof(obsolete_str)-1 &&
384 [ # # ]: 0 : memcmp(hashstart, obsolete_str, hashlen) == 0);
385 [ # # ]: 0 : if (obsolete)
386 : 0 : conffvalue_lastword(value, endfn, endent,
387 : : &hashstart, &hashlen, &endfn,
388 : : ps);
389 : 0 : newlink = nfmalloc(sizeof(*newlink));
390 : 0 : value = path_skip_slash_dotslash(value);
391 : 0 : namelen= (int)(endfn-value);
392 [ # # ]: 0 : if (namelen <= 0)
393 : 0 : parse_error(ps,
394 : 0 : _("root or empty directory listed as a conffile in '%s' field"),
395 : 0 : fip->name);
396 : 0 : newptr = nfmalloc(namelen+2);
397 : 0 : newptr[0]= '/';
398 : 0 : memcpy(newptr+1,value,namelen);
399 : 0 : newptr[namelen+1] = '\0';
400 : 0 : newlink->name= newptr;
401 : 0 : newptr= nfmalloc(hashlen+1);
402 : 0 : memcpy(newptr, hashstart, hashlen);
403 : 0 : newptr[hashlen] = '\0';
404 : 0 : newlink->hash= newptr;
405 : 0 : newlink->obsolete= obsolete;
406 : 0 : newlink->remove_on_upgrade = remove_on_upgrade;
407 : 0 : newlink->next =NULL;
408 : 0 : *lastp= newlink;
409 : 0 : lastp= &newlink->next;
410 : 0 : value= endent;
411 : : }
412 : 0 : }
413 : :
414 : : void
415 : 4 : f_dependency(struct pkginfo *pkg, struct pkgbin *pkgbin,
416 : : struct parsedb_state *ps,
417 : : const char *value, const struct fieldinfo *fip)
418 : : {
419 : : char c1, c2;
420 : : const char *p, *emsg;
421 : : const char *depnamestart, *versionstart;
422 : : int depnamelength, versionlength;
423 : : static struct varbuf depname, version;
424 : :
425 : : struct dependency *dyp, **ldypp;
426 : : struct deppossi *dop, **ldopp;
427 : :
428 : : /* Empty fields are ignored. */
429 [ - + ]: 4 : if (!*value)
430 : 0 : return;
431 : 4 : p= value;
432 : :
433 : 4 : ldypp = &pkgbin->depends;
434 [ + + ]: 6 : while (*ldypp)
435 : 2 : ldypp = &(*ldypp)->next;
436 : :
437 : : /* Loop creating new struct dependency's. */
438 : : for (;;) {
439 : 4 : dyp = nfmalloc(sizeof(*dyp));
440 : : /* Set this to NULL for now, as we don't know what our real
441 : : * struct pkginfo address (in the database) is going to be yet. */
442 : 4 : dyp->up = NULL;
443 : 4 : dyp->next= NULL; *ldypp= dyp; ldypp= &dyp->next;
444 : 4 : dyp->list= NULL; ldopp= &dyp->list;
445 : 4 : dyp->type= fip->integer;
446 : :
447 : : /* Loop creating new struct deppossi's. */
448 : : for (;;) {
449 : 4 : depnamestart= p;
450 : : /* Skip over package name characters. */
451 [ + + + - : 40 : while (*p && !c_isspace(*p) && *p != ':' && *p != '(' && *p != ',' &&
+ - + - +
- ]
452 [ + - ]: 36 : *p != '|')
453 : 36 : p++;
454 : 4 : depnamelength= p - depnamestart ;
455 [ - + ]: 4 : if (depnamelength == 0)
456 : 0 : parse_error(ps,
457 : 0 : _("'%s' field, missing package name, or garbage where "
458 : 0 : "package name expected"), fip->name);
459 : :
460 : 4 : varbuf_reset(&depname);
461 : 4 : varbuf_add_buf(&depname, depnamestart, depnamelength);
462 : 4 : varbuf_end_str(&depname);
463 : :
464 : 4 : emsg = pkg_name_is_illegal(depname.buf);
465 [ - + ]: 4 : if (emsg)
466 : 0 : parse_error(ps,
467 : 0 : _("'%s' field, invalid package name '%.255s': %s"),
468 : 0 : fip->name, depname.buf, emsg);
469 : 4 : dop = nfmalloc(sizeof(*dop));
470 : 4 : dop->up= dyp;
471 : 4 : dop->ed = pkg_hash_find_set(depname.buf);
472 : 4 : dop->next= NULL; *ldopp= dop; ldopp= &dop->next;
473 : :
474 : : /* Don't link this (which is after all only ‘new_pkg’ from
475 : : * the main parsing loop in parsedb) into the depended on
476 : : * packages' lists yet. This will be done later when we
477 : : * install this (in parse.c). For the moment we do the
478 : : * ‘forward’ links in deppossi (‘ed’) only, and the ‘backward’
479 : : * links from the depended on packages to dop are left undone. */
480 : 4 : dop->rev_next = NULL;
481 : 4 : dop->rev_prev = NULL;
482 : :
483 : 4 : dop->cyclebreak = false;
484 : :
485 : : /* See if we have an architecture qualifier. */
486 [ - + ]: 4 : if (*p == ':') {
487 : : static struct varbuf arch;
488 : : const char *archstart;
489 : : int archlength;
490 : :
491 : 0 : archstart = ++p;
492 [ # # # # : 0 : while (*p && !c_isspace(*p) && *p != '(' && *p != ',' && *p != '|')
# # # # #
# ]
493 : 0 : p++;
494 : 0 : archlength = p - archstart;
495 [ # # ]: 0 : if (archlength == 0)
496 : 0 : parse_error(ps, _("'%s' field, missing architecture name, or garbage "
497 : 0 : "where architecture name expected"), fip->name);
498 : :
499 : 0 : varbuf_reset(&arch);
500 : 0 : varbuf_add_buf(&arch, archstart, archlength);
501 : 0 : varbuf_end_str(&arch);
502 : :
503 : 0 : dop->arch_is_implicit = false;
504 : 0 : dop->arch = dpkg_arch_find(arch.buf);
505 : :
506 [ # # ]: 0 : if (dop->arch->type == DPKG_ARCH_ILLEGAL)
507 : 0 : emsg = dpkg_arch_name_is_illegal(arch.buf);
508 [ # # ]: 0 : if (emsg)
509 : 0 : parse_error(ps, _("'%s' field, reference to '%.255s': "
510 : : "invalid architecture name '%.255s': %s"),
511 : 0 : fip->name, depname.buf, arch.buf, emsg);
512 [ + - + - ]: 4 : } else if (fip->integer == dep_conflicts || fip->integer == dep_breaks ||
513 [ - + ]: 4 : fip->integer == dep_replaces) {
514 : : /* Conflicts/Breaks/Replaces get an implicit "any" arch qualifier. */
515 : 0 : dop->arch_is_implicit = true;
516 : 0 : dop->arch = dpkg_arch_get(DPKG_ARCH_WILDCARD);
517 : : } else {
518 : : /* Otherwise use the pkgbin architecture, which will be assigned to
519 : : * later on by parse.c, once we can guarantee we have parsed it from
520 : : * the control stanza. */
521 : 4 : dop->arch_is_implicit = true;
522 : 4 : dop->arch = NULL;
523 : : }
524 : :
525 : : /* Skip whitespace after package name. */
526 [ - + ]: 4 : while (c_isspace(*p))
527 : 0 : p++;
528 : :
529 : : /* See if we have a versioned relation. */
530 [ - + ]: 4 : if (*p == '(') {
531 : 0 : p++;
532 [ # # ]: 0 : while (c_isspace(*p))
533 : 0 : p++;
534 : 0 : c1= *p;
535 [ # # # # ]: 0 : if (c1 == '<' || c1 == '>') {
536 : 0 : c2= *++p;
537 [ # # ]: 0 : dop->verrel = (c1 == '<') ? DPKG_RELATION_LT : DPKG_RELATION_GT;
538 [ # # ]: 0 : if (c2 == '=') {
539 : 0 : dop->verrel |= DPKG_RELATION_EQ;
540 : 0 : p++;
541 [ # # ]: 0 : } else if (c2 == c1) {
542 : : /* Either ‘<<’ or ‘>>’. */
543 : 0 : p++;
544 [ # # # # ]: 0 : } else if (c2 == '<' || c2 == '>') {
545 : 0 : parse_error(ps,
546 : 0 : _("'%s' field, reference to '%.255s':\n"
547 : : " bad version relationship %c%c"),
548 : 0 : fip->name, depname.buf, c1, c2);
549 : : dop->verrel = DPKG_RELATION_NONE;
550 : : } else {
551 : 0 : parse_warn(ps,
552 : 0 : _("'%s' field, reference to '%.255s':\n"
553 : : " '%c' is obsolete, use '%c=' or '%c%c' instead"),
554 : 0 : fip->name, depname.buf, c1, c1, c1, c1);
555 : 0 : dop->verrel |= DPKG_RELATION_EQ;
556 : : }
557 [ # # ]: 0 : } else if (c1 == '=') {
558 : 0 : dop->verrel = DPKG_RELATION_EQ;
559 : 0 : p++;
560 : : } else {
561 : 0 : parse_warn(ps,
562 : 0 : _("'%s' field, reference to '%.255s':\n"
563 : : " implicit exact match on version number, "
564 : : "suggest using '=' instead"),
565 : 0 : fip->name, depname.buf);
566 : 0 : dop->verrel = DPKG_RELATION_EQ;
567 : : }
568 [ # # # # ]: 0 : if ((dop->verrel != DPKG_RELATION_EQ) && (fip->integer == dep_provides))
569 : 0 : parse_warn(ps,
570 : 0 : _("only exact versions may be used for '%s' field"),
571 : 0 : fip->name);
572 : :
573 [ # # # # ]: 0 : if (!c_isspace(*p) && !c_isalnum(*p)) {
574 : 0 : parse_warn(ps,
575 : 0 : _("'%s' field, reference to '%.255s':\n"
576 : : " version value starts with non-alphanumeric, "
577 : : "suggest adding a space"),
578 : 0 : fip->name, depname.buf);
579 : : }
580 : : /* Skip spaces between the relation and the version. */
581 [ # # ]: 0 : while (c_isspace(*p))
582 : 0 : p++;
583 : :
584 : 0 : versionstart= p;
585 [ # # # # : 0 : while (*p && *p != ')' && *p != '(') {
# # ]
586 [ # # ]: 0 : if (c_isspace(*p))
587 : 0 : break;
588 : 0 : p++;
589 : : }
590 : 0 : versionlength= p - versionstart;
591 [ # # ]: 0 : while (c_isspace(*p))
592 : 0 : p++;
593 [ # # ]: 0 : if (*p == '\0')
594 : 0 : parse_error(ps,
595 : 0 : _("'%s' field, reference to '%.255s': "
596 : 0 : "version unterminated"), fip->name, depname.buf);
597 [ # # ]: 0 : else if (*p != ')')
598 : 0 : parse_error(ps,
599 : 0 : _("'%s' field, reference to '%.255s': "
600 : : "version contains '%c' instead of '%c'"),
601 : 0 : fip->name, depname.buf, *p, ')');
602 : 0 : varbuf_reset(&version);
603 : 0 : varbuf_add_buf(&version, versionstart, versionlength);
604 : 0 : varbuf_end_str(&version);
605 [ # # ]: 0 : if (parse_db_version(ps, &dop->version, version.buf) < 0)
606 : 0 : parse_problem(ps,
607 : 0 : _("'%s' field, reference to '%.255s': version '%s'"),
608 : 0 : fip->name, depname.buf, version.buf);
609 : 0 : p++;
610 [ # # ]: 0 : while (c_isspace(*p))
611 : 0 : p++;
612 : : } else {
613 : 4 : dop->verrel = DPKG_RELATION_NONE;
614 : 4 : dpkg_version_blank(&dop->version);
615 : : }
616 [ - + - - ]: 4 : if (!*p || *p == ',') break;
617 [ # # ]: 0 : if (*p != '|')
618 : 0 : parse_error(ps,
619 : 0 : _("'%s' field, syntax error after reference to package '%.255s'"),
620 : 0 : fip->name, dop->ed->name);
621 [ # # ]: 0 : if (fip->integer == dep_conflicts ||
622 [ # # ]: 0 : fip->integer == dep_breaks ||
623 [ # # ]: 0 : fip->integer == dep_provides ||
624 [ # # ]: 0 : fip->integer == dep_replaces)
625 : 0 : parse_error(ps, _("alternatives ('|') not allowed in '%s' field"),
626 : 0 : fip->name);
627 : 0 : p++;
628 [ # # ]: 0 : while (c_isspace(*p))
629 : 0 : p++;
630 : : }
631 [ + - ]: 4 : if (!*p) break;
632 : 0 : p++;
633 [ # # ]: 0 : while (c_isspace(*p))
634 : 0 : p++;
635 : : }
636 : : }
637 : :
638 : : void
639 : 4 : f_obs_dependency(struct pkginfo *pkg, struct pkgbin *pkgbin,
640 : : struct parsedb_state *ps,
641 : : const char *value, const struct fieldinfo *fip)
642 : : {
643 : 4 : parse_warn(ps, _("obsolete '%s' field used"), fip->name);
644 : 4 : f_dependency(pkg, pkgbin, ps, value, fip);
645 : 4 : }
646 : :
647 : : static const char *
648 : 0 : scan_word(const char **valp)
649 : : {
650 : : static struct varbuf word;
651 : : const char *p, *start, *end;
652 : :
653 : 0 : p = *valp;
654 : : for (;;) {
655 [ # # ]: 0 : if (!*p) {
656 : 0 : *valp = p;
657 : 0 : return NULL;
658 : : }
659 [ # # ]: 0 : if (c_iswhite(*p)) {
660 : 0 : p++;
661 : 0 : continue;
662 : : }
663 : 0 : start = p;
664 : 0 : break;
665 : : }
666 : : for (;;) {
667 [ # # # # ]: 0 : if (*p && !c_iswhite(*p)) {
668 : 0 : p++;
669 : 0 : continue;
670 : : }
671 : 0 : end = p;
672 : 0 : break;
673 : : }
674 : :
675 : 0 : varbuf_reset(&word);
676 : 0 : varbuf_add_buf(&word, start, end - start);
677 : 0 : varbuf_end_str(&word);
678 : :
679 : 0 : *valp = p;
680 : :
681 : 0 : return word.buf;
682 : : }
683 : :
684 : : void
685 : 0 : f_trigpend(struct pkginfo *pend, struct pkgbin *pkgbin,
686 : : struct parsedb_state *ps,
687 : : const char *value, const struct fieldinfo *fip)
688 : : {
689 : : const char *word, *emsg;
690 : :
691 [ # # ]: 0 : if (ps->flags & pdb_rejectstatus)
692 : 0 : parse_error(ps,
693 : 0 : _("value for '%s' field not allowed in this context"),
694 : 0 : fip->name);
695 : :
696 [ # # ]: 0 : while ((word = scan_word(&value))) {
697 : 0 : emsg = trig_name_is_illegal(word);
698 [ # # ]: 0 : if (emsg)
699 : 0 : parse_error(ps,
700 : 0 : _("illegal pending trigger name '%.255s': %s"), word, emsg);
701 : :
702 [ # # ]: 0 : if (!trig_note_pend_core(pend, nfstrsave(word)))
703 : 0 : parse_error(ps,
704 : 0 : _("duplicate pending trigger '%.255s'"), word);
705 : : }
706 : 0 : }
707 : :
708 : : void
709 : 0 : f_trigaw(struct pkginfo *aw, struct pkgbin *pkgbin,
710 : : struct parsedb_state *ps,
711 : : const char *value, const struct fieldinfo *fip)
712 : : {
713 : : const char *word;
714 : : struct pkginfo *pend;
715 : :
716 [ # # ]: 0 : if (ps->flags & pdb_rejectstatus)
717 : 0 : parse_error(ps,
718 : 0 : _("value for '%s' field not allowed in this context"),
719 : 0 : fip->name);
720 : :
721 [ # # ]: 0 : while ((word = scan_word(&value))) {
722 : : struct dpkg_error err;
723 : :
724 : 0 : pend = pkg_spec_parse_pkg(word, &err);
725 [ # # ]: 0 : if (pend == NULL)
726 : 0 : parse_error(ps,
727 : 0 : _("illegal package name in awaited trigger '%.255s': %s"),
728 : : word, err.str);
729 : :
730 [ # # ]: 0 : if (!trig_note_aw(pend, aw))
731 : 0 : parse_error(ps,
732 : 0 : _("duplicate awaited trigger package '%.255s'"), word);
733 : :
734 : 0 : trig_awaited_pend_enqueue(pend);
735 : : }
736 : 0 : }
|