示例#1
0
AB_IMEXPORTER_ACCOUNTINFO*
AB_ImExporterAccountInfo_dup(const AB_IMEXPORTER_ACCOUNTINFO *oi) {
  AB_IMEXPORTER_ACCOUNTINFO *iea;

  GWEN_NEW_OBJECT(AB_IMEXPORTER_ACCOUNTINFO, iea);
  GWEN_LIST_INIT(AB_IMEXPORTER_ACCOUNTINFO, iea);

#define COPY_CHAR(NAME) \
  if (oi->NAME) \
    iea->NAME=strdup(oi->NAME);
  COPY_CHAR(bankCode);
  COPY_CHAR(bankName);
  COPY_CHAR(accountNumber);
  COPY_CHAR(accountName);
  COPY_CHAR(iban);
  COPY_CHAR(bic);
  COPY_CHAR(owner);
  COPY_CHAR(currency);
  COPY_CHAR(description);
  iea->accountType=oi->accountType;
#undef COPY_CHAR
  iea->accountId=oi->accountId;

  iea->accStatusList=AB_AccountStatus_List_dup(oi->accStatusList);
  iea->transactions=AB_Transaction_List_dup(oi->transactions);
  iea->standingOrders=AB_Transaction_List_dup(oi->standingOrders);
  iea->transfers=AB_Transaction_List_dup(oi->transfers);
  iea->datedTransfers=AB_Transaction_List_dup(oi->datedTransfers);
  iea->notedTransactions=AB_Transaction_List_dup(oi->notedTransactions);
  return iea;
}
示例#2
0
/* msg_quote_phrase_or_addr
 *
 * Given a single mailbox, this quotes the characters in it which need
 * to be quoted; it writes into `address' and returns a new length.
 * `address' is assumed to be long enough; worst case, its size will
 * be (N*2)+2.
 */
