static int mime_multipart_related_output_fn(const char* buf, int32_t size, void *stream_closure) { MimeMultipartRelated *relobj = (MimeMultipartRelated *) stream_closure; char* ptr; int32_t delta; int status; while (size > 0) { if (relobj->curtag_length > 0) { ptr = PL_strnchr(buf, '>', size); if (!ptr) { return push_tag(relobj, buf, size); } delta = ptr - buf + 1; status = push_tag(relobj, buf, delta); if (status < 0) return status; status = flush_tag(relobj); if (status < 0) return status; buf += delta; size -= delta; } ptr = PL_strnchr(buf, '<', size); if (ptr && ptr - buf >= size) ptr = 0; if (!ptr) { return real_write(relobj, buf, size); } delta = ptr - buf; status = real_write(relobj, buf, delta); if (status < 0) return status; buf += delta; size -= delta; PR_ASSERT(relobj->curtag_length == 0); status = push_tag(relobj, buf, 1); if (status < 0) return status; PR_ASSERT(relobj->curtag_length == 1); buf++; size--; } return 0; }
PRBool nsSMILParserUtils::ParseClockComponent(nsACString::const_iterator& aSpec, const nsACString::const_iterator& aEnd, double& aResult, PRBool& aIsReal, PRBool& aCouldBeMin, PRBool& aCouldBeSec) { nsresult rv; char const *begin = aSpec.get(); double value = GetFloat(aSpec, aEnd, &rv); // Check a number was found if (NS_FAILED(rv)) return PR_FALSE; // Check it's not expressed in exponential form size_t len = aSpec.get() - begin; PRBool isExp = (PL_strnpbrk(begin, "eE", len) != nsnull); if (isExp) return PR_FALSE; // Don't allow real numbers of the form "23." if (*(aSpec.get() - 1) == '.') return PR_FALSE; // Number looks good aResult = value; // Set some flags so we can check this number is valid once we know // whether it's an hour, minute string etc. aIsReal = (PL_strnchr(begin, '.', len) != nsnull); aCouldBeMin = (value < 60.0 && (len == 2)); aCouldBeSec = (value < 60.0 || (value == 60.0 && begin[0] == '5')); // Take care of rounding error aCouldBeSec &= (len >= 2 && (begin[2] == '\0' || begin[2] == '.' || IsSpace(begin[2]))); return PR_TRUE; }
static int flush_tag(MimeMultipartRelated* relobj) { int length = relobj->curtag_length; char* buf; int status; if (relobj->curtag == NULL || length == 0) return 0; status = push_tag(relobj, "", 1); /* Push on a trailing NULL. */ if (status < 0) return status; buf = relobj->curtag; PR_ASSERT(*buf == '<' && buf[length - 1] == '>'); while (*buf) { char c; char* absolute; char* part_url; char* ptr = buf; char *ptr2; char quoteDelimiter = '\0'; while (*ptr && *ptr != '=') ptr++; if (*ptr == '=') { /* Ignore = and leading space. */ /* Safe, because there's a '>' at the end! */ do {ptr++;} while (IS_SPACE(*ptr)); if (*ptr == '"' || *ptr == '\'') { quoteDelimiter = *ptr; /* Take up the quote and leading space here as well. */ /* Safe because there's a '>' at the end */ do {ptr++;} while (IS_SPACE(*ptr)); } } status = real_write(relobj, buf, ptr - buf); if (status < 0) return status; buf = ptr; if (!*buf) break; if (quoteDelimiter) { ptr = PL_strnchr(buf, quoteDelimiter, length - (buf - relobj->curtag)); } else { for (ptr = buf; *ptr ; ptr++) { if (*ptr == '>' || IS_SPACE(*ptr)) break; } PR_ASSERT(*ptr); } if (!ptr || !*ptr) break; while(buf < ptr) { /* ### mwelch For each word in the value string, see if the word is a cid: URL. If so, attempt to substitute the appropriate mailbox part URL in its place. */ ptr2=buf; /* walk from the left end rightward */ while((ptr2<ptr) && (!IS_SPACE(*ptr2))) ptr2++; /* Compare the beginning of the word with "cid:". Yuck. */ if (((ptr2 - buf) > 4) && ((buf[0]=='c' || buf[0]=='C') && (buf[1]=='i' || buf[1]=='I') && (buf[2]=='d' || buf[2]=='D') && buf[3]==':')) { // Make sure it's lowercase, otherwise it won't be found in the hash table buf[0] = 'c'; buf[1] = 'i'; buf[2] = 'd'; /* Null terminate the word so we can... */ c = *ptr2; *ptr2 = '\0'; /* Construct a URL out of the word. */ absolute = MakeAbsoluteURL(relobj->base_url, buf); /* See if we have a mailbox part URL corresponding to this cid. */ part_url = nullptr; MimeHashValue * value = nullptr; if (absolute) { value = (MimeHashValue *)PL_HashTableLookup(relobj->hash, buf); part_url = value ? value->m_url : nullptr; PR_FREEIF(absolute); } /*If we found a mailbox part URL, write that out instead.*/ if (part_url && accept_related_part(relobj, value->m_obj)) { status = real_write(relobj, part_url, strlen(part_url)); if (status < 0) return status; buf = ptr2; /* skip over the cid: URL we substituted */ /* don't show that object as attachment */ if (value->m_obj) value->m_obj->dontShowAsAttachment = true; } /* Restore the character that we nulled. */ *ptr2 = c; } /* rhp - if we get here, we should still check against the hash table! */ else { char holder = *ptr2; char *realout; *ptr2 = '\0'; /* Construct a URL out of the word. */ absolute = MakeAbsoluteURL(relobj->base_url, buf); /* See if we have a mailbox part URL corresponding to this cid. */ MimeHashValue * value; if (absolute) value = (MimeHashValue *)PL_HashTableLookup(relobj->hash, absolute); else value = (MimeHashValue *)PL_HashTableLookup(relobj->hash, buf); realout = value ? value->m_url : nullptr; *ptr2 = holder; PR_FREEIF(absolute); if (realout && accept_related_part(relobj, value->m_obj)) { status = real_write(relobj, realout, strlen(realout)); if (status < 0) return status; buf = ptr2; /* skip over the cid: URL we substituted */ /* don't show that object as attachment */ if (value->m_obj) value->m_obj->dontShowAsAttachment = true; } } /* rhp - if we get here, we should still check against the hash table! */ /* Advance to the beginning of the next word, or to the end of the value string. */ while((ptr2<ptr) && (IS_SPACE(*ptr2))) ptr2++; /* Write whatever original text remains after cid: URL substitution. */ status = real_write(relobj, buf, ptr2-buf); if (status < 0) return status; buf = ptr2; } } if (buf && *buf) { status = real_write(relobj, buf, strlen(buf)); if (status < 0) return status; } relobj->curtag_length = 0; return 0; }
/* * Helper function for validating a DN. This function will validate * a single RDN. If the RDN is valid, 0 will be returned, otherwise * non-zero will be returned. A pointer to the last character processed * will be set in the "last parameter. This will be the end of the RDN * in the valid case, and the illegal character in the invalid case. */ int rdn_validate( const char *begin, const char *end, const char **last ) { int rc = 0; /* Assume RDN is valid */ int numericform = 0; char *separator = NULL; const char *p = begin; /* Find the '=', then use the helpers for descr and numericoid */ if ((separator = PL_strnchr(p, '=', end - begin + 1)) == NULL) { rc = 1; goto exit; } /* Process an attribute type. The 'descr' * form must start with a 'leadkeychar'. */ if (IS_LEADKEYCHAR(*p)) { if ((rc = keystring_validate(p, separator - 1))) { goto exit; } /* See if the 'numericoid' form is being used */ } else if (isdigit(*p)) { numericform = 1; if ((rc = numericoid_validate(p, separator - 1))) { goto exit; } } else { rc = 1; goto exit; } /* Advance the pointer past the '=' and make sure * we're not past the end of the string. */ p = separator + 1; if (p > end) { rc = 1; goto exit; } /* The value must be a 'hexstring' if the 'numericoid' * form of 'attributeType' is used. Per RFC 4514: * * hexstring = SHARP 1*hexpair * hexpair = HEX HEX */ if (numericform) { if ((p == end) || !IS_SHARP(*p)) { rc = 1; goto exit; } p++; /* The value must be a 'string' when the 'descr' form * of 'attributeType' is used. Per RFC 4514: * * string = [ ( leadchar / pair ) [ *( stringchar / pair ) * ( trailchar / pair ) ] ] * * leadchar = LUTF1 / UTFMB * trailchar = TUTF1 / UTFMB * stringchar = SUTF1 / UTFMB * * pair = ESC (ESC / special / hexpair ) * special = escaped / SPACE / SHARP / EQUALS * escaped = DQUOTE / PLUS / COMMA / SEMI / LANGLE / RANGLE * hexpair = HEX HEX */ } else { /* Check the leadchar to see if anything illegal * is there. We need to allow a 'pair' to get * through, so we'll assume that a '\' is the * start of a 'pair' for now. */ if (IS_UTF1(*p) && !IS_ESC(*p) && !IS_LUTF1(*p)) { rc = 1; goto exit; } } /* Loop through string until we find the ',' separator, a '+' * char indicating a multi-value RDN, or we reach the end. */ while ((p <= end) && (*p != ',') && (*p != '+')) { if (numericform) { /* Process a single 'hexpair' */ if ((p == end) || !isxdigit(*p) || !isxdigit(*p + 1)) { rc = 1; goto exit; } p = p + 2; } else { /* Check for a valid 'stringchar'. We handle * multi-byte characters separately. */ if (IS_UTF1(*p)) { /* If we're at the end, check if we have * a valid 'trailchar'. */ if ((p == end) && !IS_TUTF1(*p)) { rc = 1; goto exit; /* Check for a 'pair'. */ } else if (IS_ESC(*p)) { /* We're guaranteed to still have at * least one more character, so lets * take a look at it. */ p++; if (!IS_ESC(*p) && !IS_SPECIAL(*p)) { /* The only thing valid now * is a 'hexpair'. */ if ((p == end) || !isxdigit(*p) ||!isxdigit(*p + 1)) { rc = 1; goto exit; } p++; } /* Only allow 'SUTF1' chars now. */ } else if (!IS_SUTF1(*p)) { rc = 1; goto exit; } p++; } else { /* Validate a single 'UTFMB' (multi-byte) character. */ if (utf8char_validate(p, end, &p ) != 0) { rc = 1; goto exit; } /* Advance the pointer past the multi-byte char. */ p++; } } } /* We'll end up either at the comma, a '+', or one past end. * If we are processing a multi-valued RDN, we recurse to * process the next 'attributeTypeAndValue'. */ if ((p <= end) && (*p == '+')) { /* Make sure that there is something after the '+'. */ if (p == end) { rc = 1; goto exit; } p++; /* Recurse to process the next value. We need to reset p to * ensure that last is set correctly for the original caller. */ rc = rdn_validate( p, end, last ); p = *last + 1; } exit: *last = p - 1; return rc; }