From b408cbf224ebc6f54804886252f1b966dc4a4673 Mon Sep 17 00:00:00 2001 From: LDA Date: Wed, 19 Jun 2024 02:33:53 +0200 Subject: [PATCH] [ADD] Make and start using an XML encoder Now, we have basic sanitation!!!!!! --- src/Main.c | 7 ++-- src/XML/Parser.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++ src/XMPP/Stanza.c | 38 +++++++++++++--------- src/XMPPThread.c | 1 + 4 files changed, 110 insertions(+), 19 deletions(-) diff --git a/src/Main.c b/src/Main.c index 929f80b..aaf6144 100644 --- a/src/Main.c +++ b/src/Main.c @@ -47,12 +47,14 @@ Main(void) ParseeConfigLoad("parsee.json"); ParseeConfigInit(); + /* Write out the config file to a YAML document */ yaml = StreamOpen("parsee.yaml", "w"); ParseeExportConfigYAML(yaml); StreamClose(yaml); parsee_conf = ParseeConfigGet(); { + Log(LOG_NOTICE, "Connecting to XMPP..."); jabber = XMPPInitialiseCompStream( parsee_conf->component_host, parsee_conf->component_port @@ -63,6 +65,7 @@ Main(void) ); } + Log(LOG_NOTICE, "Setting up local Matrix user..."); ASRegisterUser(parsee_conf, parsee_conf->sender_localpart); memset(&conf, 0, sizeof(conf)); @@ -72,6 +75,7 @@ Main(void) conf.handlerArgs = ParseeInitData(jabber); conf.handler = ParseeRequest; + Log(LOG_NOTICE, "Creating XMPP listener thread..."); if (pthread_create(&xmpp_thr, NULL, ParseeXMPPThread, conf.handlerArgs)) { Log(LOG_ERR, "Couldn't start XMPP listener thread."); @@ -99,11 +103,8 @@ Main(void) #undef SIGACTION - /* TODO: The rest of Parsee. */ server = HttpServerCreate(&conf); HttpServerStart(server); - - /* TODO: Manage signals(^C) with finesse */ HttpServerJoin(server); HttpServerFree(server); diff --git a/src/XML/Parser.c b/src/XML/Parser.c index 99405b8..f120459 100644 --- a/src/XML/Parser.c +++ b/src/XML/Parser.c @@ -1,5 +1,7 @@ #include +#include + XMLElement * XMLDecode(Stream *stream, bool autofree) { @@ -88,9 +90,90 @@ XMLDecode(Stream *stream, bool autofree) return ret; } +void +XMLEncodeString(Stream *stream, char *data) +{ + size_t i; + + for (i = 0; i < strlen(data); i++) + { + char c = data[i]; + if (c == '<') + { + StreamPrintf(stream, "<"); + continue; + } + else if (c == '>') + { + StreamPrintf(stream, ">"); + continue; + } + else if (c == '&') + { + StreamPrintf(stream, "&"); + continue; + } + else if (c == '\'') + { + StreamPrintf(stream, "'"); + continue; + } + else if (c == '"') + { + StreamPrintf(stream, """); + continue; + } + StreamPrintf(stream, "%c", c); + } +} +void +XMLEncodeTag(Stream *stream, XMLElement *element) +{ + char *key, *val; + + StreamPrintf(stream, "<%s", element->name); + while (HashMapIterate(element->attrs, &key, (void **) &val)) + { + StreamPrintf(stream, " %s='", key); + XMLEncodeString(stream, val); + StreamPrintf(stream, "'"); + + } + if (ArraySize(element->children)) + { + size_t i; + XMLElement *child; + + StreamPrintf(stream, ">", key, val); + for (i = 0; i < ArraySize(element->children); i++) + { + child = ArrayGet(element->children, i); + XMLEncode(stream, child); + } + StreamPrintf(stream, "", element->name); + return; + } + StreamPrintf(stream, "/>"); +} void XMLEncode(Stream *stream, XMLElement *element) { /* TODO: Write the entire XML element. This shouldn't be * too hard. */ + if (!stream || !element) + { + return; + } + switch (element->type) + { + case XML_ELEMENT_TAG: + XMLEncodeTag(stream, element); + return; + case XML_ELEMENT_DATA: + XMLEncodeString(stream, element->data); + return; + default: + /* TODO */ + break; + } } diff --git a/src/XMPP/Stanza.c b/src/XMPP/Stanza.c index 38357c6..1a1afee 100644 --- a/src/XMPP/Stanza.c +++ b/src/XMPP/Stanza.c @@ -1,29 +1,35 @@ #include +#include +#include + +#include + void XMPPSendPlain(XMPPComponent *comp, char *fr, char *to, char *msg, char *type) { + XMLElement *message, *body, *data; + char *from; if (!comp || !fr || !to || !msg) { return; } - StreamPrintf( - comp->stream, "host, to - ); - if (type) - { - StreamPrintf(comp->stream, " type='%s'", type); - } - StreamPrintf(comp->stream, ">"); - StreamPrintf(comp->stream, - "" - "%s" - "" - "", - msg - ); + + message = XMLCreateTag("message"); + XMLAddAttr(message, "from", (from = StrConcat(3, fr, "@", comp->host))); + XMLAddAttr(message, "to", to); + XMLAddAttr(message, "type", type); + + body = XMLCreateTag("body"); + data = XMLCreateText(msg); + + XMLAddChild(message, body); + XMLAddChild(body, data); + + XMLEncode(comp->stream, message); StreamFlush(comp->stream); + XMLFreeElement(message); + Free(from); } void XMPPSendPresence(XMPPComponent *comp, char *fr, char *to) diff --git a/src/XMPPThread.c b/src/XMPPThread.c index a98b12f..0b4b969 100644 --- a/src/XMPPThread.c +++ b/src/XMPPThread.c @@ -31,6 +31,7 @@ ParseeXMPPThread(void *argp) { continue; } + if (StrEquals(stanza->name, "message")) { size_t i;