static int
msg_quote_phrase_or_addr(char *address, PRInt32 length, PRBool addr_p)
{
    int quotable_count = 0, in_quote = 0;
    int unquotable_count = 0;
    PRInt32 new_length, full_length = length;
    char *in, *out, *orig_out, *atsign = NULL, *orig_address = address;
    PRBool user_quote = PR_FALSE;
    PRBool quote_all = PR_FALSE;

    /* If the entire address is quoted, fall out now. */
    if (address[0] == '\"' && address[length - 1] == '\"')
        return length;

    /* Check to see if there is a routing prefix.  If there is one, we can
     * skip quoting it because by definition it can't need to be quoted.
     */
    if (addr_p && *address && *address == '@')
    {
        for (in = address; *in; NEXT_CHAR(in))
        {
            if (*in == ':')
            {
                length -= ++in - address;
                address = in;
                break;
            }
            else if (!IS_DIGIT(*in) && !IS_ALPHA(*in) && *in != '@' && *in != '.')
                break;
        }
    }

    for (in = address; in < address + length; NEXT_CHAR(in))
    {
        if (*in == 0)
            return full_length; /* #### horrible kludge... */

        else if (*in == '@' && addr_p && !atsign && !in_quote)
        {
            /* Exactly one unquoted at-sign is allowed in an address. */
            if (atsign)
                quotable_count++;
            atsign = in;

            /* If address is of the form '"userid"@somewhere.com' don't quote
             * the quotes around 'userid'.  Also reset the quotable count, since
             * any quotables we've seen are already inside quotes.
             */
            if (address[0] == '\"' && in > address + 2 && *(in - 1) == '\"' && *(in - 2) != '\\')
                unquotable_count -= 2, quotable_count = 0, user_quote = PR_TRUE;
        }

        else if (*in == '\\')
        {
            if (in + 1 < address + length && (*(in + 1) == '\\' || *(in + 1) == '\"'))
                /* If the next character is a backslash or quote, this backslash */
                /* is an escape backslash; ignore it and the next character.     */
                in++;
            else
                /* If the name contains backslashes or quotes, they must be escaped. */
                unquotable_count++;
        }

        else if (*in == '\"')
            /* If the name contains quotes, they must be escaped. */
            unquotable_count++, in_quote = !in_quote;

        else if (  /* *in >= 127 || *in < 0  ducarroz: 8bits characters will be mime encoded therefore they are not a problem
             ||*/ (*in == ';' && !addr_p) || *in == '$' || *in == '(' || *in == ')'
            || *in == '<' || *in == '>' || *in == '@' || *in == ',')
            /* If the name contains control chars or Header specials, it needs to
             * be enclosed in quotes.  Double-quotes and backslashes will be dealt
             * with separately.
             *
             * The ":" character is explicitly not in this list, though Header says
             * it should be quoted, because that has been seen to break VMS
             * systems.  (Rather, it has been seen that there are Unix SMTP servers
             * which accept RCPT TO:<host::user> but not RCPT TO:<"host::user"> or
             * RCPT TO:<host\:\:user>, which is the syntax that VMS/DECNET hosts
             * use.
             *
             * For future reference: it is also claimed that some VMS SMTP servers
             * allow \ quoting but not "" quoting; and that sendmail uses self-
             * contradcitory quoting conventions that violate both RFCs 821 and
             * 822, so any address quoting on a sendmail system will lose badly.
             *
             * The ";" character in an address is a group delimiter, therefore it
             * should not be quoted in that case.
             */
            quotable_count++;

        else if (!atsign && (*in == '[' || *in == ']'))
            /* Braces are normally special characters, except when they're
             * used for domain literals (e.g. johndoe@[127.0.0.1].acme.com).
             */
            quotable_count++;

        else if (addr_p && *in == ' ')
            /* Naked spaces are allowed in names, but not addresses. */
            quotable_count++;

        else if (   !addr_p
                    && (*in == '.' || *in == '!' || *in == '$' || *in == '%'))
            /* Naked dots are allowed in addresses, but not in names.
             * The other characters (!$%) are technically allowed in names, but
             * are surely going to cause someone trouble, so we quote them anyway.
             */
            quotable_count++;
    }

    if (quotable_count == 0 && unquotable_count == 0)
        return full_length;

    /* We must quote the entire string if there are quotables outside the user
     * quote.
     */
    if (!atsign || (user_quote && quotable_count > 0))
        quote_all = PR_TRUE, atsign = NULL;

    /* Add 2 to the length for the quotes, plus one for each character
     * which will need a backslash, plus one for a null terminator.
     */
    new_length = length + quotable_count + unquotable_count + 3;

    in = address;
    out = orig_out = (char *)PR_Malloc(new_length);
    if (!out)
    {
        *orig_address = 0;
        return 0;
    }

    /* Start off with a quote.
     */
    *out++ = '\"';

    while (*in)
    {
        if (*in == '@')
        {
            if (atsign == in)
                *out++ = '\"';
            *out++ = *in++;
            continue;
        }
        else if (*in == '\"')
        {
            if (!user_quote || (in != address && in != atsign - 1))
                *out++ = '\\';
            *out++ = *in++;
            continue;
        }
        else if (*in == '\\')
        {
            if (*(in + 1) == '\\' || *(in + 1) == '\"')
                *out++ = *in++;
            else
                *out++ = '\\';
            *out++ = *in++;
            continue;
        }
        else
            COPY_CHAR(out, in);

        NEXT_CHAR(in);
    }

    /* Add a final quote if we are quoting the entire string.
     */
    if (quote_all)
        *out++ = '\"';
    *out++ = 0;

    NS_ASSERTION(new_length >= (out - orig_out), "");
    memcpy(address, orig_out, new_length);
    PR_FREEIF(orig_out); /* make sure we release the string we allocated */

    return full_length + unquotable_count + 2;
}
示例#3
0
/* msg_unquote_phrase_or_addr
 *
 * Given a name or address that might have been quoted
 * it will take out the escape and double quotes
 * The caller is responsible for freeing the resulting
 * string.
 */
