tor-browser

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

csr2022.cpp (6281B)


      1 // © 2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 /*
      4 **********************************************************************
      5 *   Copyright (C) 2005-2016, International Business Machines
      6 *   Corporation and others.  All Rights Reserved.
      7 **********************************************************************
      8 */
      9 
     10 #include "unicode/utypes.h"
     11 
     12 #if !UCONFIG_NO_CONVERSION
     13 
     14 #include "cmemory.h"
     15 #include "cstring.h"
     16 
     17 #include "csr2022.h"
     18 #include "csmatch.h"
     19 
     20 U_NAMESPACE_BEGIN
     21 
     22 /**
     23 * Matching function shared among the 2022 detectors JP, CN and KR
     24 * Counts up the number of legal and unrecognized escape sequences in
     25 * the sample of text, and computes a score based on the total number &
     26 * the proportion that fit the encoding.
     27 * 
     28 * 
     29 * @param text the byte buffer containing text to analyse
     30 * @param textLen  the size of the text in the byte.
     31 * @param escapeSequences the byte escape sequences to test for.
     32 * @return match quality, in the range of 0-100.
     33 */
     34 int32_t CharsetRecog_2022::match_2022(const uint8_t *text, int32_t textLen, const uint8_t escapeSequences[][5], int32_t escapeSequences_length) const
     35 {
     36    int32_t i, j;
     37    int32_t escN;
     38    int32_t hits   = 0;
     39    int32_t misses = 0;
     40    int32_t shifts = 0;
     41    int32_t quality;
     42 
     43    i = 0;
     44    while(i < textLen) {
     45        if(text[i] == 0x1B) {
     46            escN = 0;
     47            while(escN < escapeSequences_length) {
     48                const uint8_t *seq = escapeSequences[escN];
     49                int32_t seq_length = static_cast<int32_t>(uprv_strlen((const char*)seq));
     50 
     51                if (textLen-i >= seq_length) {
     52                    j = 1;
     53                    while(j < seq_length) {
     54                        if(seq[j] != text[i+j]) {
     55                            goto checkEscapes;
     56                        }
     57 
     58                        j += 1;
     59                    }
     60 
     61                    hits += 1;
     62                    i += seq_length-1;
     63                    goto scanInput;
     64                }
     65                // else we ran out of string to compare this time.
     66 checkEscapes:
     67                escN += 1;
     68            }
     69 
     70            misses += 1;
     71        }
     72 
     73        if( text[i]== 0x0e || text[i] == 0x0f){
     74            shifts += 1;
     75        }
     76 
     77 scanInput:
     78        i += 1;
     79    }
     80 
     81    if (hits == 0) {
     82        return 0;
     83    }
     84 
     85    //
     86    // Initial quality is based on relative proportion of recognized vs.
     87    //   unrecognized escape sequences. 
     88    //   All good:  quality = 100;
     89    //   half or less good: quality = 0;
     90    //   linear inbetween.
     91    quality = (100*hits - 100*misses) / (hits + misses);
     92 
     93    // Back off quality if there were too few escape sequences seen.
     94    //   Include shifts in this computation, so that KR does not get penalized
     95    //   for having only a single Escape sequence, but many shifts.
     96    if (hits+shifts < 5) {
     97        quality -= (5-(hits+shifts))*10;
     98    }
     99 
    100    if (quality < 0) {
    101        quality = 0;
    102    }
    103 
    104    return quality;
    105 }
    106 
    107 
    108 static const uint8_t escapeSequences_2022JP[][5] = {
    109    {0x1b, 0x24, 0x28, 0x43, 0x00},   // KS X 1001:1992
    110    {0x1b, 0x24, 0x28, 0x44, 0x00},   // JIS X 212-1990
    111    {0x1b, 0x24, 0x40, 0x00, 0x00},   // JIS C 6226-1978
    112    {0x1b, 0x24, 0x41, 0x00, 0x00},   // GB 2312-80
    113    {0x1b, 0x24, 0x42, 0x00, 0x00},   // JIS X 208-1983
    114    {0x1b, 0x26, 0x40, 0x00, 0x00},   // JIS X 208 1990, 1997
    115    {0x1b, 0x28, 0x42, 0x00, 0x00},   // ASCII
    116    {0x1b, 0x28, 0x48, 0x00, 0x00},   // JIS-Roman
    117    {0x1b, 0x28, 0x49, 0x00, 0x00},   // Half-width katakana
    118    {0x1b, 0x28, 0x4a, 0x00, 0x00},   // JIS-Roman
    119    {0x1b, 0x2e, 0x41, 0x00, 0x00},   // ISO 8859-1
    120    {0x1b, 0x2e, 0x46, 0x00, 0x00}    // ISO 8859-7
    121 };
    122 
    123 #if !UCONFIG_ONLY_HTML_CONVERSION
    124 static const uint8_t escapeSequences_2022KR[][5] = {
    125    {0x1b, 0x24, 0x29, 0x43, 0x00}   
    126 };
    127 
    128 static const uint8_t escapeSequences_2022CN[][5] = {
    129    {0x1b, 0x24, 0x29, 0x41, 0x00},   // GB 2312-80
    130    {0x1b, 0x24, 0x29, 0x47, 0x00},   // CNS 11643-1992 Plane 1
    131    {0x1b, 0x24, 0x2A, 0x48, 0x00},   // CNS 11643-1992 Plane 2
    132    {0x1b, 0x24, 0x29, 0x45, 0x00},   // ISO-IR-165
    133    {0x1b, 0x24, 0x2B, 0x49, 0x00},   // CNS 11643-1992 Plane 3
    134    {0x1b, 0x24, 0x2B, 0x4A, 0x00},   // CNS 11643-1992 Plane 4
    135    {0x1b, 0x24, 0x2B, 0x4B, 0x00},   // CNS 11643-1992 Plane 5
    136    {0x1b, 0x24, 0x2B, 0x4C, 0x00},   // CNS 11643-1992 Plane 6
    137    {0x1b, 0x24, 0x2B, 0x4D, 0x00},   // CNS 11643-1992 Plane 7
    138    {0x1b, 0x4e, 0x00, 0x00, 0x00},   // SS2
    139    {0x1b, 0x4f, 0x00, 0x00, 0x00},   // SS3
    140 };
    141 #endif
    142 
    143 CharsetRecog_2022JP::~CharsetRecog_2022JP() {}
    144 
    145 const char *CharsetRecog_2022JP::getName() const {
    146    return "ISO-2022-JP";
    147 }
    148 
    149 UBool CharsetRecog_2022JP::match(InputText *textIn, CharsetMatch *results) const {
    150    int32_t confidence = match_2022(textIn->fInputBytes, 
    151                                    textIn->fInputLen, 
    152                                    escapeSequences_2022JP, 
    153                                    UPRV_LENGTHOF(escapeSequences_2022JP));
    154    results->set(textIn, this, confidence);
    155    return (confidence > 0);
    156 }
    157 
    158 #if !UCONFIG_ONLY_HTML_CONVERSION
    159 CharsetRecog_2022KR::~CharsetRecog_2022KR() {}
    160 
    161 const char *CharsetRecog_2022KR::getName() const {
    162    return "ISO-2022-KR";
    163 }
    164 
    165 UBool CharsetRecog_2022KR::match(InputText *textIn, CharsetMatch *results) const {
    166    int32_t confidence = match_2022(textIn->fInputBytes, 
    167                                    textIn->fInputLen, 
    168                                    escapeSequences_2022KR, 
    169                                    UPRV_LENGTHOF(escapeSequences_2022KR));
    170    results->set(textIn, this, confidence);
    171    return (confidence > 0);
    172 }
    173 
    174 CharsetRecog_2022CN::~CharsetRecog_2022CN() {}
    175 
    176 const char *CharsetRecog_2022CN::getName() const {
    177    return "ISO-2022-CN";
    178 }
    179 
    180 UBool CharsetRecog_2022CN::match(InputText *textIn, CharsetMatch *results) const {
    181    int32_t confidence = match_2022(textIn->fInputBytes,
    182                                    textIn->fInputLen,
    183                                    escapeSequences_2022CN,
    184                                    UPRV_LENGTHOF(escapeSequences_2022CN));
    185    results->set(textIn, this, confidence);
    186    return (confidence > 0);
    187 }
    188 #endif
    189 
    190 CharsetRecog_2022::~CharsetRecog_2022() {
    191    // nothing to do
    192 }
    193 
    194 U_NAMESPACE_END
    195 #endif