tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Identifier.cpp (3866B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      3 * This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "util/Identifier.h"
      8 
      9 #include "mozilla/Assertions.h"  // MOZ_ASSERT
     10 
     11 #include <stddef.h>  // size_t
     12 
     13 #include "js/GCAPI.h"      // JS::AutoCheckCannotGC
     14 #include "js/TypeDecls.h"  // JS::Latin1Char
     15 #include "util/Unicode.h"  // unicode::{IsIdentifierStart, IsIdentifierPart, IsIdentifierStartASCII, IsIdentifierPartASCII, IsLeadSurrogate, IsTrailSurrogate, UTF16Decode}
     16 #include "vm/StringType.h"  // JSLinearString
     17 
     18 using namespace js;
     19 
     20 bool js::IsIdentifier(const JSLinearString* str) {
     21  JS::AutoCheckCannotGC nogc;
     22  MOZ_ASSERT(str);
     23  if (str->hasLatin1Chars()) {
     24    return IsIdentifier(str->latin1Chars(nogc), str->length());
     25  }
     26  return IsIdentifier(str->twoByteChars(nogc), str->length());
     27 }
     28 
     29 bool js::IsIdentifierNameOrPrivateName(const JSLinearString* str) {
     30  JS::AutoCheckCannotGC nogc;
     31  MOZ_ASSERT(str);
     32  if (str->hasLatin1Chars()) {
     33    return IsIdentifierNameOrPrivateName(str->latin1Chars(nogc), str->length());
     34  }
     35  return IsIdentifierNameOrPrivateName(str->twoByteChars(nogc), str->length());
     36 }
     37 
     38 bool js::IsIdentifier(const JS::Latin1Char* chars, size_t length) {
     39  if (length == 0) {
     40    return false;
     41  }
     42 
     43  if (!unicode::IsIdentifierStart(char16_t(*chars))) {
     44    return false;
     45  }
     46 
     47  const JS::Latin1Char* end = chars + length;
     48  while (++chars != end) {
     49    if (!unicode::IsIdentifierPart(char16_t(*chars))) {
     50      return false;
     51    }
     52  }
     53 
     54  return true;
     55 }
     56 
     57 bool js::IsIdentifierASCII(char c) {
     58  return unicode::IsIdentifierStartASCII(c);
     59 }
     60 
     61 bool js::IsIdentifierASCII(char c1, char c2) {
     62  return unicode::IsIdentifierStartASCII(c1) &&
     63         unicode::IsIdentifierPartASCII(c2);
     64 }
     65 
     66 bool js::IsIdentifierNameOrPrivateName(const JS::Latin1Char* chars,
     67                                       size_t length) {
     68  if (length == 0) {
     69    return false;
     70  }
     71 
     72  // Skip over any private name marker.
     73  if (*chars == '#') {
     74    ++chars;
     75    --length;
     76  }
     77 
     78  return IsIdentifier(chars, length);
     79 }
     80 
     81 static char32_t GetSingleCodePoint(const char16_t** p, const char16_t* end) {
     82  using namespace js;
     83 
     84  if (MOZ_UNLIKELY(unicode::IsLeadSurrogate(**p)) && *p + 1 < end) {
     85    char16_t lead = **p;
     86    char16_t maybeTrail = *(*p + 1);
     87    if (unicode::IsTrailSurrogate(maybeTrail)) {
     88      *p += 2;
     89      return unicode::UTF16Decode(lead, maybeTrail);
     90    }
     91  }
     92 
     93  char32_t codePoint = **p;
     94  (*p)++;
     95  return codePoint;
     96 }
     97 
     98 bool js::IsIdentifier(const char16_t* chars, size_t length) {
     99  if (length == 0) {
    100    return false;
    101  }
    102 
    103  const char16_t* p = chars;
    104  const char16_t* end = chars + length;
    105  char32_t codePoint;
    106 
    107  codePoint = GetSingleCodePoint(&p, end);
    108  if (!unicode::IsIdentifierStart(codePoint)) {
    109    return false;
    110  }
    111 
    112  while (p < end) {
    113    codePoint = GetSingleCodePoint(&p, end);
    114    if (!unicode::IsIdentifierPart(codePoint)) {
    115      return false;
    116    }
    117  }
    118 
    119  return true;
    120 }
    121 
    122 bool js::IsIdentifierNameOrPrivateName(const char16_t* chars, size_t length) {
    123  if (length == 0) {
    124    return false;
    125  }
    126 
    127  const char16_t* p = chars;
    128  const char16_t* end = chars + length;
    129  char32_t codePoint;
    130 
    131  codePoint = GetSingleCodePoint(&p, end);
    132 
    133  // Skip over any private name marker.
    134  if (codePoint == '#') {
    135    // The identifier part of a private name mustn't be empty.
    136    if (length == 1) {
    137      return false;
    138    }
    139 
    140    codePoint = GetSingleCodePoint(&p, end);
    141  }
    142 
    143  if (!unicode::IsIdentifierStart(codePoint)) {
    144    return false;
    145  }
    146 
    147  while (p < end) {
    148    codePoint = GetSingleCodePoint(&p, end);
    149    if (!unicode::IsIdentifierPart(codePoint)) {
    150      return false;
    151    }
    152  }
    153 
    154  return true;
    155 }