Exemplo n.º 1
0
static inline int HexNibbleValue( const char* c )
{
   int h = HexDigitValue( c[0] );
   if ( h < 0 )
      return -1;

   int l = HexDigitValue( c[1] );
   if ( l < 0 )
      return -1;

   return (h << 4) + l;
}
Exemplo n.º 2
0
int HexStrToInt64(const char *string, uint64_t *dest){
    while(*string!='\0'){
        if(!IsHexDigit(*string)) return -1;
        
        dest[0]<<=4;
        dest[0]+=HexDigitValue(*string);
        string++;
    }
    return 1;
}
Exemplo n.º 3
0
PRBool
nsCSSScanner::ParseURange(PRInt32 aChar, nsCSSToken& aResult)
{
  PRInt32 intro2 = Read();
  PRInt32 ch = Peek();

  // We should only ever be called if these things are true.
  NS_ASSERTION(aChar == 'u' || aChar == 'U',
               "unicode-range called with improper introducer (U)");
  NS_ASSERTION(intro2 == '+',
               "unicode-range called with improper introducer (+)");

  // If the character immediately after the '+' is not a hex digit or
  // '?', this is not really a unicode-range token; push everything
  // back and scan the U as an ident.
  if (!IsHexDigit(ch) && ch != '?') {
    Pushback(intro2);
    Pushback(aChar);
    return ParseIdent(aChar, aResult);
  }

  aResult.mIdent.Truncate();
  aResult.mIdent.Append(aChar);
  aResult.mIdent.Append(intro2);

  PRBool valid = PR_TRUE;
  PRBool haveQues = PR_FALSE;
  PRUint32 low = 0;
  PRUint32 high = 0;
  int i = 0;

  for (;;) {
    ch = Read();
    i++;
    if (i == 7 || !(IsHexDigit(ch) || ch == '?')) {
      break;
    }

    aResult.mIdent.Append(ch);
    if (IsHexDigit(ch)) {
      if (haveQues) {
        valid = PR_FALSE; // all question marks should be at the end
      }
      low = low*16 + HexDigitValue(ch);
      high = high*16 + HexDigitValue(ch);
    } else {
      haveQues = PR_TRUE;
      low = low*16 + 0x0;
      high = high*16 + 0xF;
    }
  }

  if (ch == '-' && IsHexDigit(Peek())) {
    if (haveQues) {
      valid = PR_FALSE;
    }

    aResult.mIdent.Append(ch);
    high = 0;
    i = 0;
    for (;;) {
      ch = Read();
      i++;
      if (i == 7 || !IsHexDigit(ch)) {
        break;
      }
      aResult.mIdent.Append(ch);
      high = high*16 + HexDigitValue(ch);
    }
  }
  Pushback(ch);

  aResult.mInteger = low;
  aResult.mInteger2 = high;
  aResult.mIntegerValid = valid;
  aResult.mType = eCSSToken_URange;
  return PR_TRUE;
}
Exemplo n.º 4
0
void
nsCSSScanner::ParseAndAppendEscape(nsString& aOutput)
{
  PRInt32 ch = Peek();
  if (ch < 0) {
    aOutput.Append(CSS_ESCAPE);
    return;
  }
  if (IsHexDigit(ch)) {
    PRInt32 rv = 0;
    int i;
    for (i = 0; i < 6; i++) { // up to six digits
      ch = Read();
      if (ch < 0) {
        // Whoops: error or premature eof
        break;
      }
      if (!IsHexDigit(ch) && !IsWhitespace(ch)) {
        Pushback(ch);
        break;
      } else if (IsHexDigit(ch)) {
        rv = rv * 16 + HexDigitValue(ch);
      } else {
        NS_ASSERTION(IsWhitespace(ch), "bad control flow");
        // single space ends escape
        break;
      }
    }
    if (6 == i) { // look for trailing whitespace and eat it
      ch = Peek();
      if (IsWhitespace(ch)) {
        (void) Read();
      }
    }
    NS_ASSERTION(rv >= 0, "How did rv become negative?");
    // "[at most six hexadecimal digits following a backslash] stand
    // for the ISO 10646 character with that number, which must not be
    // zero. (It is undefined in CSS 2.1 what happens if a style sheet
    // does contain a character with Unicode codepoint zero.)"
    //   -- CSS2.1 section 4.1.3
    //
    // Silently deleting \0 opens a content-filtration loophole (see
    // bug 228856), so what we do instead is pretend the "cancels the
    // meaning of special characters" rule applied.
    if (rv > 0) {
      AppendUCS4ToUTF16(ENSURE_VALID_CHAR(rv), aOutput);
    } else {
      while (i--)
        aOutput.Append('0');
      if (IsWhitespace(ch))
        Pushback(ch);
    }
    return;
  } 
  // "Any character except a hexidecimal digit can be escaped to
  // remove its special meaning by putting a backslash in front"
  // -- CSS1 spec section 7.1
  ch = Read();  // Consume the escaped character
  if ((ch > 0) && (ch != '\n')) {
    aOutput.Append(ch);
  }
}
Exemplo n.º 5
0
/**
 * If there is a valid escape sequence starting at the current read
 * position, consume it, decode it, append the result to |aOutput|,
 * and return true.  Otherwise, consume nothing, leave |aOutput|
 * unmodified, and return false.  If |aInString| is true, accept the
 * additional form of escape sequence allowed within string-like tokens.
 */
