extensions/spellcheck/hunspell/src/hunzip.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /******* BEGIN LICENSE BLOCK *******
     2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
     3  * 
     4  * The contents of this file are subject to the Mozilla Public License Version
     5  * 1.1 (the "License"); you may not use this file except in compliance with
     6  * the License. You may obtain a copy of the License at
     7  * http://www.mozilla.org/MPL/
     8  * 
     9  * Software distributed under the License is distributed on an "AS IS" basis,
    10  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    11  * for the specific language governing rights and limitations under the
    12  * License.
    13  * 
    14  * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
    15  * and László Németh (Hunspell). Portions created by the Initial Developers
    16  * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
    17  * 
    18  * Contributor(s): László Németh (nemethl@gyorsposta.hu)
    19  *                 Caolan McNamara (caolanm@redhat.com)
    20  * 
    21  * Alternatively, the contents of this file may be used under the terms of
    22  * either the GNU General Public License Version 2 or later (the "GPL"), or
    23  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    24  * in which case the provisions of the GPL or the LGPL are applicable instead
    25  * of those above. If you wish to allow use of your version of this file only
    26  * under the terms of either the GPL or the LGPL, and not to allow others to
    27  * use your version of this file under the terms of the MPL, indicate your
    28  * decision by deleting the provisions above and replace them with the notice
    29  * and other provisions required by the GPL or the LGPL. If you do not delete
    30  * the provisions above, a recipient may use your version of this file under
    31  * the terms of any one of the MPL, the GPL or the LGPL.
    32  *
    33  ******* END LICENSE BLOCK *******/
    35 #include <stdlib.h> 
    36 #include <string.h>
    37 #include <stdio.h> 
    39 #include "hunzip.hxx"
    41 #define CODELEN  65536
    42 #define BASEBITREC 5000
    44 #define UNCOMPRESSED '\002'
    45 #define MAGIC "hz0"
    46 #define MAGIC_ENCRYPT "hz1"
    47 #define MAGICLEN (sizeof(MAGIC) - 1)
    49 int Hunzip::fail(const char * err, const char * par) {
    50     fprintf(stderr, err, par);
    51     return -1;
    52 }
    54 Hunzip::Hunzip(const char * file, const char * key) {
    55     bufsiz = 0;
    56     lastbit = 0;
    57     inc = 0;
    58     outc = 0;
    59     dec = NULL;
    60     fin = NULL;
    61     filename = (char *) malloc(strlen(file) + 1);
    62     if (filename) strcpy(filename, file);
    63     if (getcode(key) == -1) bufsiz = -1;
    64     else bufsiz = getbuf();
    65 }
    67 int Hunzip::getcode(const char * key) {
    68     unsigned char c[2];
    69     int i, j, n, p;
    70     int allocatedbit = BASEBITREC;
    71     const char * enc = key;
    73     if (!filename) return -1;
    75     fin = fopen(filename, "rb");
    76     if (!fin) return -1;
    78     // read magic number
    79     if ((fread(in, 1, 3, fin) < MAGICLEN)
    80         || !(strncmp(MAGIC, in, MAGICLEN) == 0 ||
    81                 strncmp(MAGIC_ENCRYPT, in, MAGICLEN) == 0)) {
    82             return fail(MSG_FORMAT, filename);
    83     }
    85     // check encryption
    86     if (strncmp(MAGIC_ENCRYPT, in, MAGICLEN) == 0) {
    87         unsigned char cs;
    88         if (!key) return fail(MSG_KEY, filename);
    89         if (fread(&c, 1, 1, fin) < 1) return fail(MSG_FORMAT, filename);
    90         for (cs = 0; *enc; enc++) cs ^= *enc;
    91         if (cs != c[0]) return fail(MSG_KEY, filename);
    92         enc = key;
    93     } else key = NULL;
    95     // read record count
    96     if (fread(&c, 1, 2, fin) < 2) return fail(MSG_FORMAT, filename);
    98     if (key) {
    99         c[0] ^= *enc;
   100         if (*(++enc) == '\0') enc = key;
   101         c[1] ^= *enc;
   102     }        
   104     n = ((int) c[0] << 8) + c[1];
   105     dec = (struct bit *) malloc(BASEBITREC * sizeof(struct bit));
   106     if (!dec) return fail(MSG_MEMORY, filename);
   107     dec[0].v[0] = 0;
   108     dec[0].v[1] = 0;
   110     // read codes
   111     for (i = 0; i < n; i++) {
   112         unsigned char l;
   113         if (fread(c, 1, 2, fin) < 2) return fail(MSG_FORMAT, filename);
   114         if (key) {
   115             if (*(++enc) == '\0') enc = key;
   116             c[0] ^= *enc;
   117             if (*(++enc) == '\0') enc = key;            
   118             c[1] ^= *enc;
   119         }        
   120         if (fread(&l, 1, 1, fin) < 1) return fail(MSG_FORMAT, filename);
   121         if (key) {
   122             if (*(++enc) == '\0') enc = key;
   123             l ^= *enc;
   124         }
   125         if (fread(in, 1, l/8+1, fin) < (size_t) l/8+1) return fail(MSG_FORMAT, filename);
   126         if (key) for (j = 0; j <= l/8; j++) {
   127             if (*(++enc) == '\0') enc = key;
   128             in[j] ^= *enc;
   129         }
   130         p = 0;
   131         for (j = 0; j < l; j++) {
   132             int b = (in[j/8] & (1 << (7 - (j % 8)))) ? 1 : 0;
   133             int oldp = p;
   134             p = dec[p].v[b];
   135             if (p == 0) {
   136                 lastbit++;
   137                 if (lastbit == allocatedbit) {
   138                     allocatedbit += BASEBITREC;
   139                     dec = (struct bit *) realloc(dec, allocatedbit * sizeof(struct bit));
   140                 }
   141                 dec[lastbit].v[0] = 0;
   142                 dec[lastbit].v[1] = 0;
   143                 dec[oldp].v[b] = lastbit;
   144                 p = lastbit;
   145             }
   146         }
   147         dec[p].c[0] = c[0];
   148         dec[p].c[1] = c[1];
   149     }
   150     return 0;
   151 }
   153 Hunzip::~Hunzip()
   154 {
   155     if (dec) free(dec);
   156     if (fin) fclose(fin);
   157     if (filename) free(filename);
   158 }
   160 int Hunzip::getbuf() {
   161     int p = 0;
   162     int o = 0;
   163     do {
   164         if (inc == 0) inbits = fread(in, 1, BUFSIZE, fin) * 8;
   165         for (; inc < inbits; inc++) {
   166             int b = (in[inc / 8] & (1 << (7 - (inc % 8)))) ? 1 : 0;
   167             int oldp = p;
   168             p = dec[p].v[b];
   169             if (p == 0) {
   170                 if (oldp == lastbit) {
   171                     fclose(fin);
   172                     fin = NULL;
   173                     // add last odd byte
   174                     if (dec[lastbit].c[0]) out[o++]  = dec[lastbit].c[1];
   175                     return o;
   176                 }
   177                 out[o++] = dec[oldp].c[0];
   178                 out[o++] = dec[oldp].c[1];
   179                 if (o == BUFSIZE) return o;
   180                 p = dec[p].v[b];
   181             }
   182         }
   183         inc = 0;
   184     } while (inbits == BUFSIZE * 8);
   185     return fail(MSG_FORMAT, filename);
   186 }
   188 const char * Hunzip::getline() {
   189     char linebuf[BUFSIZE];
   190     int l = 0, eol = 0, left = 0, right = 0;
   191     if (bufsiz == -1) return NULL;
   192     while (l < bufsiz && !eol) {
   193         linebuf[l++] = out[outc];
   194         switch (out[outc]) {
   195             case '\t': break;
   196             case 31: { // escape
   197                 if (++outc == bufsiz) {
   198                     bufsiz = getbuf();
   199                     outc = 0;
   200                 }
   201                 linebuf[l - 1] = out[outc];
   202                 break;
   203             }
   204             case ' ': break;
   205             default: if (((unsigned char) out[outc]) < 47) {
   206                 if (out[outc] > 32) {
   207                     right = out[outc] - 31;
   208                     if (++outc == bufsiz) {
   209                         bufsiz = getbuf();
   210                         outc = 0;
   211                     }
   212                 }
   213                 if (out[outc] == 30) left = 9; else left = out[outc];
   214                 linebuf[l-1] = '\n';
   215                 eol = 1;
   216             }
   217         }
   218         if (++outc == bufsiz) {
   219             outc = 0;
   220             bufsiz = fin ? getbuf(): -1;
   221         }
   222     }
   223     if (right) strcpy(linebuf + l - 1, line + strlen(line) - right - 1);
   224     else linebuf[l] = '\0';
   225     strcpy(line + left, linebuf);
   226     return line;
   227 }

mercurial