Example #1
0
  // Reads over a boundary and sets start to the position after the end of the
  // boundary. Returns false if no boundary is found immediately.
  bool
  PushOverBoundary(const nsACString& aBoundaryString,
                   nsACString::const_iterator& aStart,
                   nsACString::const_iterator& aEnd)
  {
    // We copy the end iterator to keep the original pointing to the real end
    // of the string.
    nsACString::const_iterator end(aEnd);
    const char* beginning = aStart.get();
    if (FindInReadable(aBoundaryString, aStart, end)) {
      // We either should find the body immediately, or after 2 chars with the
      // 2 chars being '-', everything else is failure.
      if ((aStart.get() - beginning) == 0) {
        aStart.advance(aBoundaryString.Length());
        return true;
      }

      if ((aStart.get() - beginning) == 2) {
        if (*(--aStart) == '-' && *(--aStart) == '-') {
          aStart.advance(aBoundaryString.Length() + 2);
          return true;
        }
      }
    }

    return false;
  }
/**
 * Reads one table of results from the response.  Leaves begin pointing at the
 * next table.
 */
nsresult
nsUrlClassifierHashCompleterRequest::HandleTable(nsACString::const_iterator& begin,
                                                 const nsACString::const_iterator& end)
{
  nsACString::const_iterator iter;
  iter = begin;
  if (!FindCharInReadable(':', iter, end)) {
    // No table line.
    NS_WARNING("Received badly-formatted gethash response.");
    return NS_ERROR_FAILURE;
  }

  const nsCSubstring& tableName = Substring(begin, iter);
  iter++;
  begin = iter;

  if (!FindCharInReadable('\n', iter, end)) {
    // Unterminated header line.
    NS_WARNING("Received badly-formatted gethash response.");
    return NS_ERROR_FAILURE;
  }

  const nsCSubstring& remaining = Substring(begin, iter);
  iter++;
  begin = iter;

  PRUint32 chunkId;
  PRInt32 size;
  if (PR_sscanf(PromiseFlatCString(remaining).get(),
                "%u:%d", &chunkId, &size) != 2) {
    NS_WARNING("Received badly-formatted gethash response.");
    return NS_ERROR_FAILURE;
  }

  if (size % COMPLETE_LENGTH != 0) {
    NS_WARNING("Unexpected gethash response length");
    return NS_ERROR_FAILURE;
  }

  // begin now refers to the hash data.

  if (begin.size_forward() < size) {
    NS_WARNING("Response does not match the expected response length.");
    return NS_ERROR_FAILURE;
  }

  for (PRInt32 i = 0; i < (size / COMPLETE_LENGTH); i++) {
    // Read the complete hash.
    iter.advance(COMPLETE_LENGTH);

    nsresult rv = HandleItem(Substring(begin, iter), tableName, chunkId);
    NS_ENSURE_SUCCESS(rv, rv);

    begin = iter;
  }

  // begin now points at the end of the hash data.

  return NS_OK;
}
Example #3
0
// static
bool
FetchUtil::ExtractHeader(nsACString::const_iterator& aStart,
                         nsACString::const_iterator& aEnd,
                         nsCString& aHeaderName,
                         nsCString& aHeaderValue,
                         bool* aWasEmptyHeader)
{
  MOZ_ASSERT(aWasEmptyHeader);
  // Set it to a valid value here so we don't forget later.
  *aWasEmptyHeader = false;

  const char* beginning = aStart.get();
  nsACString::const_iterator end(aEnd);
  if (!FindCRLF(aStart, end)) {
    return false;
  }

  if (aStart.get() == beginning) {
    *aWasEmptyHeader = true;
    return true;
  }

  nsAutoCString header(beginning, aStart.get() - beginning);

  nsACString::const_iterator headerStart, iter, headerEnd;
  header.BeginReading(headerStart);
  header.EndReading(headerEnd);
  iter = headerStart;
  if (!FindCharInReadable(':', iter, headerEnd)) {
    return false;
  }

  aHeaderName.Assign(StringHead(header, iter - headerStart));
  aHeaderName.CompressWhitespace();
  if (!NS_IsValidHTTPToken(aHeaderName)) {
    return false;
  }

  aHeaderValue.Assign(Substring(++iter, headerEnd));
  if (!NS_IsReasonableHTTPHeaderValue(aHeaderValue)) {
    return false;
  }
  aHeaderValue.CompressWhitespace();

  return PushOverLine(aStart, aEnd);
}
Example #4
0
  // Reads over a CRLF and positions start after it.
  bool
  PushOverLine(nsACString::const_iterator& aStart)
  {
    if (*aStart == nsCRT::CR && (aStart.size_forward() > 1) && *(++aStart) == nsCRT::LF) {
      ++aStart; // advance to after CRLF
      return true;
    }

    return false;
  }
