LCOV - code coverage report
Current view: top level - js/src/util - Text.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 25 135 18.5 %
Date: 2018-08-07 16:42:27 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2             :  * vim: set ts=8 sts=4 et sw=4 tw=99:
       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/Text.h"
       8             : 
       9             : #include "mozilla/PodOperations.h"
      10             : 
      11             : #include "gc/GC.h"
      12             : #include "js/GCAPI.h"
      13             : #include "vm/JSContext.h"
      14             : #include "vm/StringType.h"
      15             : 
      16             : using namespace JS;
      17             : using namespace js;
      18             : using js::gc::AutoSuppressGC;
      19             : using mozilla::PodCopy;
      20             : 
      21             : template <typename CharT>
      22             : const CharT*
      23           0 : js_strchr_limit(const CharT* s, char16_t c, const CharT* limit)
      24             : {
      25           0 :     while (s < limit) {
      26           0 :         if (*s == c)
      27             :             return s;
      28           0 :         s++;
      29             :     }
      30             :     return nullptr;
      31             : }
      32             : 
      33             : template const Latin1Char*
      34             : js_strchr_limit(const Latin1Char* s, char16_t c, const Latin1Char* limit);
      35             : 
      36             : template const char16_t*
      37             : js_strchr_limit(const char16_t* s, char16_t c, const char16_t* limit);
      38             : 
      39             : int32_t
      40           0 : js_fputs(const char16_t* s, FILE* f)
      41             : {
      42           0 :     while (*s != 0) {
      43           0 :         if (fputwc(wchar_t(*s), f) == WEOF)
      44             :             return WEOF;
      45           0 :         s++;
      46             :     }
      47             :     return 1;
      48             : }
      49             : 
      50             : UniqueChars
      51           1 : js::DuplicateString(JSContext* cx, const char* s)
      52             : {
      53        1266 :     size_t n = strlen(s) + 1;
      54        1266 :     auto ret = cx->make_pod_array<char>(n);
      55        1266 :     if (!ret)
      56             :         return ret;
      57           0 :     PodCopy(ret.get(), s, n);
      58        1266 :     return ret;
      59             : }
      60             : 
      61             : UniqueTwoByteChars
      62          20 : js::DuplicateString(JSContext* cx, const char16_t* s)
      63             : {
      64           0 :     size_t n = js_strlen(s) + 1;
      65          20 :     auto ret = cx->make_pod_array<char16_t>(n);
      66          20 :     if (!ret)
      67             :         return ret;
      68           0 :     PodCopy(ret.get(), s, n);
      69          20 :     return ret;
      70             : }
      71             : 
      72             : UniqueChars
      73       15438 : js::DuplicateString(const char* s)
      74             : {
      75           0 :     size_t n = strlen(s) + 1;
      76       30876 :     UniqueChars ret(js_pod_malloc<char>(n));
      77       15438 :     if (!ret)
      78             :         return ret;
      79           0 :     PodCopy(ret.get(), s, n);
      80       15438 :     return ret;
      81             : }
      82             : 
      83             : UniqueChars
      84           0 : js::DuplicateString(const char* s, size_t n)
      85             : {
      86           0 :     UniqueChars ret(js_pod_malloc<char>(n + 1));
      87           0 :     if (!ret)
      88             :         return nullptr;
      89           0 :     PodCopy(ret.get(), s, n);
      90           0 :     ret[n] = 0;
      91             :     return ret;
      92             : }
      93             : 
      94             : UniqueTwoByteChars
      95           0 : js::DuplicateString(const char16_t* s)
      96             : {
      97           0 :     return DuplicateString(s, js_strlen(s));
      98             : }
      99             : 
     100             : UniqueTwoByteChars
     101           0 : js::DuplicateString(const char16_t* s, size_t n)
     102             : {
     103           0 :     UniqueTwoByteChars ret(js_pod_malloc<char16_t>(n + 1));
     104          36 :     if (!ret)
     105             :         return nullptr;
     106          36 :     PodCopy(ret.get(), s, n);
     107           0 :     ret[n] = 0;
     108             :     return ret;
     109             : }
     110             : 
     111             : char16_t*
     112           0 : js::InflateString(JSContext* cx, const char* bytes, size_t length)
     113             : {
     114         299 :     char16_t* chars = cx->pod_malloc<char16_t>(length + 1);
     115         299 :     if (!chars)
     116             :         return nullptr;
     117         299 :     CopyAndInflateChars(chars, bytes, length);
     118           0 :     chars[length] = 0;
     119         299 :     return chars;
     120             : }
     121             : 
     122             : template <typename CharT>
     123             : bool
     124           0 : js::DeflateStringToBuffer(JSContext* maybecx, const CharT* src, size_t srclen,
     125             :                           char* dst, size_t* dstlenp)
     126             : {
     127        1695 :     size_t dstlen = *dstlenp;
     128        1695 :     if (srclen > dstlen) {
     129           0 :         for (size_t i = 0; i < dstlen; i++)
     130           0 :             dst[i] = char(src[i]);
     131           0 :         if (maybecx) {
     132           0 :             AutoSuppressGC suppress(maybecx);
     133           0 :             JS_ReportErrorNumberASCII(maybecx, GetErrorMessage, nullptr,
     134             :                                       JSMSG_BUFFER_TOO_SMALL);
     135             :         }
     136             :         return false;
     137             :     }
     138           1 :     for (size_t i = 0; i < srclen; i++)
     139           1 :         dst[i] = char(src[i]);
     140        1695 :     *dstlenp = srclen;
     141        1695 :     return true;
     142             : }
     143             : 
     144             : template bool
     145             : js::DeflateStringToBuffer(JSContext* maybecx, const Latin1Char* src, size_t srclen,
     146             :                           char* dst, size_t* dstlenp);
     147             : 
     148             : template bool
     149             : js::DeflateStringToBuffer(JSContext* maybecx, const char16_t* src, size_t srclen,
     150             :                           char* dst, size_t* dstlenp);
     151             : 
     152             : /*
     153             :  * Convert one UCS-4 char and write it into a UTF-8 buffer, which must be at
     154             :  * least 4 bytes long.  Return the number of UTF-8 bytes of data written.
     155             :  */
     156             : uint32_t
     157           0 : js::OneUcs4ToUtf8Char(uint8_t* utf8Buffer, uint32_t ucs4Char)
     158             : {
     159           0 :     MOZ_ASSERT(ucs4Char <= unicode::NonBMPMax);
     160             : 
     161           0 :     if (ucs4Char < 0x80) {
     162           0 :         utf8Buffer[0] = uint8_t(ucs4Char);
     163           0 :         return 1;
     164             :     }
     165             : 
     166           0 :     uint32_t a = ucs4Char >> 11;
     167           0 :     uint32_t utf8Length = 2;
     168           0 :     while (a) {
     169           0 :         a >>= 5;
     170           0 :         utf8Length++;
     171             :     }
     172             : 
     173           0 :     MOZ_ASSERT(utf8Length <= 4);
     174             : 
     175             :     uint32_t i = utf8Length;
     176           0 :     while (--i) {
     177           0 :         utf8Buffer[i] = uint8_t((ucs4Char & 0x3F) | 0x80);
     178           0 :         ucs4Char >>= 6;
     179             :     }
     180             : 
     181           0 :     utf8Buffer[0] = uint8_t(0x100 - (1 << (8 - utf8Length)) + ucs4Char);
     182           0 :     return utf8Length;
     183             : }
     184             : 
     185             : size_t
     186           0 : js::PutEscapedStringImpl(char* buffer, size_t bufferSize, GenericPrinter* out, JSLinearString* str,
     187             :                          uint32_t quote)
     188             : {
     189           0 :     size_t len = str->length();
     190           0 :     AutoCheckCannotGC nogc;
     191           0 :     return str->hasLatin1Chars()
     192           0 :            ? PutEscapedStringImpl(buffer, bufferSize, out, str->latin1Chars(nogc), len, quote)
     193           0 :            : PutEscapedStringImpl(buffer, bufferSize, out, str->twoByteChars(nogc), len, quote);
     194             : }
     195             : 
     196             : template <typename CharT>
     197             : size_t
     198           0 : js::PutEscapedStringImpl(char* buffer, size_t bufferSize, GenericPrinter* out, const CharT* chars,
     199             :                          size_t length, uint32_t quote)
     200             : {
     201             :     enum {
     202             :         STOP, FIRST_QUOTE, LAST_QUOTE, CHARS, ESCAPE_START, ESCAPE_MORE
     203             :     } state;
     204             : 
     205           0 :     MOZ_ASSERT(quote == 0 || quote == '\'' || quote == '"');
     206           0 :     MOZ_ASSERT_IF(!buffer, bufferSize == 0);
     207           0 :     MOZ_ASSERT_IF(out, !buffer);
     208             : 
     209           0 :     if (bufferSize == 0)
     210             :         buffer = nullptr;
     211             :     else
     212           0 :         bufferSize--;
     213             : 
     214           0 :     const CharT* charsEnd = chars + length;
     215           0 :     size_t n = 0;
     216           0 :     state = FIRST_QUOTE;
     217           0 :     unsigned shift = 0;
     218           0 :     unsigned hex = 0;
     219           0 :     unsigned u = 0;
     220           0 :     char c = 0;  /* to quell GCC warnings */
     221             : 
     222             :     for (;;) {
     223           0 :         switch (state) {
     224             :           case STOP:
     225             :             goto stop;
     226             :           case FIRST_QUOTE:
     227             :             state = CHARS;
     228             :             goto do_quote;
     229             :           case LAST_QUOTE:
     230           0 :             state = STOP;
     231             :           do_quote:
     232           0 :             if (quote == 0)
     233             :                 continue;
     234           0 :             c = (char)quote;
     235           0 :             break;
     236             :           case CHARS:
     237           0 :             if (chars == charsEnd) {
     238             :                 state = LAST_QUOTE;
     239             :                 continue;
     240             :             }
     241           0 :             u = *chars++;
     242           0 :             if (u < ' ') {
     243           0 :                 if (u != 0) {
     244           0 :                     const char* escape = strchr(js_EscapeMap, (int)u);
     245           0 :                     if (escape) {
     246           0 :                         u = escape[1];
     247           0 :                         goto do_escape;
     248             :                     }
     249             :                 }
     250             :                 goto do_hex_escape;
     251             :             }
     252           0 :             if (u < 127) {
     253           0 :                 if (u == quote || u == '\\')
     254             :                     goto do_escape;
     255           0 :                 c = (char)u;
     256           0 :             } else if (u < 0x100) {
     257             :                 goto do_hex_escape;
     258             :             } else {
     259             :                 shift = 16;
     260             :                 hex = u;
     261             :                 u = 'u';
     262             :                 goto do_escape;
     263             :             }
     264           0 :             break;
     265             :           do_hex_escape:
     266           0 :             shift = 8;
     267           0 :             hex = u;
     268           0 :             u = 'x';
     269             :           do_escape:
     270           0 :             c = '\\';
     271           0 :             state = ESCAPE_START;
     272           0 :             break;
     273             :           case ESCAPE_START:
     274           0 :             MOZ_ASSERT(' ' <= u && u < 127);
     275           0 :             c = (char)u;
     276           0 :             state = ESCAPE_MORE;
     277           0 :             break;
     278             :           case ESCAPE_MORE:
     279           0 :             if (shift == 0) {
     280             :                 state = CHARS;
     281             :                 continue;
     282             :             }
     283           0 :             shift -= 4;
     284           0 :             u = 0xF & (hex >> shift);
     285           0 :             c = (char)(u + (u < 10 ? '0' : 'A' - 10));
     286           0 :             break;
     287             :         }
     288           0 :         if (buffer) {
     289           0 :             MOZ_ASSERT(n <= bufferSize);
     290           0 :             if (n != bufferSize) {
     291           0 :                 buffer[n] = c;
     292             :             } else {
     293           0 :                 buffer[n] = '\0';
     294           0 :                 buffer = nullptr;
     295             :             }
     296           0 :         } else if (out) {
     297           0 :             if (!out->put(&c, 1))
     298             :                 return size_t(-1);
     299             :         }
     300           0 :         n++;
     301             :     }
     302             :   stop:
     303           0 :     if (buffer)
     304           0 :         buffer[n] = '\0';
     305             :     return n;
     306             : }
     307             : 
     308             : template size_t
     309             : js::PutEscapedStringImpl(char* buffer, size_t bufferSize, GenericPrinter* out, const Latin1Char* chars,
     310             :                          size_t length, uint32_t quote);
     311             : 
     312             : template size_t
     313             : js::PutEscapedStringImpl(char* buffer, size_t bufferSize, GenericPrinter* out, const char* chars,
     314             :                          size_t length, uint32_t quote);
     315             : 
     316             : template size_t
     317             : js::PutEscapedStringImpl(char* buffer, size_t bufferSize, GenericPrinter* out, const char16_t* chars,
     318             :                          size_t length, uint32_t quote);
     319             : 
     320             : template size_t
     321             : js::PutEscapedString(char* buffer, size_t bufferSize, const Latin1Char* chars, size_t length,
     322             :                      uint32_t quote);
     323             : 
     324             : template size_t
     325             : js::PutEscapedString(char* buffer, size_t bufferSize, const char16_t* chars, size_t length,
     326             :                      uint32_t quote);

Generated by: LCOV version 1.13-14-ga5dd952