<p>Sean Bright has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/13124">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res_calendar_exchange: Use libxml2 instead of libiksemel<br><br>Change-Id: I1ad47fdf13f4146996ac94be7181ee075d2480d8<br>---<br>M res/res_calendar_exchange.c<br>1 file changed, 65 insertions(+), 63 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/24/13124/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/res/res_calendar_exchange.c b/res/res_calendar_exchange.c</span><br><span>index d2edd01..b48023c 100644</span><br><span>--- a/res/res_calendar_exchange.c</span><br><span>+++ b/res/res_calendar_exchange.c</span><br><span>@@ -24,7 +24,6 @@</span><br><span> <depend>res_calendar</depend></span><br><span> <depend>neon</depend></span><br><span> <depend>ical</depend></span><br><span style="color: hsl(0, 100%, 40%);">- <depend>iksemel</depend></span><br><span> <support_level>core</support_level></span><br><span> ***/</span><br><span> </span><br><span>@@ -38,7 +37,7 @@</span><br><span> #include <ne_request.h></span><br><span> #include <ne_auth.h></span><br><span> #include <ne_redirect.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <iksemel.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <libxml/parser.h></span><br><span> </span><br><span> #include "asterisk/module.h"</span><br><span> #include "asterisk/channel.h"</span><br><span>@@ -82,61 +81,61 @@</span><br><span> struct exchangecal_pvt *pvt;</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int parse_tag(void *data, char *name, char **atts, int type)</span><br><span style="color: hsl(120, 100%, 40%);">+static void parse_start_tag(void *data,</span><br><span style="color: hsl(120, 100%, 40%);">+ const xmlChar *local_name,</span><br><span style="color: hsl(120, 100%, 40%);">+ const xmlChar *prefix,</span><br><span style="color: hsl(120, 100%, 40%);">+ const xmlChar *uri,</span><br><span style="color: hsl(120, 100%, 40%);">+ int nb_namespaces,</span><br><span style="color: hsl(120, 100%, 40%);">+ const xmlChar **namespaces,</span><br><span style="color: hsl(120, 100%, 40%);">+ int nb_attributes,</span><br><span style="color: hsl(120, 100%, 40%);">+ int nb_defaulted,</span><br><span style="color: hsl(120, 100%, 40%);">+ const xmlChar **attributes)</span><br><span> {</span><br><span> struct xmlstate *state = data;</span><br><span style="color: hsl(0, 100%, 40%);">- char *tmp;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if ((tmp = strchr(name, ':'))) {</span><br><span style="color: hsl(0, 100%, 40%);">- tmp++;</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- return IKS_HOOK;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_copy_string(state->tag, (char *) local_name, sizeof(state->tag));</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- ast_copy_string(state->tag, tmp, sizeof(state->tag));</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!strcasecmp(state->tag, "response")) {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_calendar_event *event;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- switch (type) {</span><br><span style="color: hsl(0, 100%, 40%);">- case IKS_OPEN:</span><br><span style="color: hsl(0, 100%, 40%);">- if (!strcasecmp(state->tag, "response")) {</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_calendar_event *event;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- state->in_response = 1;</span><br><span style="color: hsl(0, 100%, 40%);">- if (!(event = ast_calendar_event_alloc(state->pvt->owner))) {</span><br><span style="color: hsl(0, 100%, 40%);">- return IKS_NOMEM;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- state->ptr = event;</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (!strcasecmp(state->tag, "propstat")) {</span><br><span style="color: hsl(0, 100%, 40%);">- state->in_propstat = 1;</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (!strcasecmp(state->tag, "prop")) {</span><br><span style="color: hsl(0, 100%, 40%);">- state->in_prop = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ state->in_response = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!(event = ast_calendar_event_alloc(state->pvt->owner))) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(120, 100%, 40%);">+ state->ptr = event;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (!strcasecmp(state->tag, "propstat")) {</span><br><span style="color: hsl(120, 100%, 40%);">+ state->in_propstat = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (!strcasecmp(state->tag, "prop")) {</span><br><span style="color: hsl(120, 100%, 40%);">+ state->in_prop = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- case IKS_CLOSE:</span><br><span style="color: hsl(0, 100%, 40%);">- if (!strcasecmp(state->tag, "response")) {</span><br><span style="color: hsl(0, 100%, 40%);">- struct ao2_container *events = state->pvt->events;</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_calendar_event *event = state->ptr;</span><br><span style="color: hsl(120, 100%, 40%);">+static void parse_end_tag(void *data,</span><br><span style="color: hsl(120, 100%, 40%);">+ const xmlChar *local_name,</span><br><span style="color: hsl(120, 100%, 40%);">+ const xmlChar *prefix,</span><br><span style="color: hsl(120, 100%, 40%);">+ const xmlChar *uri)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct xmlstate *state = data;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- state->in_response = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_strlen_zero(event->uid)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "This event has no UID, something has gone wrong\n");</span><br><span style="color: hsl(0, 100%, 40%);">- event = ast_calendar_unref_event(event);</span><br><span style="color: hsl(0, 100%, 40%);">- return IKS_HOOK;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_link(events, event);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_copy_string(state->tag, (char *) local_name, sizeof(state->tag));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!strcasecmp(state->tag, "response")) {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ao2_container *events = state->pvt->events;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_calendar_event *event = state->ptr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ state->in_response = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ast_strlen_zero(event->uid)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(LOG_ERROR, "This event has no UID, something has gone wrong\n");</span><br><span> event = ast_calendar_unref_event(event);</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (!strcasecmp(state->tag, "propstat")) {</span><br><span style="color: hsl(0, 100%, 40%);">- state->in_propstat = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (!strcasecmp(state->tag, "prop")) {</span><br><span style="color: hsl(0, 100%, 40%);">- state->in_prop = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- default:</span><br><span style="color: hsl(0, 100%, 40%);">- return IKS_OK;</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_link(events, event);</span><br><span style="color: hsl(120, 100%, 40%);">+ event = ast_calendar_unref_event(event);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (!strcasecmp(state->tag, "propstat")) {</span><br><span style="color: hsl(120, 100%, 40%);">+ state->in_propstat = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (!strcasecmp(state->tag, "prop")) {</span><br><span style="color: hsl(120, 100%, 40%);">+ state->in_prop = 0;</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return IKS_OK;</span><br><span> }</span><br><span> </span><br><span> static time_t mstime_to_time_t(char *mstime)</span><br><span>@@ -170,28 +169,28 @@</span><br><span> }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int parse_cdata(void *data, char *value, size_t len)</span><br><span style="color: hsl(120, 100%, 40%);">+static void parse_cdata(void *data, const xmlChar *ch, int len)</span><br><span> {</span><br><span> char *str;</span><br><span style="color: hsl(120, 100%, 40%);">+ char *value = (char *) ch;</span><br><span> struct xmlstate *state = data;</span><br><span> struct ast_calendar_event *event = state->ptr;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ if (!state->in_response || !state->in_propstat || !state->in_prop) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* Check if we're empty */</span><br><span> str = ast_skip_blanks(value);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (str == value + len)</span><br><span style="color: hsl(0, 100%, 40%);">- return IKS_OK;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!(str = ast_calloc(1, len + 1))) {</span><br><span style="color: hsl(0, 100%, 40%);">- return IKS_NOMEM;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!*str) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">- memcpy(str, value, len);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!(state->in_response && state->in_propstat && state->in_prop)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_free(str);</span><br><span style="color: hsl(0, 100%, 40%);">- return IKS_OK;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ str = ast_strdup(value);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!str) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">- /* We use ast_string_field_build here because libiksemel is parsing CDATA with < as</span><br><span style="color: hsl(0, 100%, 40%);">- * new elements which is a bit odd and shouldn't happen */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> if (!strcasecmp(state->tag, "subject")) {</span><br><span> ast_string_field_build(event, summary, "%s%s", event->summary, str);</span><br><span> } else if (!strcasecmp(state->tag, "location")) {</span><br><span>@@ -215,7 +214,6 @@</span><br><span> }</span><br><span> </span><br><span> ast_free(str);</span><br><span style="color: hsl(0, 100%, 40%);">- return IKS_OK;</span><br><span> }</span><br><span> </span><br><span> static void exchangecal_destructor(void *obj)</span><br><span>@@ -581,7 +579,12 @@</span><br><span> struct timeval now = ast_tvnow();</span><br><span> time_t start, end;</span><br><span> struct ast_str *response;</span><br><span style="color: hsl(0, 100%, 40%);">- iksparser *p;</span><br><span style="color: hsl(120, 100%, 40%);">+ xmlSAXHandler sax = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .initialized = XML_SAX2_MAGIC,</span><br><span style="color: hsl(120, 100%, 40%);">+ .startElementNs = parse_start_tag,</span><br><span style="color: hsl(120, 100%, 40%);">+ .endElementNs = parse_end_tag,</span><br><span style="color: hsl(120, 100%, 40%);">+ .characters = parse_cdata,</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span> </span><br><span> state.pvt = pvt;</span><br><span> start = now.tv_sec;</span><br><span>@@ -590,8 +593,7 @@</span><br><span> return -1;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- p = iks_sax_new(&state, parse_tag, parse_cdata);</span><br><span style="color: hsl(0, 100%, 40%);">- iks_parse(p, ast_str_buffer(response), ast_str_strlen(response), 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ xmlSAXUserParseMemory(&sax, &state, ast_str_buffer(response), ast_str_strlen(response));</span><br><span> ast_calendar_merge_events(pvt->owner, pvt->events);</span><br><span> ast_free(response);</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/13124">change 13124</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/13124"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 13 </div>
<div style="display:none"> Gerrit-Change-Id: I1ad47fdf13f4146996ac94be7181ee075d2480d8 </div>
<div style="display:none"> Gerrit-Change-Number: 13124 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Sean Bright <sean.bright@gmail.com> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>