Merge branch 'mh/unify-xml-in-imap-send-and-http-push'
authorJunio C Hamano <gitster@pobox.com>
Sun, 6 Jan 2013 07:41:04 +0000 (23:41 -0800)
committerJunio C Hamano <gitster@pobox.com>
Sun, 6 Jan 2013 07:41:04 +0000 (23:41 -0800)
Update imap-send to reuse xml quoting code from http-push codepath,
clean up some code, and fix a small bug.

* mh/unify-xml-in-imap-send-and-http-push:
wrap_in_html(): process message in bulk rather than line-by-line
wrap_in_html(): use strbuf_addstr_xml_quoted()
imap-send: change msg_data from storing (ptr, len) to storing strbuf
imap-send: correctly report errors reading from stdin
imap-send: store all_msgs as a strbuf
lf_to_crlf(): NUL-terminate msg_data::data
xml_entities(): use function strbuf_addstr_xml_quoted()
Add new function strbuf_add_xml_quoted()

1  2 
strbuf.c
strbuf.h
diff --combined strbuf.c
index 05d0693eba1eba4e2f21057388368c0890e668fe,41828f05d81d6c1e42834be8c092d05dd52367e8..9a373bef70b7fdd434c02d1ca753fcc8f799ecc2
+++ b/strbuf.c
@@@ -44,9 -44,7 +44,9 @@@ void strbuf_release(struct strbuf *sb
  
  char *strbuf_detach(struct strbuf *sb, size_t *sz)
  {
 -      char *res = sb->alloc ? sb->buf : NULL;
 +      char *res;
 +      strbuf_grow(sb, 0);
 +      res = sb->buf;
        if (sz)
                *sz = sb->len;
        strbuf_init(sb, 0);
@@@ -106,30 -104,35 +106,30 @@@ void strbuf_ltrim(struct strbuf *sb
        sb->buf[sb->len] = '\0';
  }
  
 -struct strbuf **strbuf_split_buf(const char *str, size_t slen, int delim, int max)
 +struct strbuf **strbuf_split_buf(const char *str, size_t slen,
 +                               int terminator, int max)
  {
 -      int alloc = 2, pos = 0;
 -      const char *n, *p;
 -      struct strbuf **ret;
 +      struct strbuf **ret = NULL;
 +      size_t nr = 0, alloc = 0;
        struct strbuf *t;
  
 -      ret = xcalloc(alloc, sizeof(struct strbuf *));
 -      p = n = str;
 -      while (n < str + slen) {
 -              int len;
 -              if (max <= 0 || pos + 1 < max)
 -                      n = memchr(n, delim, slen - (n - str));
 -              else
 -                      n = NULL;
 -              if (pos + 1 >= alloc) {
 -                      alloc = alloc * 2;
 -                      ret = xrealloc(ret, sizeof(struct strbuf *) * alloc);
 +      while (slen) {
 +              int len = slen;
 +              if (max <= 0 || nr + 1 < max) {
 +                      const char *end = memchr(str, terminator, slen);
 +                      if (end)
 +                              len = end - str + 1;
                }
 -              if (!n)
 -                      n = str + slen - 1;
 -              len = n - p + 1;
                t = xmalloc(sizeof(struct strbuf));
                strbuf_init(t, len);
 -              strbuf_add(t, p, len);
 -              ret[pos] = t;
 -              ret[++pos] = NULL;
 -              p = ++n;
 +              strbuf_add(t, str, len);
 +              ALLOC_GROW(ret, nr + 2, alloc);
 +              ret[nr++] = t;
 +              str += len;
 +              slen -= len;
        }
 +      ALLOC_GROW(ret, nr + 1, alloc); /* In case string was empty */
 +      ret[nr] = NULL;
        return ret;
  }
  
@@@ -425,6 -428,32 +425,32 @@@ void strbuf_add_lines(struct strbuf *ou
        strbuf_complete_line(out);
  }
  
+ void strbuf_addstr_xml_quoted(struct strbuf *buf, const char *s)
+ {
+       while (*s) {
+               size_t len = strcspn(s, "\"<>&");
+               strbuf_add(buf, s, len);
+               s += len;
+               switch (*s) {
+               case '"':
+                       strbuf_addstr(buf, "&quot;");
+                       break;
+               case '<':
+                       strbuf_addstr(buf, "&lt;");
+                       break;
+               case '>':
+                       strbuf_addstr(buf, "&gt;");
+                       break;
+               case '&':
+                       strbuf_addstr(buf, "&amp;");
+                       break;
+               case 0:
+                       return;
+               }
+               s++;
+       }
+ }
  static int is_rfc3986_reserved(char ch)
  {
        switch (ch) {
diff --combined strbuf.h
index aa386c6074ec0006acbd1067b561a9b2695e29f0,65aa2a032f6e8ef89dad51173085c7380c15bef0..ecae4e215f6377702c2b33e78ca1a0e454ebd819
+++ b/strbuf.h
@@@ -44,56 -44,22 +44,56 @@@ extern void strbuf_rtrim(struct strbuf 
  extern void strbuf_ltrim(struct strbuf *);
  extern int strbuf_cmp(const struct strbuf *, const struct strbuf *);
  
 +/*
 + * Split str (of length slen) at the specified terminator character.
 + * Return a null-terminated array of pointers to strbuf objects
 + * holding the substrings.  The substrings include the terminator,
 + * except for the last substring, which might be unterminated if the
 + * original string did not end with a terminator.  If max is positive,
 + * then split the string into at most max substrings (with the last
 + * substring containing everything following the (max-1)th terminator
 + * character).
 + *
 + * For lighter-weight alternatives, see string_list_split() and
 + * string_list_split_in_place().
 + */
  extern struct strbuf **strbuf_split_buf(const char *, size_t,
 -                                      int delim, int max);
 +                                      int terminator, int max);
 +
 +/*
 + * Split a NUL-terminated string at the specified terminator
 + * character.  See strbuf_split_buf() for more information.
 + */
  static inline struct strbuf **strbuf_split_str(const char *str,
 -                                             int delim, int max)
 +                                             int terminator, int max)
  {
 -      return strbuf_split_buf(str, strlen(str), delim, max);
 +      return strbuf_split_buf(str, strlen(str), terminator, max);
  }
 +
 +/*
 + * Split a strbuf at the specified terminator character.  See
 + * strbuf_split_buf() for more information.
 + */
  static inline struct strbuf **strbuf_split_max(const struct strbuf *sb,
 -                                              int delim, int max)
 +                                              int terminator, int max)
  {
 -      return strbuf_split_buf(sb->buf, sb->len, delim, max);
 +      return strbuf_split_buf(sb->buf, sb->len, terminator, max);
  }
 -static inline struct strbuf **strbuf_split(const struct strbuf *sb, int delim)
 +
 +/*
 + * Split a strbuf at the specified terminator character.  See
 + * strbuf_split_buf() for more information.
 + */
 +static inline struct strbuf **strbuf_split(const struct strbuf *sb,
 +                                         int terminator)
  {
 -      return strbuf_split_max(sb, delim, 0);
 +      return strbuf_split_max(sb, terminator, 0);
  }
 +
 +/*
 + * Free a NULL-terminated list of strbufs (for example, the return
 + * values of the strbuf_split*() functions).
 + */
  extern void strbuf_list_free(struct strbuf **);
  
  /*----- add data in your buffer -----*/
@@@ -136,6 -102,12 +136,12 @@@ extern void strbuf_vaddf(struct strbuf 
  
  extern void strbuf_add_lines(struct strbuf *sb, const char *prefix, const char *buf, size_t size);
  
+ /*
+  * Append s to sb, with the characters '<', '>', '&' and '"' converted
+  * into XML entities.
+  */
+ extern void strbuf_addstr_xml_quoted(struct strbuf *sb, const char *s);
  static inline void strbuf_complete_line(struct strbuf *sb)
  {
        if (sb->len && sb->buf[sb->len - 1] != '\n')