static nsresult
msg_unquote_phrase_or_addr(const char *line, PRBool preserveIntegrity, char **lineout)
{
    if (!line || !lineout)
        return NS_OK;

    /* If the first character isn't a double quote, there is nothing to do
     */
    if (*line != '\"')
    {
        *lineout = strdup(line);
        if (!*lineout)
            return NS_ERROR_OUT_OF_MEMORY;
        else
            return NS_OK;
    }

    /* in preserveIntegrity mode, we must preserve the quote if the name contains a comma */
    if (preserveIntegrity)
    {
        const char * open_quote = nsnull;
        const char * comma = nsnull;;
        const char * at_sign = nsnull;
        const char * readPos = line + 1;

        while (*readPos)
        {
            if (*readPos == ',')
            {
                if (!open_quote)
                    comma = readPos;
            }
            else if (*readPos == '@')
            {
                at_sign = readPos;
                break;
            }
            else if (*readPos == '"')
            {
                if (!open_quote)
                    open_quote = readPos;
                else
                    open_quote = nsnull;
            }

            readPos ++;
        }

        if (comma && at_sign)
        {
            *lineout = strdup(line);
            if (!*lineout)
                return NS_ERROR_OUT_OF_MEMORY;
            else
                return NS_OK;
        }
    }

    /* Don't copy the first double quote
     */
    *lineout = strdup(line + 1);
    if (!*lineout)
        return NS_ERROR_OUT_OF_MEMORY;

    const char *lineptr = line + 1;
    char *outptr = *lineout;
    PRBool escaped = PR_FALSE;

    while (*lineptr)
    {
        /* If the character is an '\' then output the character that was
         * escaped.  If it was part of the quote then don't output it.
         */
        if (*lineptr == '\\')
        {
            escaped = PR_TRUE;
            lineptr++;
        }
        if (*lineptr == '\"' && !escaped)
            lineptr++;
        escaped = PR_FALSE;

        if (*lineptr)
        {
            COPY_CHAR(outptr, lineptr);
            NEXT_CHAR(lineptr);
        }
    }
    *outptr = '\0';

    return NS_OK;
}
示例#4
0
/* msg_parse_Header_addresses
 *
 * Given a string which contains a list of Header addresses, parses it into
 * their component names and mailboxes.
 *
 * The returned value is the number of addresses, or a negative error code;
 * the names and addresses are returned into the provided pointers as
 * consecutive null-terminated strings.  It is up to the caller to free them.
 * Note that some of the strings may be zero-length.
 *
 * Either of the provided pointers may be NULL if the caller is not interested
 * in those components.
 *
 * quote_names_p and quote_addrs_p control whether the returned strings should
 * be quoted as Header entities, or returned in a more human-presentable (but
 * not necessarily parsable) form.
 *
 * If first_only_p is true, then only the first element of the list is
 * returned; we don't bother parsing the rest.
 */
