Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/miniupnpc/src/upnpreplyparse.c
9904 views
1
/* $Id: upnpreplyparse.c,v 1.22 2025/02/08 23:12:26 nanard Exp $ */
2
/* vim: tabstop=4 shiftwidth=4 noexpandtab
3
* MiniUPnP project
4
* http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
5
* (c) 2006-2025 Thomas Bernard
6
* This software is subject to the conditions detailed
7
* in the LICENCE file provided within the distribution */
8
9
#include <stdlib.h>
10
#include <string.h>
11
#include <stdio.h>
12
13
#include "upnpreplyparse.h"
14
#include "minixml.h"
15
16
struct NameValue {
17
/*! \brief pointer to the next element */
18
struct NameValue * l_next;
19
/*! \brief name */
20
char name[64];
21
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
22
/* C99 flexible array member */
23
/*! \brief character value */
24
char value[];
25
#elif defined(__GNUC__)
26
char value[0];
27
#else
28
/* Fallback to a hack */
29
char value[1];
30
#endif
31
};
32
33
static void
34
NameValueParserStartElt(void * d, const char * name, int l)
35
{
36
struct NameValueParserData * data = (struct NameValueParserData *)d;
37
data->topelt = 1;
38
if(l>63)
39
l = 63;
40
memcpy(data->curelt, name, l);
41
data->curelt[l] = '\0';
42
data->cdata = NULL;
43
data->cdatalen = 0;
44
}
45
46
static void
47
NameValueParserEndElt(void * d, const char * name, int namelen)
48
{
49
struct NameValueParserData * data = (struct NameValueParserData *)d;
50
struct NameValue * nv;
51
(void)name;
52
(void)namelen;
53
if(!data->topelt)
54
return;
55
if(strcmp(data->curelt, "NewPortListing") != 0)
56
{
57
int l;
58
/* standard case. Limited to n chars strings */
59
l = data->cdatalen;
60
nv = malloc(sizeof(struct NameValue) + l + 1);
61
if(nv == NULL)
62
{
63
/* malloc error */
64
#ifdef DEBUG
65
fprintf(stderr, "%s: error allocating memory",
66
"NameValueParserEndElt");
67
#endif /* DEBUG */
68
return;
69
}
70
strncpy(nv->name, data->curelt, 64);
71
nv->name[63] = '\0';
72
if(data->cdata != NULL)
73
{
74
memcpy(nv->value, data->cdata, l);
75
nv->value[l] = '\0';
76
}
77
else
78
{
79
nv->value[0] = '\0';
80
}
81
nv->l_next = data->l_head; /* insert in list */
82
data->l_head = nv;
83
}
84
data->cdata = NULL;
85
data->cdatalen = 0;
86
data->topelt = 0;
87
}
88
89
static void
90
NameValueParserGetData(void * d, const char * datas, int l)
91
{
92
struct NameValueParserData * data = (struct NameValueParserData *)d;
93
if(strcmp(data->curelt, "NewPortListing") == 0)
94
{
95
/* specific case for NewPortListing which is a XML Document */
96
free(data->portListing);
97
data->portListing = malloc(l + 1);
98
if(!data->portListing)
99
{
100
/* malloc error */
101
#ifdef DEBUG
102
fprintf(stderr, "%s: error allocating memory",
103
"NameValueParserGetData");
104
#endif /* DEBUG */
105
return;
106
}
107
memcpy(data->portListing, datas, l);
108
data->portListing[l] = '\0';
109
data->portListingLength = l;
110
}
111
else
112
{
113
/* standard case. */
114
data->cdata = datas;
115
data->cdatalen = l;
116
}
117
}
118
119
void
120
ParseNameValue(const char * buffer, int bufsize,
121
struct NameValueParserData * data)
122
{
123
struct xmlparser parser;
124
memset(data, 0, sizeof(struct NameValueParserData));
125
/* init xmlparser object */
126
parser.xmlstart = buffer;
127
parser.xmlsize = bufsize;
128
parser.data = data;
129
parser.starteltfunc = NameValueParserStartElt;
130
parser.endeltfunc = NameValueParserEndElt;
131
parser.datafunc = NameValueParserGetData;
132
parser.attfunc = 0;
133
parsexml(&parser);
134
}
135
136
void
137
ClearNameValueList(struct NameValueParserData * pdata)
138
{
139
struct NameValue * nv;
140
if(pdata->portListing)
141
{
142
free(pdata->portListing);
143
pdata->portListing = NULL;
144
pdata->portListingLength = 0;
145
}
146
while((nv = pdata->l_head) != NULL)
147
{
148
pdata->l_head = nv->l_next;
149
free(nv);
150
}
151
}
152
153
char *
154
GetValueFromNameValueList(struct NameValueParserData * pdata,
155
const char * name)
156
{
157
struct NameValue * nv;
158
char * p = NULL;
159
for(nv = pdata->l_head;
160
(nv != NULL) && (p == NULL);
161
nv = nv->l_next)
162
{
163
if(strcmp(nv->name, name) == 0)
164
p = nv->value;
165
}
166
return p;
167
}
168
169
/* debug all-in-one function
170
* do parsing then display to stdout */
171
#ifdef DEBUG
172
void
173
DisplayNameValueList(char * buffer, int bufsize)
174
{
175
struct NameValueParserData pdata;
176
struct NameValue * nv;
177
ParseNameValue(buffer, bufsize, &pdata);
178
for(nv = pdata.l_head;
179
nv != NULL;
180
nv = nv->l_next)
181
{
182
printf("%s = %s\n", nv->name, nv->value);
183
}
184
ClearNameValueList(&pdata);
185
}
186
#endif /* DEBUG */
187
188
189