Home | History | Annotate | Download | only in cintltst
      1 /*
      2  *******************************************************************************
      3  *
      4  *   Copyright (C) 2003-2014, International Business Machines
      5  *   Corporation and others.  All Rights Reserved.
      6  *
      7  *******************************************************************************
      8  *   file name:  nfsprep.c
      9  *   encoding:   US-ASCII
     10  *   tab size:   8 (not used)
     11  *   indentation:4
     12  *
     13  *   created on: 2003jul11
     14  *   created by: Ram Viswanadha
     15  */
     16 
     17 #include "unicode/utypes.h"
     18 
     19 #if !UCONFIG_NO_IDNA
     20 
     21 #include "nfsprep.h"
     22 #include "ustr_imp.h"
     23 #include "cintltst.h"
     24 #include "cmemory.h"
     25 
     26 #define NFS4_MAX_BUFFER_SIZE 1000
     27 #define PREFIX_SUFFIX_SEPARATOR 0x0040 /* '@' */
     28 
     29 
     30 const char* NFS4DataFileNames[5] ={
     31     "nfscss",
     32     "nfscsi",
     33     "nfscis",
     34     "nfsmxp",
     35     "nfsmxs"
     36 };
     37 
     38 
     39 int32_t
     40 nfs4_prepare( const char* src, int32_t srcLength,
     41               char* dest, int32_t destCapacity,
     42               NFS4ProfileState state,
     43               UParseError* parseError,
     44               UErrorCode*  status){
     45 
     46     UChar b1Stack[NFS4_MAX_BUFFER_SIZE],
     47           b2Stack[NFS4_MAX_BUFFER_SIZE];
     48     char  b3Stack[NFS4_MAX_BUFFER_SIZE];
     49 
     50     /* initialize pointers to stack buffers */
     51     UChar *b1 = b1Stack, *b2 = b2Stack;
     52     char  *b3=b3Stack;
     53     int32_t b1Len=0, b2Len=0, b3Len=0,
     54             b1Capacity = NFS4_MAX_BUFFER_SIZE,
     55             b2Capacity = NFS4_MAX_BUFFER_SIZE,
     56             b3Capacity = NFS4_MAX_BUFFER_SIZE,
     57             reqLength=0;
     58 
     59     UStringPrepProfile* profile = NULL;
     60     /* get the test data path */
     61     const char *testdatapath = NULL;
     62 
     63     if(status==NULL || U_FAILURE(*status)){
     64         return 0;
     65     }
     66     if((src==NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0)){
     67         *status = U_ILLEGAL_ARGUMENT_ERROR;
     68         return 0;
     69     }
     70     testdatapath = loadTestData(status);
     71 
     72     /* convert the string from UTF-8 to UTF-16 */
     73     u_strFromUTF8(b1,b1Capacity,&b1Len,src,srcLength,status);
     74     if(*status == U_BUFFER_OVERFLOW_ERROR){
     75 
     76         /* reset the status */
     77         *status = U_ZERO_ERROR;
     78 
     79         b1 = (UChar*) malloc(b1Len * U_SIZEOF_UCHAR);
     80         if(b1==NULL){
     81             *status = U_MEMORY_ALLOCATION_ERROR;
     82             goto CLEANUP;
     83         }
     84 
     85         b1Capacity = b1Len;
     86         u_strFromUTF8(b1, b1Capacity, &b1Len, src, srcLength, status);
     87     }
     88 
     89     /* open the profile */
     90     profile = usprep_open(testdatapath, NFS4DataFileNames[state],  status);
     91     /* prepare the string */
     92     b2Len = usprep_prepare(profile, b1, b1Len, b2, b2Capacity, USPREP_DEFAULT, parseError, status);
     93     if(*status == U_BUFFER_OVERFLOW_ERROR){
     94         *status = U_ZERO_ERROR;
     95         b2 = (UChar*) malloc(b2Len * U_SIZEOF_UCHAR);
     96         if(b2== NULL){
     97             *status = U_MEMORY_ALLOCATION_ERROR;
     98             goto CLEANUP;
     99         }
    100         b2Len = usprep_prepare(profile, b1, b1Len, b2, b2Len, USPREP_DEFAULT, parseError, status);
    101     }
    102 
    103     /* convert the string back to UTF-8 */
    104     u_strToUTF8(b3,b3Capacity, &b3Len, b2, b2Len, status);
    105     if(*status == U_BUFFER_OVERFLOW_ERROR){
    106         *status = U_ZERO_ERROR;
    107         b3 = (char*) malloc(b3Len);
    108         if(b3== NULL){
    109             *status = U_MEMORY_ALLOCATION_ERROR;
    110             goto CLEANUP;
    111         }
    112         b3Capacity = b3Len;
    113         u_strToUTF8(b3,b3Capacity, &b3Len, b2, b2Len, status);
    114     }
    115 
    116     reqLength = b3Len;
    117     if(dest!=NULL && reqLength <= destCapacity){
    118         memmove(dest, b3, reqLength);
    119     }
    120 
    121 CLEANUP:
    122     if(b1!=b1Stack){
    123         free(b1);
    124     }
    125     if(b2!=b2Stack){
    126         free(b2);
    127     }
    128     if(b3!=b3Stack){
    129         free(b3);
    130     }
    131 
    132     return u_terminateChars(dest, destCapacity, reqLength, status);
    133 }
    134 
    135 /* sorted array for binary search*/
    136 static const char* special_prefixes[]={
    137     "\x0041\x004e\x004f\x004e\x0059\x004d\x004f\x0055\x0053",
    138     "\x0041\x0055\x0054\x0048\x0045\x004e\x0054\x0049\x0043\x0041\x0054\x0045\x0044",
    139     "\x0042\x0041\x0054\x0043\x0048",
    140     "\x0044\x0049\x0041\x004c\x0055\x0050",
    141     "\x0045\x0056\x0045\x0052\x0059\x004f\x004e\x0045",
    142     "\x0047\x0052\x004f\x0055\x0050",
    143     "\x0049\x004e\x0054\x0045\x0052\x0041\x0043\x0054\x0049\x0056\x0045",
    144     "\x004e\x0045\x0054\x0057\x004f\x0052\x004b",
    145     "\x004f\x0057\x004e\x0045\x0052",
    146 };
    147 
    148 
    149 /* binary search the sorted array */
    150 static int
    151 findStringIndex(const char* const *sortedArr, int32_t sortedArrLen, const char* target, int32_t targetLen){
    152 
    153     int left, middle, right,rc;
    154 
    155     left =0;
    156     right= sortedArrLen-1;
    157 
    158     while(left <= right){
    159         middle = (left+right)/2;
    160         rc=strncmp(sortedArr[middle],target, targetLen);
    161 
    162         if(rc<0){
    163             left = middle+1;
    164         }else if(rc >0){
    165             right = middle -1;
    166         }else{
    167             return middle;
    168         }
    169     }
    170     return -1;
    171 }
    172 
    173 static void
    174 getPrefixSuffix(const char *src, int32_t srcLength,
    175                 const char **prefix, int32_t *prefixLen,
    176                 const char **suffix, int32_t *suffixLen,
    177                 UErrorCode *status){
    178 
    179     int32_t i=0;
    180     *prefix = src;
    181     while(i<srcLength){
    182         if(src[i] == PREFIX_SUFFIX_SEPARATOR){
    183             if((i+1) == srcLength){
    184                 /* we reached the end of the string */
    185                 *suffix = NULL;
    186                 i++;
    187                 break;
    188             }
    189             i++;/* the prefix contains the separator */
    190             *suffix = src + i;
    191             break;
    192         }
    193         i++;
    194     }
    195     *prefixLen = i;
    196     *suffixLen = srcLength - i;
    197     /* special prefixes must not be followed by suffixes! */
    198     if((findStringIndex(special_prefixes,UPRV_LENGTHOF(special_prefixes), *prefix, *prefixLen-1) != -1) && (*suffix != NULL)){
    199         *status = U_PARSE_ERROR;
    200         return;
    201     }
    202 
    203 }
    204 
    205 int32_t
    206 nfs4_mixed_prepare( const char* src, int32_t srcLength,
    207                     char* dest, int32_t destCapacity,
    208                     UParseError* parseError,
    209                     UErrorCode*  status){
    210 
    211     const char *prefix = NULL, *suffix = NULL;
    212     int32_t prefixLen=0, suffixLen=0;
    213     char  pStack[NFS4_MAX_BUFFER_SIZE],
    214           sStack[NFS4_MAX_BUFFER_SIZE];
    215     char *p=pStack, *s=sStack;
    216     int32_t pLen=0, sLen=0, reqLen=0,
    217             pCapacity = NFS4_MAX_BUFFER_SIZE,
    218             sCapacity = NFS4_MAX_BUFFER_SIZE;
    219 
    220 
    221     if(status==NULL || U_FAILURE(*status)){
    222         return 0;
    223     }
    224     if((src==NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0)){
    225         *status = U_ILLEGAL_ARGUMENT_ERROR;
    226         return 0;
    227     }
    228     if(srcLength == -1){
    229         srcLength = (int32_t)strlen(src);
    230     }
    231     getPrefixSuffix(src, srcLength, &prefix, &prefixLen, &suffix, &suffixLen, status);
    232 
    233     /* prepare the prefix */
    234     pLen = nfs4_prepare(prefix, prefixLen, p, pCapacity, NFS4_MIXED_PREP_PREFIX, parseError, status);
    235     if(*status == U_BUFFER_OVERFLOW_ERROR){
    236         *status = U_ZERO_ERROR;
    237         p = (char*) malloc(pLen);
    238         if(p == NULL){
    239            *status = U_MEMORY_ALLOCATION_ERROR;
    240            goto CLEANUP;
    241         }
    242         pLen = nfs4_prepare(prefix, prefixLen, p, pLen, NFS4_MIXED_PREP_PREFIX, parseError, status);
    243     }
    244 
    245     /* prepare the suffix */
    246     if(suffix != NULL){
    247         sLen = nfs4_prepare(suffix, suffixLen, s, sCapacity, NFS4_MIXED_PREP_SUFFIX, parseError, status);
    248         if(*status == U_BUFFER_OVERFLOW_ERROR){
    249             *status = U_ZERO_ERROR;
    250             s = (char*) malloc(pLen);
    251             if(s == NULL){
    252                *status = U_MEMORY_ALLOCATION_ERROR;
    253                goto CLEANUP;
    254             }
    255             sLen = nfs4_prepare(suffix, suffixLen, s, sLen, NFS4_MIXED_PREP_SUFFIX, parseError, status);
    256         }
    257     }
    258     reqLen = pLen+sLen+1 /* for the delimiter */;
    259     if(dest != NULL && reqLen <= destCapacity){
    260         memmove(dest, p, pLen);
    261         /* add the suffix */
    262         if(suffix!=NULL){
    263             dest[pLen++] = PREFIX_SUFFIX_SEPARATOR;
    264             memmove(dest+pLen, s, sLen);
    265         }
    266     }
    267 
    268 CLEANUP:
    269     if(p != pStack){
    270         free(p);
    271     }
    272     if(s != sStack){
    273         free(s);
    274     }
    275 
    276     return u_terminateChars(dest, destCapacity, reqLen, status);
    277 }
    278 
    279 int32_t
    280 nfs4_cis_prepare(   const char* src, int32_t srcLength,
    281                     char* dest, int32_t destCapacity,
    282                     UParseError* parseError,
    283                     UErrorCode*  status){
    284     return nfs4_prepare(src, srcLength, dest, destCapacity, NFS4_CIS_PREP, parseError, status);
    285 }
    286 
    287 
    288 int32_t
    289 nfs4_cs_prepare(    const char* src, int32_t srcLength,
    290                     char* dest, int32_t destCapacity,
    291                     UBool isCaseSensitive,
    292                     UParseError* parseError,
    293                     UErrorCode*  status){
    294     if(isCaseSensitive){
    295         return nfs4_prepare(src, srcLength, dest, destCapacity, NFS4_CS_PREP_CS, parseError, status);
    296     }else{
    297         return nfs4_prepare(src, srcLength, dest, destCapacity, NFS4_CS_PREP_CI, parseError, status);
    298     }
    299 }
    300 
    301 #endif
    302 /*
    303  * Hey, Emacs, please set the following:
    304  *
    305  * Local Variables:
    306  * indent-tabs-mode: nil
    307  * End:
    308  *
    309  */
    310 
    311