00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <config.h>
00027
00028
00029 #include <stringprep.h>
00030
00031
00032 #include <string.h>
00033
00034
00035 #include <tld.h>
00036
00037
00038 extern const Tld_table *_tld_tables[];
00039
00052 const Tld_table *
00053 tld_get_table (const char *tld, const Tld_table ** tables)
00054 {
00055 const Tld_table **tldtable = NULL;
00056
00057 if (!tld || !tables)
00058 return NULL;
00059
00060 for (tldtable = tables; *tldtable; tldtable++)
00061 if (!strcmp ((*tldtable)->name, tld))
00062 return *tldtable;
00063
00064 return NULL;
00065 }
00066
00081 const Tld_table *
00082 tld_default_table (const char *tld, const Tld_table ** overrides)
00083 {
00084 const Tld_table *tldtable = NULL;
00085
00086 if (!tld)
00087 return NULL;
00088
00089 if (overrides)
00090 tldtable = tld_get_table (tld, overrides);
00091
00092 if (!tldtable)
00093 tldtable = tld_get_table (tld, _tld_tables);
00094
00095 return tldtable;
00096 }
00097
00098 #define DOTP(c) ((c) == 0x002E || (c) == 0x3002 || \
00099 (c) == 0xFF0E || (c) == 0xFF61)
00100
00114 int
00115 tld_get_4 (const uint32_t * in, size_t inlen, char **out)
00116 {
00117 const uint32_t *ipos;
00118 size_t olen;
00119
00120 *out = NULL;
00121 if (!in || inlen == 0)
00122 return TLD_NODATA;
00123
00124 ipos = &in[inlen - 1];
00125 olen = 0;
00126
00127 while (ipos >= in && ((*ipos >= 0x41 && *ipos <= 0x5A) ||
00128 (*ipos >= 0x61 && *ipos <= 0x7A)))
00129 ipos--, olen++;
00130
00131 if (olen > 0 && DOTP (*ipos))
00132 {
00133 char *out_s = malloc (sizeof (char) * (olen + 1));
00134 char *opos = out_s;
00135
00136 if (!opos)
00137 return TLD_MALLOC_ERROR;
00138
00139 ipos++;
00140
00141 for (; ipos < &in[inlen]; ipos++, opos++)
00142 *opos = *ipos > 0x5A ? *ipos : *ipos + 0x20;
00143 *opos = 0;
00144 *out = out_s;
00145 return TLD_SUCCESS;
00146 }
00147
00148 return TLD_NO_TLD;
00149 }
00150
00162 int
00163 tld_get_4z (const uint32_t * in, char **out)
00164 {
00165 const uint32_t *ipos = in;
00166
00167 if (!in)
00168 return TLD_NODATA;
00169
00170 while (*ipos)
00171 ipos++;
00172
00173 return tld_get_4 (in, ipos - in, out);
00174 }
00175
00188 int
00189 tld_get_z (const char *in, char **out)
00190 {
00191 uint32_t *iucs;
00192 size_t i, ilen;
00193 int rc;
00194
00195 ilen = strlen (in);
00196 iucs = calloc (ilen, sizeof (*iucs));
00197
00198 if (!iucs)
00199 return TLD_MALLOC_ERROR;
00200
00201 for (i = 0; i < ilen; i++)
00202 iucs[i] = in[i];
00203
00204 rc = tld_get_4 (iucs, ilen, out);
00205
00206 free (iucs);
00207
00208 return rc;
00209 }
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223 static int
00224 _tld_checkchar (uint32_t ch, const Tld_table * tld)
00225 {
00226 const Tld_table_element *s, *e, *m;
00227
00228 if (!tld)
00229 return TLD_SUCCESS;
00230
00231
00232 if ((ch >= 0x61 && ch <= 0x7A) ||
00233 (ch >= 0x30 && ch <= 0x39) || ch == 0x2D || DOTP (ch))
00234 return TLD_SUCCESS;
00235
00236 s = tld->valid;
00237 e = s + tld->nvalid;
00238 while (s < e)
00239 {
00240 m = s + ((e - s) >> 1);
00241 if (ch < m->start)
00242 e = m;
00243 else if (ch > m->end)
00244 s = m + 1;
00245 else
00246 return TLD_SUCCESS;
00247 }
00248
00249 return TLD_INVALID;
00250 }
00251
00271 int
00272 tld_check_4t (const uint32_t * in, size_t inlen, size_t * errpos,
00273 const Tld_table * tld)
00274 {
00275 const uint32_t *ipos;
00276 int rc;
00277
00278 if (!tld)
00279 return TLD_SUCCESS;
00280
00281 ipos = in;
00282 while (ipos < &in[inlen])
00283 {
00284 rc = _tld_checkchar (*ipos, tld);
00285 if (rc != TLD_SUCCESS)
00286 {
00287 if (errpos)
00288 *errpos = ipos - in;
00289 return rc;
00290 }
00291 ipos++;
00292 }
00293 return TLD_SUCCESS;
00294 }
00295
00313 int
00314 tld_check_4tz (const uint32_t * in, size_t * errpos, const Tld_table * tld)
00315 {
00316 const uint32_t *ipos = in;
00317
00318 if (!ipos)
00319 return TLD_NODATA;
00320
00321 while (*ipos)
00322 ipos++;
00323
00324 return tld_check_4t (in, ipos - in, errpos, tld);
00325 }
00326
00350 int
00351 tld_check_4 (const uint32_t * in, size_t inlen, size_t * errpos,
00352 const Tld_table ** overrides)
00353 {
00354 const Tld_table *tld;
00355 char *domain;
00356 int rc;
00357
00358 if (errpos)
00359 *errpos = 0;
00360
00361
00362 rc = tld_get_4 (in, inlen, &domain);
00363
00364 if (rc != TLD_SUCCESS)
00365 {
00366 if (rc == TLD_NO_TLD)
00367 return TLD_SUCCESS;
00368 else
00369 return rc;
00370 }
00371
00372
00373 tld = tld_default_table (domain, overrides);
00374 free (domain);
00375
00376 return tld_check_4t (in, inlen, errpos, tld);
00377 }
00378
00400 int
00401 tld_check_4z (const uint32_t * in, size_t * errpos,
00402 const Tld_table ** overrides)
00403 {
00404 const uint32_t *ipos = in;
00405
00406 if (!ipos)
00407 return TLD_NODATA;
00408
00409 while (*ipos)
00410 ipos++;
00411
00412 return tld_check_4 (in, ipos - in, errpos, overrides);
00413 }
00414
00438 int
00439 tld_check_8z (const char *in, size_t * errpos, const Tld_table ** overrides)
00440 {
00441 uint32_t *iucs;
00442 size_t ilen;
00443 int rc;
00444
00445 if (!in)
00446 return TLD_NODATA;
00447
00448 iucs = stringprep_utf8_to_ucs4 (in, -1, &ilen);
00449
00450 if (!iucs)
00451 return TLD_MALLOC_ERROR;
00452
00453 rc = tld_check_4 (iucs, ilen, errpos, overrides);
00454
00455 free (iucs);
00456
00457 return rc;
00458 }
00459
00483 int
00484 tld_check_lz (const char *in, size_t * errpos, const Tld_table ** overrides)
00485 {
00486 char *utf8;
00487 int rc;
00488
00489 if (!in)
00490 return TLD_NODATA;
00491
00492 utf8 = stringprep_locale_to_utf8 (in);
00493 if (!utf8)
00494 return TLD_ICONV_ERROR;
00495
00496
00497 rc = tld_check_8z (utf8, errpos, overrides);
00498
00499 free (utf8);
00500
00501 return rc;
00502 }
00503