Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
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;
}