static int msg_parse_Header_addresses (const char *line, char **names, char **addresses,
                                       PRBool quote_names_p, PRBool quote_addrs_p, PRBool first_only_p)
{
    PRUint32 addr_count = 0;
    size_t line_length;
    const char *line_end;
    const char *this_start;
    char *name_buf = 0, *name_out, *name_start;
    char *addr_buf = 0, *addr_out, *addr_start;

    if (names)
        *names = 0;
    if (addresses)
        *addresses = 0;
    NS_ASSERTION(line, "");
    if (!line)
        return -1;
    line_length = strlen(line);
    if (line_length == 0)
        return 0;

    name_buf = (char *)PR_Malloc(line_length * 2 + 10);
    if (!name_buf)
        return NS_ERROR_OUT_OF_MEMORY;

    addr_buf = (char *)PR_Malloc(line_length * 2 + 10);
    if (!addr_buf)
    {
        FREEIF(name_buf);
        return NS_ERROR_OUT_OF_MEMORY;
    }

    line_end = line;
    addr_out = addr_buf;
    name_out = name_buf;
    name_start = name_buf;
    addr_start = addr_buf;
    this_start = line;

    /* Skip over extra whitespace or commas before addresses.
     */
    while (*line_end && (IS_SPACE(*line_end) || *line_end == ','))
        NEXT_CHAR(line_end);

    while (*line_end)
    {
        PRUint32 paren_depth = 0;
        const char *oparen = 0;
        const char *mailbox_start = 0;
        const char *mailbox_end = 0;

        while (   *line_end
                  && !(   *line_end == ',' && paren_depth <= 0 /* comma is ok inside () */
                          && (!mailbox_start || mailbox_end)))    /* comma is ok inside <> */
        {
            if (*line_end == '\\')
            {
                line_end++;
                if (!*line_end) /* otherwise, we walk off end of line, right? */
                    break;
            }
            else if (*line_end == '\"')
            {
                int leave_quotes = 0;

                line_end++;  /* remove open " */

                /* handle '"John.Van Doe"@space.com' case */
                if (paren_depth == 0 && !mailbox_start)
                {
                    const char *end_quote;
                    /* search for the closing quote but ignored escaped quote \" */
                    for (end_quote = line_end;; end_quote++)
                    {
                        end_quote = PL_strchr(end_quote, '"');
                        if (!end_quote || *(end_quote - 1) != '\\')
                            break;
                    }
                    const char *mailbox = end_quote ? PL_strchr(end_quote, '<') : (char *)NULL;
                    const char *comma = end_quote ? PL_strchr(end_quote, ',') : (char *)NULL;
                    if (!mailbox || (comma && comma < mailbox))
                    {
                        leave_quotes = 1; /* no mailbox for this address */
                        *addr_out++ = '\"';
                    }
                }

                while (*line_end)
                {
                    if (*line_end == '\\')
                    {
                        line_end++;
                        if (paren_depth == 0 && (*line_end == '\\' || *line_end == '\"'))
                            *addr_out++ = *line_end++;
                        continue;
                    }
                    else if (*line_end == '\"')
                    {
                        line_end++;  /* remove close " */
                        break;
                    }

                    if (paren_depth == 0)
                        COPY_CHAR(addr_out, line_end);

                    NEXT_CHAR(line_end);
                }
                if (leave_quotes) *addr_out++ = '\"';
                continue;
            }

            if (*line_end == '(')
            {
                if (paren_depth == 0)
                    oparen = line_end;
                paren_depth++;
            }
            else if (*line_end == '<' && paren_depth == 0)
            {
                mailbox_start = line_end;
            }
            else if (*line_end == '>' && mailbox_start && paren_depth == 0)
            {
                mailbox_end = line_end;
            }
            else if (*line_end == ')' && paren_depth > 0)
            {
                paren_depth--;
                if (paren_depth == 0)
                {
                    const char *s = oparen + 1;

                    /* Copy the chars inside the parens onto the "name" buffer. */

                    /* Push out some whitespace before the paren, if
                                       * there is non-whitespace there already.
                                       */
                    if (name_out > name_start && !IS_SPACE(name_out [-1]))
                        *name_out++ = ' ';

                    /* Skip leading whitespace.
                     */
                    while (IS_SPACE(*s) && s < line_end)
                        s++;

                    while (s < line_end)
                    {
                        /* Strip out " within () unless backslashed
                         */
                        if (*s == '\"')
                        {
                            s++;
                            continue;
                        }

                        if (*s == '\\') /* remove one \ */
                            s++;

                        if (IS_SPACE(*s) && name_out > name_start && IS_SPACE(name_out[-1]))
                            /* collapse consecutive whitespace */;
                        else
                            COPY_CHAR(name_out, s);

                        NEXT_CHAR(s);
                    }
                    oparen = 0;
                }
            }
            else
            {
                /* If we're not inside parens or a <mailbox>, tack this
                 * on to the end of the addr_buf.
                 */
                if (paren_depth == 0 && (!mailbox_start || mailbox_end))
                {
                    /* Eat whitespace at the beginning of the line,
                     * and eat consecutive whitespace within the line.
                     */
                    if (IS_SPACE(*line_end)
                            && (addr_out == addr_start || IS_SPACE(addr_out[-1])))
                        /* skip it */;
                    else
                        COPY_CHAR(addr_out, line_end);
                }
            }

            NEXT_CHAR(line_end);
        }

        /* Now we have extracted a single address from the comma-separated
           * list of addresses.  The characters have been divided among the
           * various buffers: the parts inside parens have been placed in the
           * name_buf, and everything else has been placed in the addr_buf.
           * Quoted strings and backslashed characters have been `expanded.'
           *
           * If there was a <mailbox> spec in it, we have remembered where it was.
           * Copy that on to the addr_buf, replacing what was there, and copy the
           * characters not inside <> onto the name_buf, replacing what is there
           * now (which was just the parenthesized parts.)  (And we need to do the
           * quote and backslash hacking again, since we're coming from the
           * original source.)
           *
           * Otherwise, we're already done - the addr_buf and name_buf contain
           * the right data already (de-quoted.)
           */
        if (mailbox_end)
        {
            const char *s;
            NS_ASSERTION(*mailbox_start == '<', "");
            NS_ASSERTION(*mailbox_end == '>', "");

            /* First, copy the name.
             */
            name_out = name_start;
            s = this_start;

            /* Skip leading whitespace.
             */
            while (IS_SPACE(*s) && s < mailbox_start)
                s++;

            /* Copy up to (not including) the <
             */
            while (s < mailbox_start)
            {
                if (*s == '\"' && !quote_names_p)
                {
                    s++;
                    continue;
                }
                if (*s == '\\' && !quote_names_p)
                {
                    s++;
                    if (s < mailbox_start && (*s == '\\' || *s == '\"'))
                        *name_out++ = *s++;
                    continue;
                }
                if (IS_SPACE(*s) && name_out > name_start && IS_SPACE(name_out[-1]))
                    /* collapse consecutive whitespace */;
                else
                    COPY_CHAR(name_out, s);

                NEXT_CHAR(s);
            }

            /* Push out one space.
             */
            TRIM_WHITESPACE(name_start, name_out, ' ');
            s = mailbox_end + 1;

            /* Skip whitespace after >
             */
            while (IS_SPACE(*s) && s < line_end)
                s++;

            /* Copy from just after > to the end.
             */
            while (s < line_end)
            {
                if (*s == '\"' && !quote_names_p)
                {
                    s++;
                    continue;
                }
                if (*s == '\\' && !quote_names_p)
                {
                    s++;
                    if (s  < line_end && (*s == '\\' || *s == '\"'))
                        *name_out++ = *s++;
                    continue;
                }
                if (IS_SPACE(*s) && name_out > name_start && IS_SPACE(name_out[-1]))
                    /* collapse consecutive whitespace */;
                else
                    COPY_CHAR(name_out, s);

                NEXT_CHAR(s);
            }

            TRIM_WHITESPACE(name_start, name_out, 0);

            /* Now, copy the address.
             */
            mailbox_start++;
            addr_out = addr_start;
            s = mailbox_start;

            /* Skip leading whitespace.
             */
            while (IS_SPACE(*s) && s < mailbox_end)
                s++;

            /* Copy up to (not including) the >
             */
            while (s < mailbox_end)
            {
                if (*s == '\"' && !quote_addrs_p)
                {
                    s++;
                    continue;
                }
                if (*s == '\\' && !quote_addrs_p)
                {
                    s++;
                    if (s < mailbox_end && (*s == '\\' || *s == '\"'))
                        *addr_out++ = *s++;
                    continue;
                }
                COPY_CHAR(addr_out, s);
                NEXT_CHAR(s);
            }

            TRIM_WHITESPACE(addr_start, addr_out, 0);
        }
        /* No component of <mailbox> form.
         */
        else
        {
            TRIM_WHITESPACE(addr_start, addr_out, 0);
            TRIM_WHITESPACE(name_start, name_out, 0);
        }

        /* Now re-quote the names and addresses if necessary.
         */
#ifdef BUG11892
        // **** jefft - we don't want and shouldn't to requtoe the name, this
        // violate the RFC822 spec
        if (quote_names_p && names)
        {
            int L = name_out - name_start - 1;
            L = msg_quote_phrase_or_addr(name_start, L, PR_FALSE);
            name_out = name_start + L + 1;
        }
#endif

        if (quote_addrs_p && addresses)
        {
            int L = addr_out - addr_start - 1;
            L = msg_quote_phrase_or_addr(addr_start, L, PR_TRUE);
            addr_out = addr_start + L + 1;
        }

        addr_count++;

        /* If we only want the first address, we can stop now.
         */
        if (first_only_p)
            break;

        if (*line_end)
            NEXT_CHAR(line_end);

        /* Skip over extra whitespace or commas between addresses. */
        while (*line_end && (IS_SPACE(*line_end) || *line_end == ','))
            line_end++;

        this_start = line_end;
        name_start = name_out;
        addr_start = addr_out;
    }

    /* Make one more pass through and convert all whitespace characters
     * to SPC.  We could do that in the first pass, but this is simpler.
     */
    {
        char *s;
        for (s = name_buf; s < name_out; NEXT_CHAR(s))
            if (IS_SPACE(*s) && *s != ' ')
                *s = ' ';
        for (s = addr_buf; s < addr_out; NEXT_CHAR(s))
            if (IS_SPACE(*s) && *s != ' ')
                *s = ' ';
    }

    if (names)
        *names = name_buf;
    else
        PR_Free(name_buf);

    if (addresses)
        *addresses = addr_buf;
    else
        PR_Free(addr_buf);

    return addr_count;
}