1 /* $NetBSD: selectiveencode.c,v 1.4 2014/12/10 04:37:56 christos Exp $ */ 2 3 #ifndef lint 4 static char *rcsid = "Id: selectiveencode.c,v 1.1 2003/06/04 00:27:07 marka Exp "; 5 #endif 6 7 /* 8 * Copyright (c) 2000,2002 Japan Network Information Center. 9 * All rights reserved. 10 * 11 * By using this file, you agree to the terms and conditions set forth bellow. 12 * 13 * LICENSE TERMS AND CONDITIONS 14 * 15 * The following License Terms and Conditions apply, unless a different 16 * license is obtained from Japan Network Information Center ("JPNIC"), 17 * a Japanese association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda, 18 * Chiyoda-ku, Tokyo 101-0047, Japan. 19 * 20 * 1. Use, Modification and Redistribution (including distribution of any 21 * modified or derived work) in source and/or binary forms is permitted 22 * under this License Terms and Conditions. 23 * 24 * 2. Redistribution of source code must retain the copyright notices as they 25 * appear in each source code file, this License Terms and Conditions. 26 * 27 * 3. Redistribution in binary form must reproduce the Copyright Notice, 28 * this License Terms and Conditions, in the documentation and/or other 29 * materials provided with the distribution. For the purposes of binary 30 * distribution the "Copyright Notice" refers to the following language: 31 * "Copyright (c) 2000-2002 Japan Network Information Center. All rights reserved." 32 * 33 * 4. The name of JPNIC may not be used to endorse or promote products 34 * derived from this Software without specific prior written approval of 35 * JPNIC. 36 * 37 * 5. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY JPNIC 38 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 39 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 40 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JPNIC BE LIABLE 41 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 42 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 43 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 44 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 45 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 46 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 47 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 48 */ 49 50 #include <config.h> 51 52 #include <stddef.h> 53 54 #include <idn/assert.h> 55 #include <idn/logmacro.h> 56 #include <idn/result.h> 57 #include <idn/utf8.h> 58 #include <idn/debug.h> 59 60 #include "selectiveencode.h" 61 62 static int is_domain_delimiter(char c); 63 static char *find_nonascii(const char *s); 64 65 idn_result_t 66 idn_selectiveencode_findregion(const char *s, 67 char **startp, char **endp) 68 { 69 char *non_ascii; 70 char *start, *end; 71 72 assert(s != NULL && startp != NULL && endp != NULL); 73 74 TRACE(("idn_selectiveencode_findregion(s=\"%s\")\n", 75 idn__debug_xstring(s, 20))); 76 77 /* 78 * Scan the specified string looking for non-ascii character. 79 */ 80 if ((non_ascii = find_nonascii(s)) == NULL) 81 return (idn_notfound); 82 83 /* 84 * Non-ascii character found. 85 * Determine the region to encode. 86 */ 87 88 /* 89 * First, we scan backwards to find the beginning of the region 90 * that should be converted. 91 */ 92 start = non_ascii; 93 while (start > s) { 94 char *prev = idn_utf8_findfirstbyte(start - 1, s); 95 if (is_domain_delimiter(*prev)) 96 break; /* Found */ 97 start = prev; 98 } 99 *startp = start; 100 101 /* 102 * Next we scan forwards looking for the end of the region. 103 */ 104 end = non_ascii + idn_utf8_mblen(non_ascii); 105 while (!is_domain_delimiter(*end)) 106 end += idn_utf8_mblen(end); 107 *endp = end; 108 109 return (idn_success); 110 } 111 112 static int 113 is_domain_delimiter(char c) { 114 return ((unsigned char)c < 0x80 && 115 !('A' <= c && c <= 'Z') && 116 !('a' <= c && c <= 'z') && 117 !('0' <= c && c <= '9') && 118 c != '-' && c != '.'); 119 } 120 121 static char * 122 find_nonascii(const char *s) { 123 while (*s != '\0' && (unsigned char)*s < 0x80) 124 s++; 125 if (*s == '\0') 126 return (NULL); 127 else 128 return ((char *)s); 129 } 130