]> git.ipfire.org Git - thirdparty/nettle.git/blame - sexp-transport.c
Update config.guess and config.sub to 2024-01-01 versions.
[thirdparty/nettle.git] / sexp-transport.c
CommitLineData
b64b3086 1/* sexp-transport.c
90112edb
NM
2
3 Parsing s-expressions in transport format.
4
5 Copyright (C) 2002 Niels Möller
6
7 This file is part of GNU Nettle.
8
9 GNU Nettle is free software: you can redistribute it and/or
10 modify it under the terms of either:
11
12 * the GNU Lesser General Public License as published by the Free
13 Software Foundation; either version 3 of the License, or (at your
14 option) any later version.
15
16 or
17
18 * the GNU General Public License as published by the Free
19 Software Foundation; either version 2 of the License, or (at your
20 option) any later version.
21
22 or both in parallel, as here.
23
24 GNU Nettle is distributed in the hope that it will be useful,
25 but WITHOUT ANY WARRANTY; without even the implied warranty of
26 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 General Public License for more details.
28
29 You should have received copies of the GNU General Public License and
30 the GNU Lesser General Public License along with this program. If
31 not, see http://www.gnu.org/licenses/.
32*/
b64b3086 33
c5c15385
NM
34#if HAVE_CONFIG_H
35# include "config.h"
36#endif
b64b3086
NM
37
38#include <assert.h>
39#include <string.h>
40
c5c15385
NM
41#include "sexp.h"
42
43#include "base64.h"
44
b64b3086
NM
45/* NOTE: Decodes the input string in place */
46int
47sexp_transport_iterator_first(struct sexp_iterator *iterator,
86fdb2ce 48 size_t length, uint8_t *input)
b64b3086
NM
49{
50 /* We first base64 decode any transport encoded sexp at the start of
51 * the input. */
52
86fdb2ce
NM
53 size_t in = 0;
54 size_t out = 0;
b64b3086
NM
55
56 while (in < length)
57 switch(input[in])
58 {
59 case ' ': /* SPC, TAB, LF, CR */
60 case '\t':
61 case '\n':
62 case '\r':
63 in++;
64 break;
65
66 case ';': /* Comments */
67 while (++in < length && input[in] != '\n')
68 ;
69 break;
70
71 case '{':
72 {
73 /* Found transport encoding */
74 struct base64_decode_ctx ctx;
86fdb2ce
NM
75 size_t coded_length;
76 size_t end;
b64b3086
NM
77
78 for (end = ++in; end < length && input[end] != '}'; end++)
79 ;
80
81 if (end == length)
82 return 0;
83
84 base64_decode_init(&ctx);
e0292d52 85
38f1828d 86 if (base64_decode_update(&ctx, &coded_length, input + out,
f2da4031 87 end - in, (const char*) (input + in))
e0292d52
NM
88 && base64_decode_final(&ctx))
89 {
38f1828d 90 out += coded_length;
e0292d52
NM
91 in = end + 1;
92 }
93 else
b64b3086 94 return 0;
e0292d52 95
b64b3086
NM
96 break;
97 }
98 default:
99 /* Expression isn't in transport encoding. Rest of the input
100 * should be in canonical encoding. */
101 goto transport_done;
102 }
103
104 transport_done:
105
106 /* Here, we have two, possibly empty, input parts in canonical
107 * encoding:
108 *
109 * 0...out-1, in...length -1
110 *
111 * If the input was already in canonical encoding, out = 0 and in =
112 * amount of leading space.
113 *
114 * If all input was in transport encoding, in == length.
115 */
116 if (!out)
117 {
118 input += in;
119 length -= in;
120 }
121 else if (in == length)
122 length = out;
123 else if (out == in)
124 /* Unusual case, nothing happens */
125 ;
126 else
127 {
128 /* Both parts non-empty */
129 assert(out < in);
130 memmove(input + out, input + in, length - in);
131 length -= (in - out);
132 }
133
134 return sexp_iterator_first(iterator, length, input);
135}