netwerk/dns/race.c

Wed, 31 Dec 2014 06:55:46 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:46 +0100
changeset 1
ca08bd8f51b2
permissions
-rw-r--r--

Added tag TORBROWSER_REPLICA for changeset 6474c204b198

     1 /*
     2  * Copyright (c) 2000,2001,2002 Japan Network Information Center.
     3  * All rights reserved.
     4  *  
     5  * By using this file, you agree to the terms and conditions set forth bellow.
     6  * 
     7  * 			LICENSE TERMS AND CONDITIONS 
     8  * 
     9  * The following License Terms and Conditions apply, unless a different
    10  * license is obtained from Japan Network Information Center ("JPNIC"),
    11  * a Japanese association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda,
    12  * Chiyoda-ku, Tokyo 101-0047, Japan.
    13  * 
    14  * 1. Use, Modification and Redistribution (including distribution of any
    15  *    modified or derived work) in source and/or binary forms is permitted
    16  *    under this License Terms and Conditions.
    17  * 
    18  * 2. Redistribution of source code must retain the copyright notices as they
    19  *    appear in each source code file, this License Terms and Conditions.
    20  * 
    21  * 3. Redistribution in binary form must reproduce the Copyright Notice,
    22  *    this License Terms and Conditions, in the documentation and/or other
    23  *    materials provided with the distribution.  For the purposes of binary
    24  *    distribution the "Copyright Notice" refers to the following language:
    25  *    "Copyright (c) 2000-2002 Japan Network Information Center.  All rights reserved."
    26  * 
    27  * 4. The name of JPNIC may not be used to endorse or promote products
    28  *    derived from this Software without specific prior written approval of
    29  *    JPNIC.
    30  * 
    31  * 5. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY JPNIC
    32  *    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    33  *    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
    34  *    PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL JPNIC BE LIABLE
    35  *    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    36  *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    37  *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
    38  *    BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
    39  *    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
    40  *    OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
    41  *    ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
    42  */
    45 #include <stddef.h>
    46 #include <stdlib.h>
    47 #include <string.h>
    49 #include "nsIDNKitInterface.h"
    52 #define RACE_2OCTET_MODE	0xd8
    53 #define RACE_ESCAPE		0xff
    54 #define RACE_ESCAPE_2ND		0x99
    56 /*
    57  * Compression type.
    58  */
    59 enum {
    60 	compress_one,	/* all characters are in a single row */
    61 	compress_two,	/* row 0 and another row */
    62 	compress_none	/* nope */
    63 };
    66 idn_result_t
    67 race_decode_decompress(const char *from, uint16_t *buf, size_t buflen)
    68 {
    69 	uint16_t *p = buf;
    70 	unsigned int bitbuf = 0;
    71 	int bitlen = 0;
    72 	unsigned int i, j;
    73 	size_t len;
    75 	while (*from != '\0') {
    76 		int c = *from++;
    77 		int x;
    79 		if ('a' <= c && c <= 'z')
    80 			x = c - 'a';
    81 		else if ('A' <= c && c <= 'Z')
    82 			x = c - 'A';
    83 		else if ('2' <= c && c <= '7')
    84 			x = c - '2' + 26;
    85 		else
    86 			return (idn_invalid_encoding);
    88 		bitbuf = (bitbuf << 5) + x;
    89 		bitlen += 5;
    90 		if (bitlen >= 8) {
    91 			*p++ = (bitbuf >> (bitlen - 8)) & 0xff;
    92 			bitlen -= 8;
    93 		}
    94 	}
    95 	len = p - buf;
    97 	/*
    98 	 * Now 'buf' holds the decoded string.
    99 	 */
   101 	/*
   102 	 * Decompress.
   103 	 */
   104 	if (buf[0] == RACE_2OCTET_MODE) {
   105 		if ((len - 1) % 2 != 0)
   106 			return (idn_invalid_encoding);
   107 		for (i = 1, j = 0; i < len; i += 2, j++)
   108 			buf[j] = (buf[i] << 8) + buf[i + 1];
   109 		len = j;
   110 	} else {
   111 		uint16_t c = buf[0] << 8;	/* higher octet */
   113 		for (i = 1, j = 0; i < len; j++) {
   114 			if (buf[i] == RACE_ESCAPE) {
   115 				if (i + 1 >= len)
   116 					return (idn_invalid_encoding);
   117 				else if (buf[i + 1] == RACE_ESCAPE_2ND)
   118 					buf[j] = c | 0xff;
   119 				else
   120 					buf[j] = buf[i + 1];
   121 				i += 2;
   123 			} else if (buf[i] == 0x99 && c == 0x00) {
   124 				/*
   125 				 * The RACE specification says this is error.
   126 				 */
   127 				return (idn_invalid_encoding);
   129 			} else {
   130 				buf[j] = c | buf[i++];
   131 			}
   132 		}
   133 		len = j;
   134 	}
   135 	buf[len] = '\0';
   137 	return (idn_success);
   138 }
   140 idn_result_t
   141 race_compress_encode(const uint16_t *p, int compress_mode,
   142 		     char *to, size_t tolen)
   143 {
   144 	uint32_t bitbuf = *p++;	/* bit stream buffer */
   145 	int bitlen = 8;			/* # of bits in 'bitbuf' */
   147 	while (*p != '\0' || bitlen > 0) {
   148 		unsigned int c = *p;
   150 		if (c == '\0') {
   151 			/* End of data.  Flush. */
   152 			bitbuf <<= (5 - bitlen);
   153 			bitlen = 5;
   154 		} else if (compress_mode == compress_none) {
   155 			/* Push 16 bit data. */
   156 			bitbuf = (bitbuf << 16) | c;
   157 			bitlen += 16;
   158 			p++;
   159 		} else {/* compress_mode == compress_one/compress_two */
   160 			/* Push 8 or 16 bit data. */
   161 			if (compress_mode == compress_two &&
   162 			    (c & 0xff00) == 0) {
   163 				/* Upper octet is zero (and not U1). */
   164 				bitbuf = (bitbuf << 16) | 0xff00 | c;
   165 				bitlen += 16;
   166 			} else if ((c & 0xff) == 0xff) {
   167 				/* Lower octet is 0xff. */
   168 				bitbuf = (bitbuf << 16) |
   169 					(RACE_ESCAPE << 8) | RACE_ESCAPE_2ND;
   170 				bitlen += 16;
   171 			} else {
   172 				/* Just output lower octet. */
   173 				bitbuf = (bitbuf << 8) | (c & 0xff);
   174 				bitlen += 8;
   175 			}
   176 			p++;
   177 		}
   179 		/*
   180 		 * Output bits in 'bitbuf' in 5-bit unit.
   181 		 */
   182 		while (bitlen >= 5) {
   183 			int x;
   185 			/* Get top 5 bits. */
   186 			x = (bitbuf >> (bitlen - 5)) & 0x1f;
   187 			bitlen -= 5;
   189 			/* Encode. */
   190 			if (x < 26)
   191 				x += 'a';
   192 			else
   193 				x = (x - 26) + '2';
   195 			if (tolen < 1)
   196 				return (idn_buffer_overflow);
   198 			*to++ = x;
   199 			tolen--;
   200 		}
   201 	}
   203 	if (tolen <= 0)
   204 		return (idn_buffer_overflow);
   206 	*to = '\0';
   207 	return (idn_success);
   208 }
   210 int
   211 get_compress_mode(uint16_t *p) {
   212 	int zero = 0;
   213 	unsigned int upper = 0;
   214 	uint16_t *modepos = p - 1;
   216 	while (*p != '\0') {
   217 		unsigned int hi = *p++ & 0xff00;
   219 		if (hi == 0) {
   220 			zero++;
   221 		} else if (hi == upper) {
   222 			;
   223 		} else if (upper == 0) {
   224 			upper = hi;
   225 		} else {
   226 			*modepos = RACE_2OCTET_MODE;
   227 			return (compress_none);
   228 		}
   229 	}
   230 	*modepos = upper >> 8;
   231 	if (upper > 0 && zero > 0)
   232 		return (compress_two);
   233 	else
   234 		return (compress_one);
   235 }

mercurial