LCOV - code coverage report
Current view: top level - txt_db - txt_db.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 140 177 79.1 %
Date: 2014-08-02 Functions: 6 6 100.0 %
Branches: 89 144 61.8 %

           Branch data     Line data    Source code
       1                 :            : /* crypto/txt_db/txt_db.c */
       2                 :            : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
       3                 :            :  * All rights reserved.
       4                 :            :  *
       5                 :            :  * This package is an SSL implementation written
       6                 :            :  * by Eric Young (eay@cryptsoft.com).
       7                 :            :  * The implementation was written so as to conform with Netscapes SSL.
       8                 :            :  * 
       9                 :            :  * This library is free for commercial and non-commercial use as long as
      10                 :            :  * the following conditions are aheared to.  The following conditions
      11                 :            :  * apply to all code found in this distribution, be it the RC4, RSA,
      12                 :            :  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
      13                 :            :  * included with this distribution is covered by the same copyright terms
      14                 :            :  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
      15                 :            :  * 
      16                 :            :  * Copyright remains Eric Young's, and as such any Copyright notices in
      17                 :            :  * the code are not to be removed.
      18                 :            :  * If this package is used in a product, Eric Young should be given attribution
      19                 :            :  * as the author of the parts of the library used.
      20                 :            :  * This can be in the form of a textual message at program startup or
      21                 :            :  * in documentation (online or textual) provided with the package.
      22                 :            :  * 
      23                 :            :  * Redistribution and use in source and binary forms, with or without
      24                 :            :  * modification, are permitted provided that the following conditions
      25                 :            :  * are met:
      26                 :            :  * 1. Redistributions of source code must retain the copyright
      27                 :            :  *    notice, this list of conditions and the following disclaimer.
      28                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      29                 :            :  *    notice, this list of conditions and the following disclaimer in the
      30                 :            :  *    documentation and/or other materials provided with the distribution.
      31                 :            :  * 3. All advertising materials mentioning features or use of this software
      32                 :            :  *    must display the following acknowledgement:
      33                 :            :  *    "This product includes cryptographic software written by
      34                 :            :  *     Eric Young (eay@cryptsoft.com)"
      35                 :            :  *    The word 'cryptographic' can be left out if the rouines from the library
      36                 :            :  *    being used are not cryptographic related :-).
      37                 :            :  * 4. If you include any Windows specific code (or a derivative thereof) from 
      38                 :            :  *    the apps directory (application code) you must include an acknowledgement:
      39                 :            :  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
      40                 :            :  * 
      41                 :            :  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
      42                 :            :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      43                 :            :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      44                 :            :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
      45                 :            :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      46                 :            :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      47                 :            :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      48                 :            :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      49                 :            :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      50                 :            :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      51                 :            :  * SUCH DAMAGE.
      52                 :            :  * 
      53                 :            :  * The licence and distribution terms for any publically available version or
      54                 :            :  * derivative of this code cannot be changed.  i.e. this code cannot simply be
      55                 :            :  * copied and put under another distribution licence
      56                 :            :  * [including the GNU Public Licence.]
      57                 :            :  */
      58                 :            : 
      59                 :            : #include <stdio.h>
      60                 :            : #include <stdlib.h>
      61                 :            : #include <string.h>
      62                 :            : #include "cryptlib.h"
      63                 :            : #include <openssl/buffer.h>
      64                 :            : #include <openssl/txt_db.h>
      65                 :            : 
      66                 :            : #undef BUFSIZE
      67                 :            : #define BUFSIZE 512
      68                 :            : 
      69                 :            : const char TXT_DB_version[]="TXT_DB" OPENSSL_VERSION_PTEXT;
      70                 :            : 
      71                 :          2 : TXT_DB *TXT_DB_read(BIO *in, int num)
      72                 :            :         {
      73                 :          2 :         TXT_DB *ret=NULL;
      74                 :          2 :         int er=1;
      75                 :          2 :         int esc=0;
      76                 :          2 :         long ln=0;
      77                 :            :         int i,add,n;
      78                 :          2 :         int size=BUFSIZE;
      79                 :          2 :         int offset=0;
      80                 :            :         char *p,*f;
      81                 :            :         OPENSSL_STRING *pp;
      82                 :          2 :         BUF_MEM *buf=NULL;
      83                 :            : 
      84         [ +  - ]:          2 :         if ((buf=BUF_MEM_new()) == NULL) goto err;
      85         [ +  - ]:          2 :         if (!BUF_MEM_grow(buf,size)) goto err;
      86                 :            : 
      87         [ +  - ]:          2 :         if ((ret=OPENSSL_malloc(sizeof(TXT_DB))) == NULL)
      88                 :            :                 goto err;
      89                 :          2 :         ret->num_fields=num;
      90                 :          2 :         ret->index=NULL;
      91                 :          2 :         ret->qual=NULL;
      92         [ +  - ]:          2 :         if ((ret->data=sk_OPENSSL_PSTRING_new_null()) == NULL)
      93                 :            :                 goto err;
      94         [ +  - ]:          2 :         if ((ret->index=OPENSSL_malloc(sizeof(*ret->index)*num)) == NULL)
      95                 :            :                 goto err;
      96         [ +  - ]:          2 :         if ((ret->qual=OPENSSL_malloc(sizeof(*(ret->qual))*num)) == NULL)
      97                 :            :                 goto err;
      98         [ +  + ]:         14 :         for (i=0; i<num; i++)
      99                 :            :                 {
     100                 :         12 :                 ret->index[i]=NULL;
     101                 :         12 :                 ret->qual[i]=NULL;
     102                 :            :                 }
     103                 :            : 
     104                 :          2 :         add=(num+1)*sizeof(char *);
     105                 :          2 :         buf->data[size-1]='\0';
     106                 :          3 :         offset=0;
     107                 :            :         for (;;)
     108                 :            :                 {
     109         [ -  + ]:          3 :                 if (offset != 0)
     110                 :            :                         {
     111                 :          0 :                         size+=BUFSIZE;
     112         [ #  # ]:          0 :                         if (!BUF_MEM_grow_clean(buf,size)) goto err;
     113                 :            :                         }
     114                 :          3 :                 buf->data[offset]='\0';
     115                 :          3 :                 BIO_gets(in,&(buf->data[offset]),size-offset);
     116                 :          3 :                 ln++;
     117         [ +  + ]:          3 :                 if (buf->data[offset] == '\0') break;
     118 [ +  - ][ -  + ]:          1 :                 if ((offset == 0) && (buf->data[0] == '#')) continue;
     119                 :          1 :                 i=strlen(&(buf->data[offset]));
     120                 :          1 :                 offset+=i;
     121         [ -  + ]:          1 :                 if (buf->data[offset-1] != '\n')
     122                 :          0 :                         continue;
     123                 :            :                 else
     124                 :            :                         {
     125                 :          1 :                         buf->data[offset-1]='\0'; /* blat the '\n' */
     126         [ +  - ]:          1 :                         if (!(p=OPENSSL_malloc(add+offset))) goto err;
     127                 :          1 :                         offset=0;
     128                 :            :                         }
     129                 :          1 :                 pp=(char **)p;
     130                 :          1 :                 p+=add;
     131                 :          1 :                 n=0;
     132                 :          1 :                 pp[n++]=p;
     133                 :          1 :                 i=0;
     134                 :          1 :                 f=buf->data;
     135                 :            : 
     136                 :         77 :                 esc=0;
     137                 :            :                 for (;;)
     138                 :            :                         {
     139         [ +  + ]:         77 :                         if (*f == '\0') break;
     140         [ +  + ]:         76 :                         if (*f == '\t')
     141                 :            :                                 {
     142         [ -  + ]:          5 :                                 if (esc)
     143                 :          0 :                                         p--;
     144                 :            :                                 else
     145                 :            :                                         {       
     146                 :          5 :                                         *(p++)='\0';
     147                 :          5 :                                         f++;
     148         [ +  - ]:          5 :                                         if (n >=  num) break;
     149                 :          5 :                                         pp[n++]=p;
     150                 :          5 :                                         continue;
     151                 :            :                                         }
     152                 :            :                                 }
     153                 :         71 :                         esc=(*f == '\\');
     154                 :         71 :                         *(p++)= *(f++);
     155                 :            :                         }
     156                 :          1 :                 *(p++)='\0';
     157 [ +  - ][ -  + ]:          1 :                 if ((n != num) || (*f != '\0'))
     158                 :            :                         {
     159                 :            : #if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)   /* temporary fix :-( */
     160                 :          0 :                         fprintf(stderr,"wrong number of fields on line %ld (looking for field %d, got %d, '%s' left)\n",ln,num,n,f);
     161                 :            : #endif
     162                 :          0 :                         er=2;
     163                 :          0 :                         goto err;
     164                 :            :                         }
     165                 :          1 :                 pp[n]=p;
     166         [ +  - ]:          1 :                 if (!sk_OPENSSL_PSTRING_push(ret->data,pp))
     167                 :            :                         {
     168                 :            : #if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)   /* temporary fix :-( */
     169                 :          0 :                         fprintf(stderr,"failure in sk_push\n");
     170                 :            : #endif
     171                 :          0 :                         er=2;
     172                 :          0 :                         goto err;
     173                 :            :                         }
     174                 :            :                 }
     175                 :            :         er=0;
     176                 :            : err:
     177                 :          2 :         BUF_MEM_free(buf);
     178         [ -  + ]:          2 :         if (er)
     179                 :            :                 {
     180                 :            : #if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)
     181         [ #  # ]:          0 :                 if (er == 1) fprintf(stderr,"OPENSSL_malloc failure\n");
     182                 :            : #endif
     183         [ #  # ]:          0 :                 if (ret != NULL)
     184                 :            :                         {
     185         [ #  # ]:          0 :                         if (ret->data != NULL) sk_OPENSSL_PSTRING_free(ret->data);
     186         [ #  # ]:          0 :                         if (ret->index != NULL) OPENSSL_free(ret->index);
     187         [ #  # ]:          0 :                         if (ret->qual != NULL) OPENSSL_free(ret->qual);
     188         [ #  # ]:          0 :                         if (ret != NULL) OPENSSL_free(ret);
     189                 :            :                         }
     190                 :            :                 return(NULL);
     191                 :            :                 }
     192                 :            :         else
     193                 :            :                 return(ret);
     194                 :            :         }
     195                 :            : 
     196                 :          4 : OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx, OPENSSL_STRING *value)
     197                 :            :         {
     198                 :            :         OPENSSL_STRING *ret;
     199                 :            :         LHASH_OF(OPENSSL_STRING) *lh;
     200                 :            : 
     201         [ -  + ]:          4 :         if (idx >= db->num_fields)
     202                 :            :                 {
     203                 :          0 :                 db->error=DB_ERROR_INDEX_OUT_OF_RANGE;
     204                 :          0 :                 return(NULL);
     205                 :            :                 }
     206                 :          4 :         lh=db->index[idx];
     207         [ -  + ]:          4 :         if (lh == NULL)
     208                 :            :                 {
     209                 :          0 :                 db->error=DB_ERROR_NO_INDEX;
     210                 :          0 :                 return(NULL);
     211                 :            :                 }
     212                 :          4 :         ret=lh_OPENSSL_STRING_retrieve(lh,value);
     213                 :          4 :         db->error=DB_ERROR_OK;
     214                 :          4 :         return(ret);
     215                 :            :         }
     216                 :            : 
     217                 :          4 : int TXT_DB_create_index(TXT_DB *db, int field, int (*qual)(OPENSSL_STRING *),
     218                 :            :                         LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp)
     219                 :            :         {
     220                 :            :         LHASH_OF(OPENSSL_STRING) *idx;
     221                 :            :         OPENSSL_STRING *r;
     222                 :            :         int i,n;
     223                 :            : 
     224         [ -  + ]:          4 :         if (field >= db->num_fields)
     225                 :            :                 {
     226                 :          0 :                 db->error=DB_ERROR_INDEX_OUT_OF_RANGE;
     227                 :          0 :                 return(0);
     228                 :            :                 }
     229                 :            :         /* FIXME: we lose type checking at this point */
     230         [ -  + ]:          4 :         if ((idx=(LHASH_OF(OPENSSL_STRING) *)lh_new(hash,cmp)) == NULL)
     231                 :            :                 {
     232                 :          0 :                 db->error=DB_ERROR_MALLOC;
     233                 :          0 :                 return(0);
     234                 :            :                 }
     235                 :          4 :         n=sk_OPENSSL_PSTRING_num(db->data);
     236         [ +  + ]:          6 :         for (i=0; i<n; i++)
     237                 :            :                 {
     238                 :          2 :                 r=sk_OPENSSL_PSTRING_value(db->data,i);
     239 [ +  + ][ -  + ]:          2 :                 if ((qual != NULL) && (qual(r) == 0)) continue;
     240         [ -  + ]:          2 :                 if ((r=lh_OPENSSL_STRING_insert(idx,r)) != NULL)
     241                 :            :                         {
     242                 :          0 :                         db->error=DB_ERROR_INDEX_CLASH;
     243                 :          0 :                         db->arg1=sk_OPENSSL_PSTRING_find(db->data,r);
     244                 :          0 :                         db->arg2=i;
     245                 :          0 :                         lh_OPENSSL_STRING_free(idx);
     246                 :          0 :                         return(0);
     247                 :            :                         }
     248                 :            :                 }
     249         [ -  + ]:          4 :         if (db->index[field] != NULL) lh_OPENSSL_STRING_free(db->index[field]);
     250                 :          4 :         db->index[field]=idx;
     251                 :          4 :         db->qual[field]=qual;
     252                 :          4 :         return(1);
     253                 :            :         }
     254                 :            : 
     255                 :          2 : long TXT_DB_write(BIO *out, TXT_DB *db)
     256                 :            :         {
     257                 :          2 :         long i,j,n,nn,l,tot=0;
     258                 :            :         char *p,**pp,*f;
     259                 :          2 :         BUF_MEM *buf=NULL;
     260                 :          2 :         long ret= -1;
     261                 :            : 
     262         [ +  - ]:          2 :         if ((buf=BUF_MEM_new()) == NULL)
     263                 :            :                 goto err;
     264                 :          2 :         n=sk_OPENSSL_PSTRING_num(db->data);
     265                 :          2 :         nn=db->num_fields;
     266         [ +  + ]:          5 :         for (i=0; i<n; i++)
     267                 :            :                 {
     268                 :          3 :                 pp=sk_OPENSSL_PSTRING_value(db->data,i);
     269                 :            : 
     270                 :          3 :                 l=0;
     271         [ +  + ]:         21 :                 for (j=0; j<nn; j++)
     272                 :            :                         {
     273         [ +  + ]:         18 :                         if (pp[j] != NULL)
     274                 :         16 :                                 l+=strlen(pp[j]);
     275                 :            :                         }
     276         [ +  - ]:          3 :                 if (!BUF_MEM_grow_clean(buf,(int)(l*2+nn))) goto err;
     277                 :            : 
     278                 :          3 :                 p=buf->data;
     279         [ +  + ]:         21 :                 for (j=0; j<nn; j++)
     280                 :            :                         {
     281                 :         18 :                         f=pp[j];
     282         [ +  + ]:         18 :                         if (f != NULL)
     283                 :            :                                 for (;;) 
     284                 :            :                                         {
     285         [ +  + ]:        243 :                                         if (*f == '\0') break;
     286         [ -  + ]:        227 :                                         if (*f == '\t') *(p++)='\\';
     287                 :        227 :                                         *(p++)= *(f++);
     288                 :        227 :                                         }
     289                 :         18 :                         *(p++)='\t';
     290                 :            :                         }
     291                 :          3 :                 p[-1]='\n';
     292                 :          3 :                 j=p-buf->data;
     293         [ +  - ]:          3 :                 if (BIO_write(out,buf->data,(int)j) != j)
     294                 :            :                         goto err;
     295                 :          3 :                 tot+=j;
     296                 :            :                 }
     297                 :            :         ret=tot;
     298                 :            : err:
     299         [ +  - ]:          2 :         if (buf != NULL) BUF_MEM_free(buf);
     300                 :          2 :         return(ret);
     301                 :            :         }
     302                 :            : 
     303                 :          2 : int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *row)
     304                 :            :         {
     305                 :            :         int i;
     306                 :            :         OPENSSL_STRING *r;
     307                 :            : 
     308         [ +  + ]:         14 :         for (i=0; i<db->num_fields; i++)
     309                 :            :                 {
     310         [ +  + ]:         12 :                 if (db->index[i] != NULL)
     311                 :            :                         {
     312   [ +  +  -  + ]:          6 :                         if ((db->qual[i] != NULL) &&
     313                 :          2 :                                 (db->qual[i](row) == 0)) continue;
     314                 :          4 :                         r=lh_OPENSSL_STRING_retrieve(db->index[i],row);
     315         [ -  + ]:          4 :                         if (r != NULL)
     316                 :            :                                 {
     317                 :          0 :                                 db->error=DB_ERROR_INDEX_CLASH;
     318                 :          0 :                                 db->arg1=i;
     319                 :          0 :                                 db->arg_row=r;
     320                 :          0 :                                 goto err;
     321                 :            :                                 }
     322                 :            :                         }
     323                 :            :                 }
     324                 :            :         /* We have passed the index checks, now just append and insert */
     325         [ +  - ]:          2 :         if (!sk_OPENSSL_PSTRING_push(db->data,row))
     326                 :            :                 {
     327                 :          0 :                 db->error=DB_ERROR_MALLOC;
     328                 :          0 :                 goto err;
     329                 :            :                 }
     330                 :            : 
     331         [ +  + ]:         14 :         for (i=0; i<db->num_fields; i++)
     332                 :            :                 {
     333         [ +  + ]:         12 :                 if (db->index[i] != NULL)
     334                 :            :                         {
     335   [ +  +  -  + ]:          6 :                         if ((db->qual[i] != NULL) &&
     336                 :          2 :                                 (db->qual[i](row) == 0)) continue;
     337                 :          4 :                         (void)lh_OPENSSL_STRING_insert(db->index[i],row);
     338                 :            :                         }
     339                 :            :                 }
     340                 :            :         return(1);
     341                 :            : err:
     342                 :            :         return(0);
     343                 :            :         }
     344                 :            : 
     345                 :          2 : void TXT_DB_free(TXT_DB *db)
     346                 :            :         {
     347                 :            :         int i,n;
     348                 :            :         char **p,*max;
     349                 :            : 
     350         [ +  - ]:          2 :         if(db == NULL)
     351                 :          2 :             return;
     352                 :            : 
     353         [ +  - ]:          2 :         if (db->index != NULL)
     354                 :            :                 {
     355         [ +  + ]:         14 :                 for (i=db->num_fields-1; i>=0; i--)
     356         [ +  + ]:         12 :                         if (db->index[i] != NULL) lh_OPENSSL_STRING_free(db->index[i]);
     357                 :          2 :                 OPENSSL_free(db->index);
     358                 :            :                 }
     359         [ +  - ]:          2 :         if (db->qual != NULL)
     360                 :          2 :                 OPENSSL_free(db->qual);
     361         [ +  - ]:          2 :         if (db->data != NULL)
     362                 :            :                 {
     363         [ +  + ]:          5 :                 for (i=sk_OPENSSL_PSTRING_num(db->data)-1; i>=0; i--)
     364                 :            :                         {
     365                 :            :                         /* check if any 'fields' have been allocated
     366                 :            :                          * from outside of the initial block */
     367                 :          3 :                         p=sk_OPENSSL_PSTRING_value(db->data,i);
     368                 :          3 :                         max=p[db->num_fields]; /* last address */
     369         [ +  + ]:          3 :                         if (max == NULL) /* new row */
     370                 :            :                                 {
     371         [ +  + ]:         14 :                                 for (n=0; n<db->num_fields; n++)
     372         [ +  + ]:         12 :                                         if (p[n] != NULL) OPENSSL_free(p[n]);
     373                 :            :                                 }
     374                 :            :                         else
     375                 :            :                                 {
     376         [ +  + ]:          7 :                                 for (n=0; n<db->num_fields; n++)
     377                 :            :                                         {
     378 [ +  - ][ -  + ]:          6 :                                         if (((p[n] < (char *)p) || (p[n] > max))
     379         [ #  # ]:          0 :                                                 && (p[n] != NULL))
     380                 :          0 :                                                 OPENSSL_free(p[n]);
     381                 :            :                                         }
     382                 :            :                                 }
     383                 :          3 :                         OPENSSL_free(sk_OPENSSL_PSTRING_value(db->data,i));
     384                 :            :                         }
     385                 :          2 :                 sk_OPENSSL_PSTRING_free(db->data);
     386                 :            :                 }
     387                 :          2 :         OPENSSL_free(db);
     388                 :            :         }

Generated by: LCOV version 1.9