Example #5
0
inline PRBool
nsSMILParserUtils::ParseMetricMultiplicand(nsACString::const_iterator& aSpec,
                                         const nsACString::const_iterator& aEnd,
                                         PRInt32& multiplicand)
{
  PRBool result = PR_FALSE;

  size_t len = aEnd.get() - aSpec.get();
  nsACString::const_iterator spec(aSpec);

  if (len) {
    switch (*spec++)
    {
      case 'h':
        multiplicand = MSEC_PER_HOUR;
        result = PR_TRUE;
        break;
      case 'm':
        if (len >= 2) {
          if (*spec == 's') {
            ++spec;
            multiplicand = 1;
            result = PR_TRUE;
          } else if (len >= 3 && *spec++ == 'i' && *spec++ == 'n') {
            multiplicand = MSEC_PER_MIN;
            result = PR_TRUE;
          }
        }
        break;
      case 's':
        multiplicand = MSEC_PER_SEC;
        result = PR_TRUE;
        break;
    }
  }

  if (result) {
    aSpec = spec;
  }

  return result;
}
Example #6
0
inline PRBool
nsSMILParserUtils::ConsumeSubstring(nsACString::const_iterator& aIter,
                                    const nsACString::const_iterator& aIterEnd,
                                    const char *aSubstring)
{
  size_t substrLen = PL_strlen(aSubstring);
  typedef nsACString::const_iterator::difference_type diff_type;

  if (aIterEnd.get() - aIter.get() < static_cast<diff_type>(substrLen))
    return PR_FALSE;

  PRBool result = PR_FALSE;

  if (PL_strstr(aIter.get(), aSubstring) == aIter.get()) {
    aIter.advance(substrLen);
    result = PR_TRUE;
  }

  return result;
}
Example #7
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;
}
Example #8
0
inline double
nsSMILParserUtils::GetFloat(nsACString::const_iterator& aIter,
                            const nsACString::const_iterator& aIterEnd,
                            nsresult *aErrorCode)
{
  char *end;
  const char *start = aIter.get();
  double value = PR_strtod(start, &end);

  nsresult rv = NS_OK;

  if (end == start || end > aIterEnd.get()) {
    rv = NS_ERROR_FAILURE;
  } else {
    aIter.advance(end - start);
  }

  if (aErrorCode) {
    *aErrorCode = rv;
  }

  return value;
}
Example #9
0
bool
FindCharInReadable( char aChar, nsACString::const_iterator& aSearchStart, const nsACString::const_iterator& aSearchEnd )
  {
    int32_t fragmentLength = aSearchEnd.get() - aSearchStart.get();

    const char* charFoundAt = nsCharTraits<char>::find(aSearchStart.get(), fragmentLength, aChar);
    if ( charFoundAt ) {
      aSearchStart.advance( charFoundAt - aSearchStart.get() );
      return true;
    }

    aSearchStart.advance(fragmentLength);
    return false;
  }
