aboutsummaryrefslogtreecommitdiff
path: root/dev-libs/libstrophe/files/libstrophe-xml-escape.patch
diff options
context:
space:
mode:
Diffstat (limited to 'dev-libs/libstrophe/files/libstrophe-xml-escape.patch')
-rw-r--r--dev-libs/libstrophe/files/libstrophe-xml-escape.patch121
1 files changed, 121 insertions, 0 deletions
diff --git a/dev-libs/libstrophe/files/libstrophe-xml-escape.patch b/dev-libs/libstrophe/files/libstrophe-xml-escape.patch
new file mode 100644
index 0000000..4b97099
--- /dev/null
+++ b/dev-libs/libstrophe/files/libstrophe-xml-escape.patch
@@ -0,0 +1,121 @@
+commit c0b1e5b7fe51c6b7018116d96ea98b7912374385
+Author: Alexandre Erwin Ittner <alexandre@ittner.com.br>
+Date: Sun Sep 23 17:18:53 2012 -0300
+
+ Fix escaping of XML text and attributes
+
+ There was a bug in xmpp_send which caused XML special characters to be
+ sent to the server verbatim, implying in invalid stanzas and making the
+ server drop the connection. This commit fixed the bug escaping such
+ characters with the usual rules.
+
+ Bugs: The code now do several (de)allocation operations in every send,
+ this may have a negative effect on performance when used with slow
+ memory managers.
+
+ License: This code is distributed under the same license used by strophe
+ (i.e., GPLv3 or MIT).
+
+diff --git a/src/stanza.c b/src/stanza.c
+index 6bf11b8..4ecc558 100644
+--- a/src/stanza.c
++++ b/src/stanza.c
+@@ -206,6 +206,64 @@ int xmpp_stanza_is_tag(xmpp_stanza_t * const stanza)
+ return (stanza && stanza->type == XMPP_STANZA_TAG);
+ }
+
++/* Escape a string with for use in a XML text node or attribute. Assumes that
++ * the input string is encoded in UTF-8. On sucess, returns a pointer to a
++ * buffer with the resulting data which must be xmpp_free()'d by the caller.
++ * On failure, returns NULL.
++ */
++
++static char *_escape_xml(xmpp_ctx_t * const ctx, char *text)
++{
++ size_t len = 0;
++ char *src;
++ char *dst;
++ char *buf;
++ for (src = text; *src != '\0'; src++) {
++ switch (*src) {
++ case '<': /* "&lt;" */
++ case '>': /* "&gt;" */
++ len += 4;
++ break;
++ case '&': /* "&amp;" */
++ len += 5;
++ break;
++ case '"':
++ len += 6; /*"&quot;" */
++ break;
++ default:
++ len++;
++ }
++ }
++ if ((buf = xmpp_alloc(ctx, (len+1) * sizeof(char))) == NULL)
++ return NULL; /* Error */
++ dst = buf;
++ for (src = text; *src != '\0'; src++) {
++ switch (*src) {
++ case '<':
++ strcpy(dst, "&lt;");
++ dst += 4;
++ break;
++ case '>':
++ strcpy(dst, "&gt;");
++ dst += 4;
++ break;
++ case '&':
++ strcpy(dst, "&amp;");
++ dst += 5;
++ break;
++ case '"':
++ strcpy(dst, "&quot;");
++ dst += 6;
++ break;
++ default:
++ *dst = *src;
++ dst++;
++ }
++ }
++ *dst = '\0';
++ return buf;
++}
++
+ /* small helper function */
+ static inline void _render_update(int *written, const int length,
+ const int lastwrite,
+@@ -236,6 +294,7 @@ static int _render_stanza_recursive(xmpp_stanza_t *stanza,
+ xmpp_stanza_t *child;
+ hash_iterator_t *iter;
+ const char *key;
++ char *tmp;
+
+ written = 0;
+
+@@ -244,7 +303,10 @@ static int _render_stanza_recursive(xmpp_stanza_t *stanza,
+ if (stanza->type == XMPP_STANZA_TEXT) {
+ if (!stanza->data) return XMPP_EINVOP;
+
+- ret = xmpp_snprintf(ptr, left, "%s", stanza->data);
++ tmp = _escape_xml(stanza->ctx, stanza->data);
++ if (tmp == NULL) return XMPP_EMEM;
++ ret = xmpp_snprintf(ptr, left, "%s", tmp);
++ xmpp_free(stanza->ctx, tmp);
+ if (ret < 0) return XMPP_EMEM;
+ _render_update(&written, buflen, ret, &left, &ptr);
+ } else { /* stanza->type == XMPP_STANZA_TAG */
+@@ -258,8 +320,11 @@ static int _render_stanza_recursive(xmpp_stanza_t *stanza,
+ if (stanza->attributes && hash_num_keys(stanza->attributes) > 0) {
+ iter = hash_iter_new(stanza->attributes);
+ while ((key = hash_iter_next(iter))) {
+- ret = xmpp_snprintf(ptr, left, " %s=\"%s\"", key,
+- (char *)hash_get(stanza->attributes, key));
++ tmp = _escape_xml(stanza->ctx,
++ (char *)hash_get(stanza->attributes, key));
++ if (tmp == NULL) return XMPP_EMEM;
++ ret = xmpp_snprintf(ptr, left, " %s=\"%s\"", key, tmp);
++ xmpp_free(stanza->ctx, tmp);
+ if (ret < 0) return XMPP_EMEM;
+ _render_update(&written, buflen, ret, &left, &ptr);
+ }