[CVE-2022-23308] Use-after-free of ID and IDREF attributes
[platform/upstream/gettext.git] / packaging / CVE-2022-23308.patch
1 diff --git a/gettext-tools/gnulib-lib/libxml/valid.c b/gettext-tools/gnulib-lib/libxml/valid.c
2 index 22ade700..182c9d5c 100644
3 --- a/gettext-tools/gnulib-lib/libxml/valid.c
4 +++ b/gettext-tools/gnulib-lib/libxml/valid.c
5 @@ -936,6 +936,36 @@ xmlFreeValidCtxt(xmlValidCtxtPtr cur) {
6  
7  #endif /* LIBXML_VALID_ENABLED */
8  
9 +/**
10 + * xmlValidNormalizeString:
11 + * @str: a string
12 + *
13 + * Normalize a string in-place.
14 + */
15 +static void
16 +xmlValidNormalizeString(xmlChar *str) {
17 +    xmlChar *dst;
18 +    const xmlChar *src;
19 +
20 +    if (str == NULL)
21 +        return;
22 +    src = str;
23 +    dst = str;
24 +
25 +    while (*src == 0x20) src++;
26 +    while (*src != 0) {
27 +       if (*src == 0x20) {
28 +           while (*src == 0x20) src++;
29 +           if (*src != 0)
30 +               *dst++ = 0x20;
31 +       } else {
32 +           *dst++ = *src++;
33 +       }
34 +    }
35 +    *dst = 0;
36 +}
37 +
38 +
39  /**
40   * xmlNewDocElementContent:
41   * @doc:  the document
42 @@ -2593,6 +2623,24 @@ xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) {
43             (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))  \
44             xmlFree((char *)(str));
45  
46 +static int
47 +xmlIsStreaming(xmlValidCtxtPtr ctxt) {
48 +    xmlParserCtxtPtr pctxt;
49 +
50 +    if (ctxt == NULL)
51 +        return(0);
52 +    /*
53 +     * These magic values are also abused to detect whether we're validating
54 +     * while parsing a document. In this case, userData points to the parser
55 +     * context.
56 +     */
57 +    if ((ctxt->finishDtd != XML_CTXT_FINISH_DTD_0) &&
58 +        (ctxt->finishDtd != XML_CTXT_FINISH_DTD_1))
59 +        return(0);
60 +    pctxt = ctxt->userData;
61 +    return(pctxt->parseMode == XML_PARSE_READER);
62 +}
63 +
64  /**
65   * xmlFreeID:
66   * @not:  A id
67 @@ -2636,7 +2684,7 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
68      if (doc == NULL) {
69         return(NULL);
70      }
71 -    if (value == NULL) {
72 +    if ((value == NULL) || (value[0] == 0)) {
73         return(NULL);
74      }
75      if (attr == NULL) {
76 @@ -2667,7 +2715,7 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
77       */
78      ret->value = xmlStrdup(value);
79      ret->doc = doc;
80 -    if ((ctxt != NULL) && (ctxt->vstateNr != 0)) {
81 +    if (xmlIsStreaming(ctxt)) {
82         /*
83          * Operating in streaming mode, attr is gonna disapear
84          */
85 @@ -2806,6 +2854,7 @@ xmlRemoveID(xmlDocPtr doc, xmlAttrPtr attr) {
86      ID = xmlNodeListGetString(doc, attr->children, 1);
87      if (ID == NULL)
88          return(-1);
89 +    xmlValidNormalizeString(ID);
90  
91      id = xmlHashLookup(table, ID);
92      if (id == NULL || id->attr != attr) {
93 @@ -2995,7 +3044,7 @@ xmlAddRef(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
94       * fill the structure.
95       */
96      ret->value = xmlStrdup(value);
97 -    if ((ctxt != NULL) && (ctxt->vstateNr != 0)) {
98 +    if (xmlIsStreaming(ctxt)) {
99         /*
100          * Operating in streaming mode, attr is gonna disapear
101          */
102 @@ -4014,8 +4063,7 @@ xmlValidateAttributeValue2(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
103  xmlChar *
104  xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
105              xmlNodePtr elem, const xmlChar *name, const xmlChar *value) {
106 -    xmlChar *ret, *dst;
107 -    const xmlChar *src;
108 +    xmlChar *ret;
109      xmlAttributePtr attrDecl = NULL;
110      int extsubset = 0;
111  
112 @@ -4056,19 +4104,7 @@ xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
113      ret = xmlStrdup(value);
114      if (ret == NULL)
115         return(NULL);
116 -    src = value;
117 -    dst = ret;
118 -    while (*src == 0x20) src++;
119 -    while (*src != 0) {
120 -       if (*src == 0x20) {
121 -           while (*src == 0x20) src++;
122 -           if (*src != 0)
123 -               *dst++ = 0x20;
124 -       } else {
125 -           *dst++ = *src++;
126 -       }
127 -    }
128 -    *dst = 0;
129 +    xmlValidNormalizeString(ret);
130      if ((doc->standalone) && (extsubset == 1) && (!xmlStrEqual(value, ret))) {
131         xmlErrValidNode(ctxt, elem, XML_DTD_NOT_STANDALONE,
132  "standalone: %s on %s value had to be normalized based on external subset declaration\n",
133 @@ -4100,8 +4136,7 @@ xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
134  xmlChar *
135  xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem,
136                                 const xmlChar *name, const xmlChar *value) {
137 -    xmlChar *ret, *dst;
138 -    const xmlChar *src;
139 +    xmlChar *ret;
140      xmlAttributePtr attrDecl = NULL;
141  
142      if (doc == NULL) return(NULL);
143 @@ -4131,19 +4166,7 @@ xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem,
144      ret = xmlStrdup(value);
145      if (ret == NULL)
146         return(NULL);
147 -    src = value;
148 -    dst = ret;
149 -    while (*src == 0x20) src++;
150 -    while (*src != 0) {
151 -       if (*src == 0x20) {
152 -           while (*src == 0x20) src++;
153 -           if (*src != 0)
154 -               *dst++ = 0x20;
155 -       } else {
156 -           *dst++ = *src++;
157 -       }
158 -    }
159 -    *dst = 0;
160 +    xmlValidNormalizeString(ret);
161      return(ret);
162  }
163  
164 diff --git a/gnulib-local/lib/libxml/valid.c b/gnulib-local/lib/libxml/valid.c
165 index 22ade700..85b67bc1 100644
166 --- a/gnulib-local/lib/libxml/valid.c
167 +++ b/gnulib-local/lib/libxml/valid.c
168 @@ -936,6 +936,35 @@ xmlFreeValidCtxt(xmlValidCtxtPtr cur) {
169  
170  #endif /* LIBXML_VALID_ENABLED */
171  
172 +/**
173 + * xmlValidNormalizeString:
174 + * @str: a string
175 + *
176 + * Normalize a string in-place.
177 + */
178 +static void
179 +xmlValidNormalizeString(xmlChar *str) {
180 +    xmlChar *dst;
181 +    const xmlChar *src;
182 +
183 +    if (str == NULL)
184 +        return;
185 +    src = str;
186 +    dst = str;
187 +
188 +    while (*src == 0x20) src++;
189 +    while (*src != 0) {
190 +       if (*src == 0x20) {
191 +           while (*src == 0x20) src++;
192 +           if (*src != 0)
193 +               *dst++ = 0x20;
194 +       } else {
195 +           *dst++ = *src++;
196 +       }
197 +    }
198 +    *dst = 0;
199 +}
200 +
201  /**
202   * xmlNewDocElementContent:
203   * @doc:  the document
204 @@ -2593,6 +2622,24 @@ xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) {
205             (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))  \
206             xmlFree((char *)(str));
207  
208 +static int
209 +xmlIsStreaming(xmlValidCtxtPtr ctxt) {
210 +    xmlParserCtxtPtr pctxt;
211 +
212 +    if (ctxt == NULL)
213 +        return(0);
214 +    /*
215 +     * These magic values are also abused to detect whether we're validating
216 +     * while parsing a document. In this case, userData points to the parser
217 +     * context.
218 +     */
219 +    if ((ctxt->finishDtd != XML_CTXT_FINISH_DTD_0) &&
220 +        (ctxt->finishDtd != XML_CTXT_FINISH_DTD_1))
221 +        return(0);
222 +    pctxt = ctxt->userData;
223 +    return(pctxt->parseMode == XML_PARSE_READER);
224 +}
225 +
226  /**
227   * xmlFreeID:
228   * @not:  A id
229 @@ -2636,7 +2683,7 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
230      if (doc == NULL) {
231         return(NULL);
232      }
233 -    if (value == NULL) {
234 +    if ((value == NULL) || (value[0] == 0)) {
235         return(NULL);
236      }
237      if (attr == NULL) {
238 @@ -2667,7 +2714,7 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
239       */
240      ret->value = xmlStrdup(value);
241      ret->doc = doc;
242 -    if ((ctxt != NULL) && (ctxt->vstateNr != 0)) {
243 +    if (xmlIsStreaming(ctxt)) {
244         /*
245          * Operating in streaming mode, attr is gonna disapear
246          */
247 @@ -2806,6 +2853,7 @@ xmlRemoveID(xmlDocPtr doc, xmlAttrPtr attr) {
248      ID = xmlNodeListGetString(doc, attr->children, 1);
249      if (ID == NULL)
250          return(-1);
251 +    xmlValidNormalizeString(ID);
252  
253      id = xmlHashLookup(table, ID);
254      if (id == NULL || id->attr != attr) {
255 @@ -2995,7 +3043,7 @@ xmlAddRef(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
256       * fill the structure.
257       */
258      ret->value = xmlStrdup(value);
259 -    if ((ctxt != NULL) && (ctxt->vstateNr != 0)) {
260 +    if (xmlIsStreaming(ctxt)) {
261         /*
262          * Operating in streaming mode, attr is gonna disapear
263          */
264 @@ -4014,8 +4062,7 @@ xmlValidateAttributeValue2(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
265  xmlChar *
266  xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
267              xmlNodePtr elem, const xmlChar *name, const xmlChar *value) {
268 -    xmlChar *ret, *dst;
269 -    const xmlChar *src;
270 +    xmlChar *ret;
271      xmlAttributePtr attrDecl = NULL;
272      int extsubset = 0;
273  
274 @@ -4056,19 +4103,7 @@ xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
275      ret = xmlStrdup(value);
276      if (ret == NULL)
277         return(NULL);
278 -    src = value;
279 -    dst = ret;
280 -    while (*src == 0x20) src++;
281 -    while (*src != 0) {
282 -       if (*src == 0x20) {
283 -           while (*src == 0x20) src++;
284 -           if (*src != 0)
285 -               *dst++ = 0x20;
286 -       } else {
287 -           *dst++ = *src++;
288 -       }
289 -    }
290 -    *dst = 0;
291 +    xmlValidNormalizeString(ret);
292      if ((doc->standalone) && (extsubset == 1) && (!xmlStrEqual(value, ret))) {
293         xmlErrValidNode(ctxt, elem, XML_DTD_NOT_STANDALONE,
294  "standalone: %s on %s value had to be normalized based on external subset declaration\n",
295 @@ -4100,8 +4135,7 @@ xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
296  xmlChar *
297  xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem,
298                                 const xmlChar *name, const xmlChar *value) {
299 -    xmlChar *ret, *dst;
300 -    const xmlChar *src;
301 +    xmlChar *ret;
302      xmlAttributePtr attrDecl = NULL;
303  
304      if (doc == NULL) return(NULL);
305 @@ -4131,19 +4165,7 @@ xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem,
306      ret = xmlStrdup(value);
307      if (ret == NULL)
308         return(NULL);
309 -    src = value;
310 -    dst = ret;
311 -    while (*src == 0x20) src++;
312 -    while (*src != 0) {
313 -       if (*src == 0x20) {
314 -           while (*src == 0x20) src++;
315 -           if (*src != 0)
316 -               *dst++ = 0x20;
317 -       } else {
318 -           *dst++ = *src++;
319 -       }
320 -    }
321 -    *dst = 0;
322 +    xmlValidNormalizeString(ret);
323      return(ret);
324  }
325  
326 diff --git a/libtextstyle/lib/libxml/valid.c b/libtextstyle/lib/libxml/valid.c
327 index 22ade700..182c9d5c 100644
328 --- a/libtextstyle/lib/libxml/valid.c
329 +++ b/libtextstyle/lib/libxml/valid.c
330 @@ -936,6 +936,36 @@ xmlFreeValidCtxt(xmlValidCtxtPtr cur) {
331  
332  #endif /* LIBXML_VALID_ENABLED */
333  
334 +/**
335 + * xmlValidNormalizeString:
336 + * @str: a string
337 + *
338 + * Normalize a string in-place.
339 + */
340 +static void
341 +xmlValidNormalizeString(xmlChar *str) {
342 +    xmlChar *dst;
343 +    const xmlChar *src;
344 +
345 +    if (str == NULL)
346 +        return;
347 +    src = str;
348 +    dst = str;
349 +
350 +    while (*src == 0x20) src++;
351 +    while (*src != 0) {
352 +       if (*src == 0x20) {
353 +           while (*src == 0x20) src++;
354 +           if (*src != 0)
355 +               *dst++ = 0x20;
356 +       } else {
357 +           *dst++ = *src++;
358 +       }
359 +    }
360 +    *dst = 0;
361 +}
362 +
363 +
364  /**
365   * xmlNewDocElementContent:
366   * @doc:  the document
367 @@ -2593,6 +2623,24 @@ xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) {
368             (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))  \
369             xmlFree((char *)(str));
370  
371 +static int
372 +xmlIsStreaming(xmlValidCtxtPtr ctxt) {
373 +    xmlParserCtxtPtr pctxt;
374 +
375 +    if (ctxt == NULL)
376 +        return(0);
377 +    /*
378 +     * These magic values are also abused to detect whether we're validating
379 +     * while parsing a document. In this case, userData points to the parser
380 +     * context.
381 +     */
382 +    if ((ctxt->finishDtd != XML_CTXT_FINISH_DTD_0) &&
383 +        (ctxt->finishDtd != XML_CTXT_FINISH_DTD_1))
384 +        return(0);
385 +    pctxt = ctxt->userData;
386 +    return(pctxt->parseMode == XML_PARSE_READER);
387 +}
388 +
389  /**
390   * xmlFreeID:
391   * @not:  A id
392 @@ -2636,7 +2684,7 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
393      if (doc == NULL) {
394         return(NULL);
395      }
396 -    if (value == NULL) {
397 +    if ((value == NULL) || (value[0] == 0)) {
398         return(NULL);
399      }
400      if (attr == NULL) {
401 @@ -2667,7 +2715,7 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
402       */
403      ret->value = xmlStrdup(value);
404      ret->doc = doc;
405 -    if ((ctxt != NULL) && (ctxt->vstateNr != 0)) {
406 +    if (xmlIsStreaming(ctxt)) {
407         /*
408          * Operating in streaming mode, attr is gonna disapear
409          */
410 @@ -2806,6 +2854,7 @@ xmlRemoveID(xmlDocPtr doc, xmlAttrPtr attr) {
411      ID = xmlNodeListGetString(doc, attr->children, 1);
412      if (ID == NULL)
413          return(-1);
414 +    xmlValidNormalizeString(ID);
415  
416      id = xmlHashLookup(table, ID);
417      if (id == NULL || id->attr != attr) {
418 @@ -2995,7 +3044,7 @@ xmlAddRef(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
419       * fill the structure.
420       */
421      ret->value = xmlStrdup(value);
422 -    if ((ctxt != NULL) && (ctxt->vstateNr != 0)) {
423 +    if (xmlIsStreaming(ctxt)) {
424         /*
425          * Operating in streaming mode, attr is gonna disapear
426          */
427 @@ -4014,8 +4063,7 @@ xmlValidateAttributeValue2(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
428  xmlChar *
429  xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
430              xmlNodePtr elem, const xmlChar *name, const xmlChar *value) {
431 -    xmlChar *ret, *dst;
432 -    const xmlChar *src;
433 +    xmlChar *ret;
434      xmlAttributePtr attrDecl = NULL;
435      int extsubset = 0;
436  
437 @@ -4056,19 +4104,7 @@ xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
438      ret = xmlStrdup(value);
439      if (ret == NULL)
440         return(NULL);
441 -    src = value;
442 -    dst = ret;
443 -    while (*src == 0x20) src++;
444 -    while (*src != 0) {
445 -       if (*src == 0x20) {
446 -           while (*src == 0x20) src++;
447 -           if (*src != 0)
448 -               *dst++ = 0x20;
449 -       } else {
450 -           *dst++ = *src++;
451 -       }
452 -    }
453 -    *dst = 0;
454 +    xmlValidNormalizeString(ret);
455      if ((doc->standalone) && (extsubset == 1) && (!xmlStrEqual(value, ret))) {
456         xmlErrValidNode(ctxt, elem, XML_DTD_NOT_STANDALONE,
457  "standalone: %s on %s value had to be normalized based on external subset declaration\n",
458 @@ -4100,8 +4136,7 @@ xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
459  xmlChar *
460  xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem,
461                                 const xmlChar *name, const xmlChar *value) {
462 -    xmlChar *ret, *dst;
463 -    const xmlChar *src;
464 +    xmlChar *ret;
465      xmlAttributePtr attrDecl = NULL;
466  
467      if (doc == NULL) return(NULL);
468 @@ -4131,19 +4166,7 @@ xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem,
469      ret = xmlStrdup(value);
470      if (ret == NULL)
471         return(NULL);
472 -    src = value;
473 -    dst = ret;
474 -    while (*src == 0x20) src++;
475 -    while (*src != 0) {
476 -       if (*src == 0x20) {
477 -           while (*src == 0x20) src++;
478 -           if (*src != 0)
479 -               *dst++ = 0x20;
480 -       } else {
481 -           *dst++ = *src++;
482 -       }
483 -    }
484 -    *dst = 0;
485 +    xmlValidNormalizeString(ret);
486      return(ret);
487  }
488