bool
nsCSSScanner::GatherEscape(nsString& aOutput, bool aInString)
{
  MOZ_ASSERT(Peek() == '\\', "should not have been called");
  int32_t ch = Peek(1);
  if (ch < 0) {
    // If we are in a string (or a url() containing a string), we want to drop
    // the backslash on the floor.  Otherwise, we want to treat it as a U+FFFD
    // character.
    Advance();
    if (aInString) {
      SetEOFCharacters(eEOFCharacters_DropBackslash);
    } else {
      aOutput.Append(UCS2_REPLACEMENT_CHAR);
      SetEOFCharacters(eEOFCharacters_ReplacementChar);
    }
    return true;
  }
  if (IsVertSpace(ch)) {
    if (aInString) {
      // In strings (and in url() containing a string), escaped
      // newlines are completely removed, to allow splitting over
      // multiple lines.
      Advance();
      AdvanceLine();
      return true;
    }
    // Outside of strings, backslash followed by a newline is not an escape.
    return false;
  }

  if (!IsHexDigit(ch)) {
    // "Any character (except a hexadecimal digit, linefeed, carriage
    // return, or form feed) can be escaped with a backslash to remove
    // its special meaning." -- CSS2.1 section 4.1.3
    Advance(2);
    if (ch == 0) {
      aOutput.Append(UCS2_REPLACEMENT_CHAR);
    } else {
      aOutput.Append(ch);
    }
    return true;
  }

  // "[at most six hexadecimal digits following a backslash] stand
  // for the ISO 10646 character with that number, which must not be
  // zero. (It is undefined in CSS 2.1 what happens if a style sheet
  // does contain a character with Unicode codepoint zero.)"
  //   -- CSS2.1 section 4.1.3

  // At this point we know we have \ followed by at least one
  // hexadecimal digit, therefore the escape sequence is valid and we
  // can go ahead and consume the backslash.
  Advance();
  uint32_t val = 0;
  int i = 0;
  do {
    val = val * 16 + HexDigitValue(ch);
    i++;
    Advance();
    ch = Peek();
  } while (i < 6 && IsHexDigit(ch));

  // "Interpret the hex digits as a hexadecimal number. If this number is zero,
  // or is greater than the maximum allowed codepoint, return U+FFFD
  // REPLACEMENT CHARACTER" -- CSS Syntax Level 3
  if (MOZ_UNLIKELY(val == 0)) {
    aOutput.Append(UCS2_REPLACEMENT_CHAR);
  } else {
    AppendUCS4ToUTF16(ENSURE_VALID_CHAR(val), aOutput);
  }

  // Consume exactly one whitespace character after a
  // hexadecimal escape sequence.
  if (IsVertSpace(ch)) {
    AdvanceLine();
  } else if (IsHorzSpace(ch)) {
    Advance();
  }
  return true;
}
Exemplo n.º 6
0
/**
 * Scan a unicode-range token.  These match the regular expression
 *
 *     u\+[0-9a-f?]{1,6}(-[0-9a-f]{1,6})?
 *
 * However, some such tokens are "invalid".  There are three valid forms:
 *
 *     u+[0-9a-f]{x}              1 <= x <= 6
 *     u+[0-9a-f]{x}\?{y}         1 <= x+y <= 6
 *     u+[0-9a-f]{x}-[0-9a-f]{y}  1 <= x <= 6, 1 <= y <= 6
 *
 * All unicode-range tokens have their text recorded in mIdent; valid ones
 * are also decoded into mInteger and mInteger2, and mIntegerValid is set.
 * Note that this does not validate the numeric range, only the syntactic
 * form.
 */
bool
nsCSSScanner::ScanURange(nsCSSToken& aResult)
{
  int32_t intro1 = Peek();
  int32_t intro2 = Peek(1);
  int32_t ch = Peek(2);

  MOZ_ASSERT((intro1 == 'u' || intro1 == 'U') &&
             intro2 == '+' &&
             (IsHexDigit(ch) || ch == '?'),
             "should not have been called");

  aResult.mIdent.Append(intro1);
  aResult.mIdent.Append(intro2);
  Advance(2);

  bool valid = true;
  bool haveQues = false;
  uint32_t low = 0;
  uint32_t high = 0;
  int i = 0;

  do {
    aResult.mIdent.Append(ch);
    if (IsHexDigit(ch)) {
      if (haveQues) {
        valid = false; // All question marks should be at the end.
      }
      low = low*16 + HexDigitValue(ch);
      high = high*16 + HexDigitValue(ch);
    } else {
      haveQues = true;
      low = low*16 + 0x0;
      high = high*16 + 0xF;
    }

    i++;
    Advance();
    ch = Peek();
  } while (i < 6 && (IsHexDigit(ch) || ch == '?'));

  if (ch == '-' && IsHexDigit(Peek(1))) {
    if (haveQues) {
      valid = false;
    }

    aResult.mIdent.Append(ch);
    Advance();
    ch = Peek();
    high = 0;
    i = 0;
    do {
      aResult.mIdent.Append(ch);
      high = high*16 + HexDigitValue(ch);

      i++;
      Advance();
      ch = Peek();
    } while (i < 6 && IsHexDigit(ch));
  }

  aResult.mInteger = low;
  aResult.mInteger2 = high;
  aResult.mIntegerValid = valid;
  aResult.mType = eCSSToken_URange;
  return true;
}