<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 &lt; 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>