size_t unquote_url_inplace(char* url, size_t len) { char *p = url; char *end = url+len; for(; url != end; ++url, ++p) { if(*url == '%') { char a,b; if(url >= end-2) { /* Less than two characters left after the '%' */ return 0; } a = UNHEX(url[1]); b = UNHEX(url[2]); if(a == NOHEX || b == NOHEX) return 0; *p = a*16 + b; url += 2; len -= 2; } else { *p = *url; } } return len; }
nsresult nsMsgSendLater::BuildHeaders() { char *buf = m_headers; char *buf_end = buf + m_headersFP; PR_FREEIF(m_to); PR_FREEIF(m_bcc); PR_FREEIF(m_newsgroups); PR_FREEIF(m_newshost); PR_FREEIF(m_fcc); PR_FREEIF(mIdentityKey); PR_FREEIF(mAccountKey); m_flags = 0; while (buf < buf_end) { bool prune_p = false; bool do_flags_p = false; char *colon = PL_strchr(buf, ':'); char *end; char *value = 0; char **header = 0; char *header_start = buf; if (! colon) break; end = colon; while (end > buf && (*end == ' ' || *end == '\t')) end--; switch (buf [0]) { case 'B': case 'b': if (!PL_strncasecmp ("BCC", buf, end - buf)) { header = &m_bcc; prune_p = true; } break; case 'C': case 'c': if (!PL_strncasecmp ("CC", buf, end - buf)) header = &m_to; else if (!PL_strncasecmp (HEADER_CONTENT_LENGTH, buf, end - buf)) prune_p = true; break; case 'F': case 'f': if (!PL_strncasecmp ("FCC", buf, end - buf)) { header = &m_fcc; prune_p = true; } break; case 'L': case 'l': if (!PL_strncasecmp ("Lines", buf, end - buf)) prune_p = true; break; case 'N': case 'n': if (!PL_strncasecmp ("Newsgroups", buf, end - buf)) header = &m_newsgroups; break; case 'S': case 's': if (!PL_strncasecmp ("Sender", buf, end - buf)) prune_p = true; break; case 'T': case 't': if (!PL_strncasecmp ("To", buf, end - buf)) header = &m_to; break; case 'X': case 'x': { int32_t headLen = PL_strlen(HEADER_X_MOZILLA_STATUS2); if (headLen == end - buf && !PL_strncasecmp(HEADER_X_MOZILLA_STATUS2, buf, end - buf)) prune_p = true; else if (PL_strlen(HEADER_X_MOZILLA_STATUS) == end - buf && !PL_strncasecmp(HEADER_X_MOZILLA_STATUS, buf, end - buf)) prune_p = do_flags_p = true; else if (!PL_strncasecmp(HEADER_X_MOZILLA_DRAFT_INFO, buf, end - buf)) prune_p = true; else if (!PL_strncasecmp(HEADER_X_MOZILLA_KEYWORDS, buf, end - buf)) prune_p = true; else if (!PL_strncasecmp(HEADER_X_MOZILLA_NEWSHOST, buf, end - buf)) { prune_p = true; header = &m_newshost; } else if (!PL_strncasecmp(HEADER_X_MOZILLA_IDENTITY_KEY, buf, end - buf)) { prune_p = true; header = &mIdentityKey; } else if (!PL_strncasecmp(HEADER_X_MOZILLA_ACCOUNT_KEY, buf, end - buf)) { prune_p = true; header = &mAccountKey; } break; } } buf = colon + 1; while (*buf == ' ' || *buf == '\t') buf++; value = buf; SEARCH_NEWLINE: while (*buf != 0 && *buf != '\r' && *buf != '\n') buf++; if (buf+1 >= buf_end) ; // If "\r\n " or "\r\n\t" is next, that doesn't terminate the header. else if (buf+2 < buf_end && (buf[0] == '\r' && buf[1] == '\n') && (buf[2] == ' ' || buf[2] == '\t')) { buf += 3; goto SEARCH_NEWLINE; } // If "\r " or "\r\t" or "\n " or "\n\t" is next, that doesn't terminate // the header either. else if ((buf[0] == '\r' || buf[0] == '\n') && (buf[1] == ' ' || buf[1] == '\t')) { buf += 2; goto SEARCH_NEWLINE; } if (header) { int L = buf - value; if (*header) { char *newh = (char*) PR_Realloc ((*header), PL_strlen(*header) + L + 10); if (!newh) return NS_ERROR_OUT_OF_MEMORY; *header = newh; newh = (*header) + PL_strlen (*header); *newh++ = ','; *newh++ = ' '; memcpy(newh, value, L); newh [L] = 0; } else { *header = (char *) PR_Malloc(L+1); if (!*header) return NS_ERROR_OUT_OF_MEMORY; memcpy((*header), value, L); (*header)[L] = 0; } } else if (do_flags_p) { int i; char *s = value; PR_ASSERT(*s != ' ' && *s != '\t'); m_flags = 0; for (i=0 ; i<4 ; i++) { m_flags = (m_flags << 4) | UNHEX(*s); s++; } } if (*buf == '\r' || *buf == '\n') { if (*buf == '\r' && buf[1] == '\n') buf++; buf++; } if (prune_p) { char *to = header_start; char *from = buf; while (from < buf_end) *to++ = *from++; buf = header_start; buf_end = to; m_headersFP = buf_end - m_headers; } } m_headers[m_headersFP++] = '\r'; m_headers[m_headersFP++] = '\n'; // Now we have parsed out all of the headers we need and we // can proceed. return NS_OK; }