LCOV - code coverage report
Current view: top level - third_party/heimdal/lib/asn1 - gen_copy.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 120 171 70.2 %
Date: 2024-04-21 15:09:00 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
       3             :  * (Royal Institute of Technology, Stockholm, Sweden).
       4             :  * All rights reserved.
       5             :  *
       6             :  * Redistribution and use in source and binary forms, with or without
       7             :  * modification, are permitted provided that the following conditions
       8             :  * are met:
       9             :  *
      10             :  * 1. Redistributions of source code must retain the above copyright
      11             :  *    notice, this list of conditions and the following disclaimer.
      12             :  *
      13             :  * 2. Redistributions in binary form must reproduce the above copyright
      14             :  *    notice, this list of conditions and the following disclaimer in the
      15             :  *    documentation and/or other materials provided with the distribution.
      16             :  *
      17             :  * 3. Neither the name of the Institute nor the names of its contributors
      18             :  *    may be used to endorse or promote products derived from this software
      19             :  *    without specific prior written permission.
      20             :  *
      21             :  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
      22             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      23             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      24             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
      25             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      26             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      27             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      28             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      29             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      30             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      31             :  * SUCH DAMAGE.
      32             :  */
      33             : 
      34             : #include "gen_locl.h"
      35             : 
      36             : RCSID("$Id$");
      37             : 
      38             : static int used_fail;
      39             : 
      40             : static void
      41         646 : copy_primitive (const char *typename, const char *from, const char *to)
      42             : {
      43         680 :     fprintf (codefile, "if(der_copy_%s(%s, %s)) goto fail;\n",
      44             :              typename, from, to);
      45         646 :     used_fail++;
      46         646 : }
      47             : 
      48             : static void
      49        7285 : copy_type (const char *from, const char *to, const Type *t, int preserve)
      50             : {
      51        7486 :     switch (t->type) {
      52        1539 :     case TType:
      53             : #if 0
      54             :         copy_type (from, to, t->symbol->type, preserve);
      55             : #endif
      56        1620 :         fprintf (codefile, "if(copy_%s(%s, %s)) goto fail;\n",
      57        1539 :                  t->symbol->gen_name, from, to);
      58        1539 :         used_fail++;
      59        1539 :         break;
      60         418 :     case TInteger:
      61         418 :         if (t->range == NULL && t->members == NULL) {
      62          76 :             copy_primitive ("heim_integer", from, to);
      63          72 :             break;
      64             :         }
      65          20 :         HEIM_FALLTHROUGH;
      66             :     case TBoolean:
      67             :     case TEnumerated :
      68         380 :         fprintf(codefile, "*(%s) = *(%s);\n", to, from);
      69         360 :         break;
      70         252 :     case TOctetString:
      71         266 :         copy_primitive ("octet_string", from, to);
      72         252 :         break;
      73         190 :     case TBitString:
      74         190 :         if (HEIM_TAILQ_EMPTY(t->members))
      75         133 :             copy_primitive ("bit_string", from, to);
      76             :         else
      77          57 :             fprintf(codefile, "*(%s) = *(%s);\n", to, from);
      78         180 :         break;
      79         722 :     case TSet:
      80             :     case TSequence:
      81             :     case TChoice: {
      82         722 :         Member *m, *have_ellipsis = NULL;
      83             : 
      84         722 :         if(t->members == NULL)
      85           0 :             break;
      86             : 
      87         722 :         if ((t->type == TSequence || t->type == TChoice) && preserve) {
      88           0 :             fprintf(codefile,
      89             :                     "{ int ret;\n"
      90             :                     "ret = der_copy_octet_string(&(%s)->_save, &(%s)->_save);\n"
      91             :                     "if (ret) goto fail;\n"
      92             :                     "}\n",
      93             :                     from, to);
      94           0 :             used_fail++;
      95             :         }
      96             : 
      97         722 :         if(t->type == TChoice) {
      98         171 :             fprintf(codefile, "(%s)->element = (%s)->element;\n", to, from);
      99         171 :             fprintf(codefile, "switch((%s)->element) {\n", from);
     100             :         }
     101             : 
     102        3287 :         HEIM_TAILQ_FOREACH(m, t->members, members) {
     103         135 :             char *fs;
     104         135 :             char *ts;
     105             : 
     106        2565 :             if (m->ellipsis) {
     107         114 :                 have_ellipsis = m;
     108         114 :                 continue;
     109             :             }
     110             : 
     111        2451 :             if(t->type == TChoice)
     112         627 :                 fprintf(codefile, "case %s:\n", m->label);
     113             : 
     114        4773 :             if (asprintf (&fs, "%s(%s)->%s%s",
     115        2451 :                           m->optional ? "" : "&", from,
     116        2451 :                           t->type == TChoice ? "u." : "", m->gen_name) < 0)
     117           0 :                 errx(1, "malloc");
     118        2451 :             if (fs == NULL)
     119           0 :                 errx(1, "malloc");
     120        4773 :             if (asprintf (&ts, "%s(%s)->%s%s",
     121        2451 :                           m->optional ? "" : "&", to,
     122        2451 :                           t->type == TChoice ? "u." : "", m->gen_name) < 0)
     123           0 :                 errx(1, "malloc");
     124        2451 :             if (ts == NULL)
     125           0 :                 errx(1, "malloc");
     126        2451 :             if(m->optional){
     127         950 :                 fprintf(codefile, "if(%s) {\n", fs);
     128         950 :                 fprintf(codefile, "%s = calloc(1, sizeof(*%s));\n", ts, ts);
     129         950 :                 fprintf(codefile, "if(%s == NULL) goto fail;\n", ts);
     130         950 :                 used_fail++;
     131             :             }
     132        2451 :             copy_type (fs, ts, m->type, FALSE);
     133        2451 :             if(m->optional){
     134         950 :                 fprintf(codefile, "}else\n");
     135         950 :                 fprintf(codefile, "%s = NULL;\n", ts);
     136             :             }
     137        2451 :             free (fs);
     138        2451 :             free (ts);
     139        2451 :             if(t->type == TChoice)
     140         723 :                 fprintf(codefile, "break;\n");
     141             :         }
     142         722 :         if(t->type == TChoice) {
     143         171 :             if (have_ellipsis) {
     144          19 :                 fprintf(codefile, "case %s: {\n"
     145             :                         "int ret;\n"
     146             :                         "ret=der_copy_octet_string(&(%s)->u.%s, &(%s)->u.%s);\n"
     147             :                         "if (ret) goto fail;\n"
     148             :                         "break;\n"
     149             :                         "}\n",
     150             :                         have_ellipsis->label,
     151             :                         from, have_ellipsis->gen_name,
     152             :                         to, have_ellipsis->gen_name);
     153          19 :                 used_fail++;
     154             :             }
     155         171 :             fprintf(codefile, "}\n");
     156             :         }
     157         684 :         break;
     158             :     }
     159         304 :     case TSetOf:
     160             :     case TSequenceOf: {
     161         304 :         char *f = NULL, *T = NULL;
     162             : 
     163         304 :         fprintf (codefile, "if(((%s)->val = "
     164             :                  "calloc(1, (%s)->len * sizeof(*(%s)->val))) == NULL && (%s)->len != 0)\n",
     165             :                  to, from, to, from);
     166         304 :         fprintf (codefile, "goto fail;\n");
     167         304 :         used_fail++;
     168         304 :         fprintf(codefile,
     169             :                 "for((%s)->len = 0; (%s)->len < (%s)->len; (%s)->len++){\n",
     170             :                 to, to, from, to);
     171         304 :         if (asprintf(&f, "&(%s)->val[(%s)->len]", from, to) < 0)
     172           0 :             errx(1, "malloc");
     173         304 :         if (f == NULL)
     174           0 :             errx(1, "malloc");
     175         304 :         if (asprintf(&T, "&(%s)->val[(%s)->len]", to, to) < 0)
     176           0 :             errx(1, "malloc");
     177         304 :         if (T == NULL)
     178           0 :             errx(1, "malloc");
     179         304 :         copy_type(f, T, t->subtype, FALSE);
     180         304 :         fprintf(codefile, "}\n");
     181         304 :         free(f);
     182         304 :         free(T);
     183         304 :         break;
     184             :     }
     185           0 :     case TGeneralizedTime:
     186           0 :         fprintf(codefile, "*(%s) = *(%s);\n", to, from);
     187           0 :         break;
     188          18 :     case TGeneralString:
     189          19 :         copy_primitive ("general_string", from, to);
     190          18 :         break;
     191           0 :     case TTeletexString:
     192           0 :         copy_primitive ("general_string", from, to);
     193           0 :         break;
     194           0 :     case TUTCTime:
     195           0 :         fprintf(codefile, "*(%s) = *(%s);\n", to, from);
     196           0 :         break;
     197          72 :     case TUTF8String:
     198          76 :         copy_primitive ("utf8string", from, to);
     199          72 :         break;
     200           0 :     case TPrintableString:
     201           0 :         copy_primitive ("printable_string", from, to);
     202           0 :         break;
     203           0 :     case TIA5String:
     204           0 :         copy_primitive ("ia5_string", from, to);
     205           0 :         break;
     206           0 :     case TBMPString:
     207           0 :         copy_primitive ("bmp_string", from, to);
     208           0 :         break;
     209           0 :     case TUniversalString:
     210           0 :         copy_primitive ("universal_string", from, to);
     211           0 :         break;
     212           0 :     case TVisibleString:
     213           0 :         copy_primitive ("visible_string", from, to);
     214           0 :         break;
     215        3819 :     case TTag:
     216        3819 :         copy_type (from, to, t->subtype, preserve);
     217        3819 :         break;
     218          72 :     case TOID:
     219          76 :         copy_primitive ("oid", from, to);
     220          72 :         break;
     221          18 :     case TNull:
     222          18 :         break;
     223           0 :     default :
     224           0 :         abort ();
     225             :     }
     226        7285 : }
     227             : 
     228             : void
     229         912 : generate_type_copy (const Symbol *s)
     230             : {
     231          48 :   struct decoration deco;
     232         912 :   ssize_t more_deco = -1;
     233         912 :   int preserve = preserve_type(s->name) ? TRUE : FALSE;
     234         912 :   int save_used_fail = used_fail;
     235             : 
     236         912 :   used_fail = 0;
     237             : 
     238         960 :   fprintf (codefile, "int ASN1CALL\n"
     239             :            "copy_%s(const %s *from, %s *to)\n"
     240             :            "{\n"
     241             :            "memset(to, 0, sizeof(*to));\n",
     242         912 :            s->gen_name, s->gen_name, s->gen_name);
     243         912 :   copy_type ("from", "to", s->type, preserve);
     244         950 :   while (decorate_type(s->gen_name, &deco, &more_deco)) {
     245          38 :       if (deco.ext && deco.copy_function_name == NULL) {
     246             :           /* Decorated with field of external type but no copy function */
     247          38 :           if (deco.ptr)
     248           0 :               fprintf(codefile, "(to)->%s = 0;\n", deco.field_name);
     249             :           else
     250          38 :               fprintf(codefile, "memset(&(to)->%s, 0, sizeof((to)->%s));\n",
     251             :                       deco.field_name, deco.field_name);
     252           0 :       } else if (deco.ext) {
     253             :           /* Decorated with field of external type w/ copy function */
     254           0 :           if (deco.ptr) {
     255           0 :               fprintf(codefile, "if (from->%s) {\n", deco.field_name);
     256           0 :               fprintf(codefile, "(to)->%s = calloc(1, sizeof(*(to)->%s));\n",
     257             :                       deco.field_name, deco.field_name);
     258           0 :               fprintf(codefile, "if (%s((from)->%s, (to)->%s)) goto fail;\n",
     259             :                       deco.copy_function_name, deco.field_name, deco.field_name);
     260           0 :               fprintf(codefile, "}\n");
     261             :           } else {
     262           0 :               fprintf(codefile, "if (%s(&(from)->%s, &(to)->%s)) goto fail;\n",
     263             :                       deco.copy_function_name, deco.field_name, deco.field_name);
     264             :           }
     265           0 :       } else if (deco.opt) {
     266             :           /* Decorated with optional field of ASN.1 type */
     267           0 :           fprintf(codefile, "if (from->%s) {\n", deco.field_name);
     268           0 :           fprintf(codefile, "(to)->%s = calloc(1, sizeof(*(to)->%s));\n", deco.field_name, deco.field_name);
     269           0 :           fprintf(codefile, "if (copy_%s((from)->%s, (to)->%s)) goto fail;\n", deco.field_type, deco.field_name, deco.field_name);
     270           0 :           fprintf(codefile, "}\n");
     271             :       } else {
     272             :           /* Decorated with required field of ASN.1 type */
     273           0 :           fprintf(codefile, "if (copy_%s(&(from)->%s, &(to)->%s)) goto fail;\n", deco.field_type, deco.field_name, deco.field_name);
     274             :       }
     275          38 :       used_fail++;
     276          38 :       free(deco.field_type);
     277             :   }
     278         912 :   fprintf (codefile, "return 0;\n");
     279             : 
     280         912 :   if (used_fail)
     281         865 :       fprintf (codefile, "fail:\n"
     282             :                "free_%s(to);\n"
     283             :                "return ENOMEM;\n",
     284         817 :                s->gen_name);
     285             : 
     286         912 :   fprintf(codefile,
     287             :           "}\n\n");
     288         912 :   used_fail = save_used_fail;
     289         912 : }
     290             : 

Generated by: LCOV version 1.14