diff options
Diffstat (limited to 'src/stringprep/stringprep_drv.c')
-rw-r--r-- | src/stringprep/stringprep_drv.c | 432 |
1 files changed, 0 insertions, 432 deletions
diff --git a/src/stringprep/stringprep_drv.c b/src/stringprep/stringprep_drv.c deleted file mode 100644 index cada92372..000000000 --- a/src/stringprep/stringprep_drv.c +++ /dev/null @@ -1,432 +0,0 @@ -/* - * ejabberd, Copyright (C) 2002-2013 ProcessOne - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - * - */ - -#include <stdio.h> -#include <string.h> -#include <erl_driver.h> -#include <ei.h> - -#include "uni_data.c" -#include "uni_norm.c" - -#define NAMEPREP_COMMAND 1 -#define NODEPREP_COMMAND 2 -#define RESOURCEPREP_COMMAND 3 - -/* - * R15B changed several driver callbacks to use ErlDrvSizeT and - * ErlDrvSSizeT typedefs instead of int. - * This provides missing typedefs on older OTP versions. - */ -#if ERL_DRV_EXTENDED_MAJOR_VERSION < 2 -typedef int ErlDrvSizeT; -typedef int ErlDrvSSizeT; -#endif - -typedef struct { - ErlDrvPort port; -} stringprep_data; - - -static ErlDrvData stringprep_erl_start(ErlDrvPort port, char *buff) -{ - stringprep_data* d = (stringprep_data*)driver_alloc(sizeof(stringprep_data)); - d->port = port; - - set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY); - - return (ErlDrvData)d; -} - -static void stringprep_erl_stop(ErlDrvData handle) -{ - driver_free((char*)handle); -} - - -/* Hangul constants */ -#define SBase 0xAC00 -#define LBase 0x1100 -#define VBase 0x1161 -#define TBase 0x11A7 -#define LCount 19 -#define VCount 21 -#define TCount 28 -#define NCount (VCount * TCount) -#define SCount (LCount * NCount) - -/* - * "canonical_ordering" and "compose" functions are based on nfkc.c from Gnome - * library - */ - -static void canonical_ordering(int *str, int len) -{ - int i, j, t; - int last, next; - - last = GetUniCharCClass(str[0]); - for (i = 0; i < len - 1; i++) - { - next = GetUniCharCClass(str[i + 1]); - if (next != 0 && last > next) - { - for (j = i; j >= 0; j--) - { - if (GetUniCharCClass(str[j]) <= next) - break; - t = str[j + 1]; - str[j + 1] = str[j]; - str[j] = t; - } - next = last; - } - last = next; - } -} - - -static int compose(int ch1, int ch2) -{ - int info1, info2; - - if (LBase <= ch1 && ch1 < LBase + LCount && - VBase <= ch2 && ch2 < VBase + VCount) { - return SBase + ((ch1 - LBase) * VCount + (ch2 - VBase)) * TCount; - } - - if (SBase <= ch1 && ch1 < SBase + SCount && ((ch1 - SBase) % TCount) == 0 && - TBase <= ch2 && ch2 < TBase + TCount) { - return ch1 + ch2 - TBase; - } - - info1 = GetUniCharCompInfo(ch1); - if (info1 != -1 && info1 & CompSingleMask) { - if (!(info1 & CompSecondMask) && - ch2 == compFirstList[info1 & CompMask][0]) { - return compFirstList[info1 & CompMask][1]; - } else - return 0; - } - - info2 = GetUniCharCompInfo(ch2); - if (info2 != -1 && info2 & CompSingleMask) { - if ((info2 & CompSecondMask) && - ch1 == compSecondList[info2 & CompMask][0]) { - return compSecondList[info2 & CompMask][1]; - } else - return 0; - } - - if (info1 != -1 && info2 != -1 && - !(info1 & CompSecondMask) && (info2 & CompSecondMask)) - return compBothList[info1][info2 & CompMask]; - else - return 0; -} - - -#define ADD_UCHAR(ruc) \ - if (ruc <= 0x7F) { \ - if (pos >= size) { \ - size = 2*size + 1; \ - rstring = driver_realloc_binary(rstring, size); \ - } \ - rstring->orig_bytes[pos] = (char) ruc; \ - pos++; \ - } else if (ruc <= 0x7FF) { \ - if (pos + 1 >= size) { \ - size = 2*size + 2; \ - rstring = driver_realloc_binary(rstring, size); \ - } \ - rstring->orig_bytes[pos] = (char) ((ruc >> 6) | 0xC0); \ - rstring->orig_bytes[pos+1] = (char) ((ruc | 0x80) & 0xBF); \ - pos += 2; \ - } else if (ruc <= 0xFFFF) { \ - if (pos + 2 >= size) { \ - size = 2*size + 3; \ - rstring = driver_realloc_binary(rstring, size); \ - } \ - rstring->orig_bytes[pos] = (char) ((ruc >> 12) | 0xE0); \ - rstring->orig_bytes[pos+1] = (char) (((ruc >> 6) | 0x80) & 0xBF); \ - rstring->orig_bytes[pos+2] = (char) ((ruc | 0x80) & 0xBF); \ - pos += 3; \ - } else if (ruc <= 0x1FFFFF) { \ - if (pos + 3 >= size) { \ - size = 2*size + 4; \ - rstring = driver_realloc_binary(rstring, size); \ - } \ - rstring->orig_bytes[pos] = (char) ((ruc >> 18) | 0xF0); \ - rstring->orig_bytes[pos+1] = (char) (((ruc >> 12) | 0x80) & 0xBF); \ - rstring->orig_bytes[pos+2] = (char) (((ruc >> 6) | 0x80) & 0xBF); \ - rstring->orig_bytes[pos+3] = (char) ((ruc | 0x80) & 0xBF); \ - pos += 4; \ - } - -#define ADD_UCHAR32(str, pos, len, ch) \ - if (pos >= len) { \ - len = 2*len + 1; \ - str = driver_realloc(str, len * sizeof(int)); \ - } \ - str[pos] = ch; \ - pos++; - - -#define ADD_DECOMP(ruc) \ - info = GetUniCharDecompInfo(ruc); \ - if (info >= 0) { \ - decomp_len = GetDecompLen(info); \ - decomp_shift = GetDecompShift(info); \ - for (j = 0; j < decomp_len; j++) { \ - ADD_UCHAR32(str32, str32pos, str32len, \ - decompList[decomp_shift + j]); \ - } \ - } else { \ - ADD_UCHAR32(str32, str32pos, str32len, ruc); \ - } - - - -static ErlDrvSSizeT stringprep_erl_control(ErlDrvData drv_data, - unsigned int command, - char *buf, ErlDrvSizeT len, - char **rbuf, ErlDrvSizeT rlen) -{ - int i, j, pos=1; - unsigned char c; - int bad = 0; - int uc = 0, ruc; - int size; - int info; - int prohibit = 0, tolower = 0; - ErlDrvBinary *rstring; - int *mc; - int *str32; - int str32len, str32pos = 0; - int decomp_len, decomp_shift; - int comp_pos, comp_starter_pos; - int cclass_prev, cclass2; - int ch1, ch2; - int first_ral, last_ral, have_ral, have_l; - - size = len + 1; - - rstring = driver_alloc_binary(size); - rstring->orig_bytes[0] = 0; - - str32len = len + 1; - - str32 = driver_alloc(str32len * sizeof(int)); - - switch (command) - { - case 0: - prohibit = ACMask; - tolower = 1; - break; - - case NAMEPREP_COMMAND: - prohibit = ACMask; - tolower = 1; - break; - - case NODEPREP_COMMAND: - prohibit = ACMask | C11Mask | C21Mask | XNPMask; - tolower = 1; - break; - - case RESOURCEPREP_COMMAND: - prohibit = ACMask | C21Mask; - tolower = 0; - break; - } - - for (i = 0; i < len; i++) - { - c = buf[i]; - if (c < 0x80) { - uc = c; - } else if (c < 0xC0) { - bad = 1; - } else if (c < 0xE0) { - if (i+1 < len && (buf[i+1] & 0xC0) == 0x80) { - uc = ((c & 0x1F) << 6) | (buf[i+1] & 0x3F); - i++; - } else { - bad = 1; - } - } else if (c < 0xF0) { - if (i+2 < len && (buf[i+1] & 0xC0) == 0x80 && - (buf[i+2] & 0xC0) == 0x80) { - uc = ((c & 0x0F) << 12) - | ((buf[i+1] & 0x3F) << 6) - | (buf[i+2] & 0x3F); - i += 2; - } else { - bad = 1; - } - } else if (c < 0xF8) { - if (i+3 < len && - (buf[i+1] & 0xC0) == 0x80 && - (buf[i+2] & 0xC0) == 0x80 && - (buf[i+3] & 0xC0) == 0x80) { - uc = ((c & 0x07) << 18) - | ((buf[i+1] & 0x3F) << 12) - | ((buf[i+2] & 0x3F) << 6) - | (buf[i+3] & 0x3F); - i += 3; - if (uc > 0x10FFFF) - bad = 1; - } else { - bad = 1; - } - } else { - bad = 1; - } - - if (bad) { - *rbuf = (char *)rstring; - driver_free(str32); - return 1; - } - - info = GetUniCharInfo(uc); - - if (!(info & B1Mask)) - { - if (tolower) { - if (!(info & MCMask)) - { - ruc = uc + GetDelta(info); - ADD_DECOMP(ruc); - } else { - mc = GetMC(info); - for (j = 1; j <= mc[0]; j++) { - ruc = mc[j]; - ADD_DECOMP(ruc); - } - } - } else { - ruc = uc; - ADD_DECOMP(ruc); - } - } - } - - if (str32pos == 0) { - rstring->orig_bytes[0] = 1; - *rbuf = (char *)rstring; - driver_free(str32); - return 1; - } - - canonical_ordering(str32, str32pos); - - comp_pos = 1; - comp_starter_pos = 0; - ch1 = str32[0]; - cclass_prev = GetUniCharCClass(ch1); - for (i = 1; i < str32pos; i++) - { - ch2 = str32[i]; - cclass2 = GetUniCharCClass(ch2); - if ((cclass_prev == 0 || cclass2 > cclass_prev) && - (ruc = compose(ch1, ch2))) { - ch1 = ruc; - } else { - if (cclass2 == 0) { - str32[comp_starter_pos] = ch1; - comp_starter_pos = comp_pos++; - ch1 = ch2; - cclass_prev = 0; - } else { - str32[comp_pos++] = ch2; - cclass_prev = cclass2; - } - } - } - str32[comp_starter_pos] = ch1; - str32pos = comp_pos; - - last_ral = have_ral = have_l = 0; - info = GetUniCharInfo(str32[0]); - first_ral = info & D1Mask; - for (i = 0; i < str32pos; i++) - { - ruc = str32[i]; - info = GetUniCharInfo(ruc); - if (info & prohibit) { - *rbuf = (char *)rstring; - driver_free(str32); - return 1; - } - last_ral = info & D1Mask; - have_ral = have_ral || last_ral; - have_l |= info & D2Mask; - ADD_UCHAR(ruc); - } - - if (have_ral && (!first_ral || !last_ral || have_l)) { - *rbuf = (char *)rstring; - driver_free(str32); - return 1; - } - - rstring->orig_bytes[0] = 1; - *rbuf = (char *)rstring; - driver_free(str32); - - return pos; -} - - - -ErlDrvEntry stringprep_driver_entry = { - NULL, /* F_PTR init, N/A */ - stringprep_erl_start, /* L_PTR start, called when port is opened */ - stringprep_erl_stop, /* F_PTR stop, called when port is closed */ - NULL, /* F_PTR output, called when erlang has sent */ - NULL, /* F_PTR ready_input, called when input descriptor ready */ - NULL, /* F_PTR ready_output, called when output descriptor ready */ - "stringprep_drv", /* char *driver_name, the argument to open_port */ - NULL, /* F_PTR finish, called when unloaded */ - NULL, /* handle */ - stringprep_erl_control, /* F_PTR control, port_command callback */ - NULL, /* F_PTR timeout, reserved */ - NULL, /* F_PTR outputv, reserved */ - /* Added in Erlang/OTP R15B: */ - NULL, /* ready_async */ - NULL, /* flush */ - NULL, /* call */ - NULL, /* event */ - ERL_DRV_EXTENDED_MARKER, /* extended_marker */ - ERL_DRV_EXTENDED_MAJOR_VERSION, /* major_version */ - ERL_DRV_EXTENDED_MINOR_VERSION, /* minor_version */ - 0, /* driver_flags */ - NULL, /* handle2 */ - NULL, /* process_exit */ - NULL /* stop_select */ -}; - -DRIVER_INIT(stringprep_erl) /* must match name in driver_entry */ -{ - return &stringprep_driver_entry; -} - |