Line data Source code
1 : /* sexp-parse.h - S-expression helper functions for canonical encodings.
2 : * Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
3 : * Copyright (C) 2012 g10 Code GmbH
4 : *
5 : * This file is part of KSBA.
6 : *
7 : * KSBA is free software; you can redistribute it and/or modify
8 : * it under the terms of either
9 : *
10 : * - the GNU Lesser General Public License as published by the Free
11 : * Software Foundation; either version 3 of the License, or (at
12 : * your option) any later version.
13 : *
14 : * or
15 : *
16 : * - the GNU General Public License as published by the Free
17 : * Software Foundation; either version 2 of the License, or (at
18 : * your option) any later version.
19 : *
20 : * or both in parallel, as here.
21 : *
22 : * KSBA is distributed in the hope that it will be useful, but WITHOUT
23 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
24 : * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
25 : * License for more details.
26 : *
27 : * You should have received a copies of the GNU General Public License
28 : * and the GNU Lesser General Public License along with this program;
29 : * if not, see <http://www.gnu.org/licenses/>.
30 : */
31 :
32 : #ifndef SEXP_PARSE_H
33 : #define SEXP_PARSE_H
34 :
35 : #include <gpg-error.h>
36 :
37 : /* Return the length of the next S-Exp part and update the pointer to
38 : the first data byte. 0 is returned on error */
39 : static inline size_t
40 0 : snext (unsigned char const **buf)
41 : {
42 : const unsigned char *s;
43 : int n;
44 :
45 0 : s = *buf;
46 0 : for (n=0; *s && *s != ':' && (*s >= '0' && *s <= '9'); s++)
47 0 : n = n*10 + (*s - '0');
48 0 : if (!n || *s != ':')
49 0 : return 0; /* we don't allow empty lengths */
50 0 : *buf = s+1;
51 0 : return n;
52 : }
53 :
54 : /* Skip over the S-Expression BUF points to and update BUF to point to
55 : the chacter right behind. DEPTH gives the initial number of open
56 : lists and may be passed as a positive number to skip over the
57 : remainder of an S-Expression if the current position is somewhere
58 : in an S-Expression. The function may return an error code if it
59 : encounters an impossible conditions */
60 : static inline gpg_error_t
61 : sskip (unsigned char const **buf, int *depth)
62 : {
63 : const unsigned char *s = *buf;
64 : size_t n;
65 : int d = *depth;
66 :
67 : while (d > 0)
68 : {
69 : if (*s == '(')
70 : {
71 : d++;
72 : s++;
73 : }
74 : else if (*s == ')')
75 : {
76 : d--;
77 : s++;
78 : }
79 : else
80 : {
81 : if (!d)
82 : return gpg_error (GPG_ERR_INV_SEXP);
83 : n = snext (&s);
84 : if (!n)
85 : return gpg_error (GPG_ERR_INV_SEXP);
86 : s += n;
87 : }
88 : }
89 : *buf = s;
90 : *depth = d;
91 : return 0;
92 : }
93 :
94 :
95 : /* Check whether the the string at the address BUF points to matches
96 : the token. Return true on match and update BUF to point behind the
97 : token. Return false and do not update the buffer if it does not
98 : match. */
99 : static inline int
100 0 : smatch (unsigned char const **buf, size_t buflen, const char *token)
101 : {
102 0 : size_t toklen = strlen (token);
103 :
104 0 : if (buflen != toklen || memcmp (*buf, token, toklen))
105 0 : return 0;
106 0 : *buf += toklen;
107 0 : return 1;
108 : }
109 :
110 :
111 : /* Format VALUE for use as the length indicatior of an S-expression.
112 : The caller needs to provide a buffer HELP_BUFFER with a length of
113 : HELP_BUFLEN. The return value is a pointer into HELP_BUFFER with
114 : the formatted length string. The colon and a trailing nul are
115 : appended. HELP_BUFLEN must be at least 3 - a more useful value is
116 : 15. If LENGTH is not NULL, the LENGTH of the resulting string
117 : (excluding the terminating nul) is stored at that address. */
118 : static inline char *
119 0 : smklen (char *help_buffer, size_t help_buflen, size_t value, size_t *length)
120 : {
121 0 : char *p = help_buffer + help_buflen;
122 :
123 0 : if (help_buflen >= 3)
124 : {
125 0 : *--p = 0;
126 0 : *--p = ':';
127 : do
128 : {
129 0 : *--p = '0' + (value % 10);
130 0 : value /= 10;
131 : }
132 0 : while (value && p > help_buffer);
133 : }
134 :
135 0 : if (length)
136 0 : *length = (help_buffer + help_buflen) - p;
137 0 : return p;
138 : }
139 :
140 : #endif /*SEXP_PARSE_H*/
|