Example #10
0
  // The end of a body is marked by a CRLF followed by the boundary. So the
  // CRLF is part of the boundary and not the body, but any prior CRLFs are
  // part of the body. This will position the iterator at the beginning of the
  // boundary (after the CRLF).
  bool
  ParseBody(const nsACString& aBoundaryString,
            nsACString::const_iterator& aStart,
            nsACString::const_iterator& aEnd)
  {
    const char* beginning = aStart.get();

    // Find the boundary marking the end of the body.
    nsACString::const_iterator end(aEnd);
    if (!FindInReadable(aBoundaryString, aStart, end)) {
      return false;
    }

    // We found a boundary, strip the just prior CRLF, and consider
    // everything else the body section.
    if (aStart.get() - beginning < 2) {
      // Only the first entry can have a boundary right at the beginning. Even
      // an empty body will have a CRLF before the boundary. So this is
      // a failure.
      return false;
    }

    // Check that there is a CRLF right before the boundary.
    aStart.advance(-2);

    // Skip optional hyphens.
    if (*aStart == '-' && *(aStart.get()+1) == '-') {
      if (aStart.get() - beginning < 2) {
        return false;
      }

      aStart.advance(-2);
    }

    if (*aStart != nsCRT::CR || *(aStart.get()+1) != nsCRT::LF) {
      return false;
    }

    nsAutoCString body(beginning, aStart.get() - beginning);

    // Restore iterator to after the \r\n as we promised.
    // We do not need to handle the extra hyphens case since our boundary
    // parser in PushOverBoundary()
    aStart.advance(2);

    if (!mFormData) {
      mFormData = new nsFormData();
    }

    NS_ConvertUTF8toUTF16 name(mName);

    if (mFilename.IsVoid()) {
      mFormData->Append(name, NS_ConvertUTF8toUTF16(body));
    } else {
      // Unfortunately we've to copy the data first since all our strings are
      // going to free it. We also need fallible alloc, so we can't just use
      // ToNewCString().
      char* copy = static_cast<char*>(moz_xmalloc(body.Length()));
      if (!copy) {
        NS_WARNING("Failed to copy File entry body.");
        return false;
      }
      nsCString::const_iterator bodyIter, bodyEnd;
      body.BeginReading(bodyIter);
      body.EndReading(bodyEnd);
      char *p = copy;
      while (bodyIter != bodyEnd) {
        *p++ = *bodyIter++;
      }
      p = nullptr;

      nsRefPtr<Blob> file =
        File::CreateMemoryFile(mParentObject,
                               reinterpret_cast<void *>(copy), body.Length(),
                               NS_ConvertUTF8toUTF16(mFilename),
                               NS_ConvertUTF8toUTF16(mContentType), /* aLastModifiedDate */ 0);
      Optional<nsAString> dummy;
      mFormData->Append(name, *file, dummy);
    }

    return true;
  }
Example #11
0
  bool
  ParseHeader(nsACString::const_iterator& aStart,
              nsACString::const_iterator& aEnd,
              bool* aWasEmptyHeader)
  {
    MOZ_ASSERT(aWasEmptyHeader);
    // Set it to a valid value here so we don't forget later.
    *aWasEmptyHeader = false;

    const char* beginning = aStart.get();
    nsACString::const_iterator end(aEnd);
    if (!FindCRLF(aStart, end)) {
      return false;
    }

    if (aStart.get() == beginning) {
      *aWasEmptyHeader = true;
      return true;
    }

    nsAutoCString header(beginning, aStart.get() - beginning);

    nsACString::const_iterator headerStart, headerEnd;
    header.BeginReading(headerStart);
    header.EndReading(headerEnd);
    if (!FindCharInReadable(':', headerStart, headerEnd)) {
      return false;
    }

    nsAutoCString headerName(StringHead(header, headerStart.size_backward()));
    headerName.CompressWhitespace();
    if (!NS_IsValidHTTPToken(headerName)) {
      return false;
    }

    nsAutoCString headerValue(Substring(++headerStart, headerEnd));
    if (!NS_IsReasonableHTTPHeaderValue(headerValue)) {
      return false;
    }
    headerValue.CompressWhitespace();

    if (headerName.LowerCaseEqualsLiteral("content-disposition")) {
      nsCCharSeparatedTokenizer tokenizer(headerValue, ';');
      bool seenFormData = false;
      while (tokenizer.hasMoreTokens()) {
        const nsDependentCSubstring& token = tokenizer.nextToken();
        if (token.IsEmpty()) {
          continue;
        }

        if (token.EqualsLiteral("form-data")) {
          seenFormData = true;
          continue;
        }

        if (seenFormData &&
            StringBeginsWith(token, NS_LITERAL_CSTRING("name="))) {
          mName = StringTail(token, token.Length() - 5);
          mName.Trim(" \"");
          continue;
        }

        if (seenFormData &&
            StringBeginsWith(token, NS_LITERAL_CSTRING("filename="))) {
          mFilename = StringTail(token, token.Length() - 9);
          mFilename.Trim(" \"");
          continue;
        }
      }

      if (mName.IsVoid()) {
        // Could not parse a valid entry name.
        return false;
      }
    } else if (headerName.LowerCaseEqualsLiteral("content-type")) {
      mContentType = headerValue;
    }

    return true;
  }