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