Add a new test harness to facilitate memory leak detection in the
authorGreg Hudson <ghudson@mit.edu>
Wed, 11 Feb 2009 20:28:40 +0000 (20:28 +0000)
committerGreg Hudson <ghudson@mit.edu>
Wed, 11 Feb 2009 20:28:40 +0000 (20:28 +0000)
ASN.1 decoder routines.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@21970 dc483132-0cff-0310-8789-dd5450dbe970

src/tests/asn.1/Makefile.in
src/tests/asn.1/deps
src/tests/asn.1/krb5_decode_leak.c [new file with mode: 0644]

index 25f9bdc367ddbb9ac662fea94d9db40985467934..605e90293c9ef23b16f93e8afa004058a604119b 100644 (file)
@@ -9,10 +9,11 @@ LDAP=@LDAP@
 RUN_SETUP = @KRB5_RUN_ENV@
 
 SRCS= $(srcdir)/krb5_encode_test.c $(srcdir)/krb5_decode_test.c \
-       $(srcdir)/ktest.c $(srcdir)/ktest_equal.c $(srcdir)/utility.c \
+       $(srcdir)/krb5_decode_leak.c $(srcdir)/ktest.c \
+       $(srcdir)/ktest_equal.c $(srcdir)/utility.c \
        $(srcdir)/trval.c $(srcdir)/t_trval.c
 
-all:: krb5_encode_test krb5_decode_test t_trval
+all:: krb5_encode_test krb5_decode_test krb5_decode_leak t_trval
 
 LOCALINCLUDES = -I$(srcdir)/../../lib/krb5/asn.1
 
@@ -26,10 +27,22 @@ DECOBJS = krb5_decode_test.o ktest.o ktest_equal.o utility.o
 krb5_decode_test: $(DECOBJS) $(KRB5_BASE_DEPLIBS)
        $(CC_LINK) -o krb5_decode_test $(DECOBJS) $(KRB5_BASE_LIBS)
 
+LEAKOBJS = krb5_decode_leak.o ktest.o ktest_equal.o utility.o
+
+krb5_decode_leak: $(LEAKOBJS) $(KRB5_BASE_DEPLIBS)
+       $(CC_LINK) -o krb5_decode_leak $(LEAKOBJS) $(KRB5_BASE_LIBS)
+
 t_trval: t_trval.o
        $(CC) -o t_trval $(ALL_CFLAGS) t_trval.o
 
-check:: check-encode check-encode-trval check-decode
+check:: check-encode check-encode-trval check-decode check-leak
+
+# Does not actually test for leaks unless using valgrind or a similar
+# tool, but does exercise a bunch of code.
+check-leak: krb5_decode_leak
+       KRB5_CONFIG=$(SRCTOP)/config-files/krb5.conf ; \
+               export KRB5_CONFIG ;\
+               $(RUN_SETUP) $(VALGRIND) ./krb5_decode_leak
 
 check-decode: krb5_decode_test
        KRB5_CONFIG=$(SRCTOP)/config-files/krb5.conf ; \
index 4291da6ad83dd0ffcffaed31b794fb9a9ced1811..0e78b6ada36093fcc6a5b66215cf8fd5d55a9025 100644 (file)
@@ -25,6 +25,18 @@ $(OUTPRE)krb5_decode_test.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/lib/krb5/asn.1/asn1buf.h \
   $(SRCTOP)/lib/krb5/asn.1/krbasn1.h debug.h krb5_decode_test.c \
   ktest.h ktest_equal.h utility.h
+$(OUTPRE)krb5_decode_leak.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+  $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+  $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \
+  $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \
+  $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \
+  $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \
+  $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/kdb.h \
+  $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/locate_plugin.h \
+  $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/lib/krb5/asn.1/asn1buf.h \
+  $(SRCTOP)/lib/krb5/asn.1/krbasn1.h debug.h krb5_decode_leak.c \
+  ktest.h utility.h
 $(OUTPRE)ktest.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
   $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
   $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h \
diff --git a/src/tests/asn.1/krb5_decode_leak.c b/src/tests/asn.1/krb5_decode_leak.c
new file mode 100644 (file)
index 0000000..4d40eec
--- /dev/null
@@ -0,0 +1,650 @@
+/* -*- mode: c; indent-tabs-mode: nil -*- */
+/*
+ * This program is intended to help detect memory leaks in the ASN.1
+ * decoder functions by exercising their failure paths.  The setup
+ * code for the test cases is copied from krb5_encode_test.c.
+ *
+ * This code does not actually detect leaks by itself; it must be run
+ * through a leak-detection tool such as valgrind to do so.  Simply
+ * running the program will exercise a bunch of ASN.1 encoder and
+ * decoder code paths but won't validate the results.
+ */
+
+#include <stdio.h>
+#include "k5-int.h"
+#include "com_err.h"
+#include "utility.h"
+
+#include "ktest.h"
+#include <string.h>
+
+#include "debug.h"
+
+krb5_context test_context;
+
+int
+main(int argc, char **argv)
+{
+    krb5_data *code;
+    krb5_error_code retval;
+    unsigned int i;
+
+    retval = krb5_init_context(&test_context);
+    if (retval) {
+        com_err(argv[0], retval, "while initializing krb5");
+        exit(1);
+    }
+    init_access(argv[0]);
+  
+#define setup(value, typestring, constructor) \
+    retval = constructor(&(value)); \
+    if (retval) { \
+        com_err("krb5_decode_leak", retval, "while making sample %s", \
+                typestring); \
+        exit(1); \
+    }
+
+#define encode_run(value,type,typestring,description,encoder)
+
+    /*
+     * Encode a value.  Then attempt to trigger most failure paths of
+     * the decoder function by passing in corrupt encodings, which we
+     * generate by perturbing each byte of the encoding in turn.  Some
+     * of the perturbed encodings are expected to decode successfully,
+     * so we need a free function to discard successful results.  Make
+     * sure to define a pointer named "tmp" of the correct type in the
+     * enclosing block.
+     */
+#define leak_test(value, encoder, decoder, freefn) \
+    retval = encoder(&(value),&(code)); \
+    if (retval) { \
+        com_err("krb5_decode_leak", retval, "while encoding"); \
+        exit(1); \
+    } \
+    for (i = 0; i < code->length; i++) { \
+        code->data[i] = (char)~((unsigned char)code->data[i]); \
+        retval = decoder(code, &tmp); \
+        code->data[i] = (char)~((unsigned char)code->data[i]); \
+        if (retval == 0) \
+            freefn(test_context, tmp); \
+    } \
+    krb5_free_data(test_context, code);
+      
+    /****************************************************************/
+    /* encode_krb5_authenticator */
+    {
+        krb5_authenticator authent, *tmp;
+
+        setup(authent, "authenticator", ktest_make_sample_authenticator);
+        leak_test(authent, encode_krb5_authenticator,
+                  decode_krb5_authenticator, krb5_free_authenticator);
+
+        ktest_destroy_checksum(&(authent.checksum));
+        ktest_destroy_keyblock(&(authent.subkey));
+        authent.seq_number = 0;
+        ktest_empty_authorization_data(authent.authorization_data);
+        leak_test(authent, encode_krb5_authenticator,
+                  decode_krb5_authenticator, krb5_free_authenticator);
+
+        ktest_destroy_authorization_data(&(authent.authorization_data));
+        leak_test(authent, encode_krb5_authenticator,
+                  decode_krb5_authenticator, krb5_free_authenticator);
+        ktest_empty_authenticator(&authent);
+    }
+  
+    /****************************************************************/
+    /* encode_krb5_ticket */
+    {
+        krb5_ticket tkt, *tmp;
+
+        setup(tkt, "ticket", ktest_make_sample_ticket);
+        leak_test(tkt, encode_krb5_ticket, decode_krb5_ticket,
+                  krb5_free_ticket);
+        ktest_empty_ticket(&tkt);
+    }
+
+    /****************************************************************/
+    /* encode_krb5_encryption_key */
+    {
+        krb5_keyblock keyblk, *tmp;
+
+        setup(keyblk, "keyblock", ktest_make_sample_keyblock);
+        leak_test(keyblk, encode_krb5_encryption_key,
+                  decode_krb5_encryption_key, krb5_free_keyblock);
+        ktest_empty_keyblock(&keyblk);
+    }  
+  
+    /****************************************************************/
+    /* encode_krb5_enc_tkt_part */
+    {
+        krb5_ticket tkt;
+        krb5_enc_tkt_part *tmp;
+
+        memset(&tkt, 0, sizeof(krb5_ticket));
+        tkt.enc_part2 = calloc(1, sizeof(krb5_enc_tkt_part));
+        if (tkt.enc_part2 == NULL)
+            com_err("allocating enc_tkt_part", errno, "");
+        setup(*(tkt.enc_part2), "enc_tkt_part",
+              ktest_make_sample_enc_tkt_part);
+
+        leak_test(*(tkt.enc_part2), encode_krb5_enc_tkt_part,
+                  decode_krb5_enc_tkt_part, krb5_free_enc_tkt_part);
+  
+        tkt.enc_part2->times.starttime = 0;
+        tkt.enc_part2->times.renew_till = 0;
+        ktest_destroy_address(&(tkt.enc_part2->caddrs[1]));
+        ktest_destroy_address(&(tkt.enc_part2->caddrs[0]));
+        ktest_destroy_authdata(&(tkt.enc_part2->authorization_data[1]));
+        ktest_destroy_authdata(&(tkt.enc_part2->authorization_data[0]));
+  
+        /* ISODE version fails on the empty caddrs field */
+        ktest_destroy_addresses(&(tkt.enc_part2->caddrs));
+        ktest_destroy_authorization_data(&(tkt.enc_part2->authorization_data));
+  
+        leak_test(*(tkt.enc_part2), encode_krb5_enc_tkt_part,
+                  decode_krb5_enc_tkt_part, krb5_free_enc_tkt_part);
+        ktest_empty_ticket(&tkt);
+    }  
+  
+    /****************************************************************/
+    /* encode_krb5_enc_kdc_rep_part */
+    {
+        krb5_kdc_rep kdcr;
+        krb5_enc_kdc_rep_part *tmp;
+
+        memset(&kdcr, 0, sizeof(kdcr));
+        kdcr.enc_part2 = calloc(1, sizeof(krb5_enc_kdc_rep_part));
+        if (kdcr.enc_part2 == NULL)
+            com_err("allocating enc_kdc_rep_part", errno, "");
+        setup(*(kdcr.enc_part2), "enc_kdc_rep_part",
+              ktest_make_sample_enc_kdc_rep_part);
+  
+        leak_test(*(kdcr.enc_part2), encode_krb5_enc_kdc_rep_part,
+                  decode_krb5_enc_kdc_rep_part, krb5_free_enc_kdc_rep_part);
+  
+        kdcr.enc_part2->key_exp = 0;
+        kdcr.enc_part2->times.starttime = 0;
+        kdcr.enc_part2->flags &= ~TKT_FLG_RENEWABLE;
+        ktest_destroy_addresses(&(kdcr.enc_part2->caddrs));
+  
+        leak_test(*(kdcr.enc_part2), encode_krb5_enc_kdc_rep_part,
+                  decode_krb5_enc_kdc_rep_part, krb5_free_enc_kdc_rep_part);
+
+        ktest_empty_kdc_rep(&kdcr);
+    }  
+
+    /****************************************************************/
+    /* encode_krb5_as_rep */
+    {
+        krb5_kdc_rep kdcr, *tmp;
+
+        setup(kdcr, "kdc_rep", ktest_make_sample_kdc_rep);
+        kdcr.msg_type = KRB5_AS_REP;
+        leak_test(kdcr, encode_krb5_as_rep, decode_krb5_as_rep,
+                  krb5_free_kdc_rep);
+  
+        ktest_destroy_pa_data_array(&(kdcr.padata));
+        leak_test(kdcr, encode_krb5_as_rep, decode_krb5_as_rep,
+                  krb5_free_kdc_rep);
+
+        ktest_empty_kdc_rep(&kdcr);
+
+    }  
+  
+    /****************************************************************/
+    /* encode_krb5_tgs_rep */
+    {
+        krb5_kdc_rep kdcr, *tmp;
+
+        setup(kdcr, "kdc_rep", ktest_make_sample_kdc_rep);
+        kdcr.msg_type = KRB5_TGS_REP;
+        leak_test(kdcr, encode_krb5_tgs_rep, decode_krb5_tgs_rep,
+                  krb5_free_kdc_rep);
+
+        ktest_destroy_pa_data_array(&(kdcr.padata));
+        leak_test(kdcr, encode_krb5_tgs_rep, decode_krb5_tgs_rep,
+                  krb5_free_kdc_rep);
+
+        ktest_empty_kdc_rep(&kdcr);
+
+    }  
+  
+    /****************************************************************/
+    /* encode_krb5_ap_req */
+    {
+        krb5_ap_req apreq, *tmp;
+
+        setup(apreq, "ap_req", ktest_make_sample_ap_req);
+        leak_test(apreq, encode_krb5_ap_req, decode_krb5_ap_req,
+                  krb5_free_ap_req);
+        ktest_empty_ap_req(&apreq);
+    }  
+
+    /****************************************************************/
+    /* encode_krb5_ap_rep */
+    {
+        krb5_ap_rep aprep, *tmp;
+
+        setup(aprep, "ap_rep", ktest_make_sample_ap_rep);
+        leak_test(aprep, encode_krb5_ap_rep, decode_krb5_ap_rep,
+                  krb5_free_ap_rep);
+        ktest_empty_ap_rep(&aprep);
+    }  
+
+    /****************************************************************/
+    /* encode_krb5_ap_rep_enc_part */
+    {
+        krb5_ap_rep_enc_part apenc, *tmp;
+
+        setup(apenc, "ap_rep_enc_part", ktest_make_sample_ap_rep_enc_part);
+        leak_test(apenc, encode_krb5_ap_rep_enc_part,
+                  decode_krb5_ap_rep_enc_part, krb5_free_ap_rep_enc_part);
+  
+        ktest_destroy_keyblock(&(apenc.subkey));
+        apenc.seq_number = 0;
+        leak_test(apenc, encode_krb5_ap_rep_enc_part,
+                  decode_krb5_ap_rep_enc_part, krb5_free_ap_rep_enc_part);
+        ktest_empty_ap_rep_enc_part(&apenc);
+    }
+  
+    /****************************************************************/
+    /* encode_krb5_as_req */
+    {
+        krb5_kdc_req asreq, *tmp;
+
+        setup(asreq, "kdc_req", ktest_make_sample_kdc_req);
+        asreq.msg_type = KRB5_AS_REQ;
+        asreq.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY;
+        leak_test(asreq, encode_krb5_as_req, decode_krb5_as_req,
+                  krb5_free_kdc_req);
+
+        ktest_destroy_pa_data_array(&(asreq.padata));
+        ktest_destroy_principal(&(asreq.client));
+#ifndef ISODE_SUCKS
+        ktest_destroy_principal(&(asreq.server));
+#endif
+        asreq.kdc_options |= KDC_OPT_ENC_TKT_IN_SKEY;
+        asreq.from = 0;
+        asreq.rtime = 0;
+        ktest_destroy_addresses(&(asreq.addresses));
+        ktest_destroy_enc_data(&(asreq.authorization_data));
+        leak_test(asreq, encode_krb5_as_req, decode_krb5_as_req,
+                  krb5_free_kdc_req);
+
+        ktest_destroy_sequence_of_ticket(&(asreq.second_ticket));
+#ifndef ISODE_SUCKS
+        ktest_make_sample_principal(&(asreq.server));
+#endif
+        asreq.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY;
+        leak_test(asreq, encode_krb5_as_req, decode_krb5_as_req,
+                  krb5_free_kdc_req);
+        ktest_empty_kdc_req(&asreq);
+    }
+  
+    /****************************************************************/
+    /* encode_krb5_tgs_req */
+    {
+        krb5_kdc_req tgsreq, *tmp;
+
+        setup(tgsreq, "kdc_req", ktest_make_sample_kdc_req);
+        tgsreq.msg_type = KRB5_TGS_REQ;
+        tgsreq.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY;
+        leak_test(tgsreq, encode_krb5_tgs_req, decode_krb5_tgs_req,
+                  krb5_free_kdc_req);
+
+        ktest_destroy_pa_data_array(&(tgsreq.padata));
+        ktest_destroy_principal(&(tgsreq.client));
+#ifndef ISODE_SUCKS
+        ktest_destroy_principal(&(tgsreq.server));
+#endif
+        tgsreq.kdc_options |= KDC_OPT_ENC_TKT_IN_SKEY;
+        tgsreq.from = 0;
+        tgsreq.rtime = 0;
+        ktest_destroy_addresses(&(tgsreq.addresses));
+        ktest_destroy_enc_data(&(tgsreq.authorization_data));
+        leak_test(tgsreq, encode_krb5_tgs_req, decode_krb5_tgs_req,
+                  krb5_free_kdc_req);
+
+        ktest_destroy_sequence_of_ticket(&(tgsreq.second_ticket));
+#ifndef ISODE_SUCKS
+        ktest_make_sample_principal(&(tgsreq.server));
+#endif
+        tgsreq.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY;
+        leak_test(tgsreq, encode_krb5_tgs_req, decode_krb5_tgs_req,
+                  krb5_free_kdc_req);
+        ktest_empty_kdc_req(&tgsreq);
+    }
+  
+    /****************************************************************/
+    /* encode_krb5_kdc_req_body */
+    {
+        krb5_kdc_req kdcrb, *tmp;
+
+        memset(&kdcrb, 0, sizeof(kdcrb));
+        setup(kdcrb, "kdc_req_body", ktest_make_sample_kdc_req_body);
+        kdcrb.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY;
+        leak_test(kdcrb, encode_krb5_kdc_req_body, decode_krb5_kdc_req_body,
+                  krb5_free_kdc_req);
+
+        ktest_destroy_principal(&(kdcrb.client));
+#ifndef ISODE_SUCKS
+        ktest_destroy_principal(&(kdcrb.server));
+#endif
+        kdcrb.kdc_options |= KDC_OPT_ENC_TKT_IN_SKEY;
+        kdcrb.from = 0;
+        kdcrb.rtime = 0;
+        ktest_destroy_addresses(&(kdcrb.addresses));
+        ktest_destroy_enc_data(&(kdcrb.authorization_data));
+        leak_test(kdcrb, encode_krb5_kdc_req_body, decode_krb5_kdc_req_body,
+                  krb5_free_kdc_req);
+
+        ktest_destroy_sequence_of_ticket(&(kdcrb.second_ticket));
+#ifndef ISODE_SUCKS
+        ktest_make_sample_principal(&(kdcrb.server));
+#endif
+        kdcrb.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY;
+        leak_test(kdcrb, encode_krb5_kdc_req_body, decode_krb5_kdc_req_body,
+                  krb5_free_kdc_req);
+        ktest_empty_kdc_req(&kdcrb);
+    }
+  
+    /****************************************************************/
+    /* encode_krb5_safe */
+    {
+        krb5_safe s, *tmp;
+
+        setup(s, "safe", ktest_make_sample_safe);
+        leak_test(s, encode_krb5_safe, decode_krb5_safe, krb5_free_safe);
+
+        s.timestamp = 0;
+        /* s.usec should be opted out by the timestamp */
+        s.seq_number = 0;
+        ktest_destroy_address(&(s.r_address));
+        leak_test(s, encode_krb5_safe, decode_krb5_safe, krb5_free_safe);
+        ktest_empty_safe(&s);
+    }
+  
+    /****************************************************************/
+    /* encode_krb5_priv */
+    {
+        krb5_priv p, *tmp;
+
+        setup(p, "priv", ktest_make_sample_priv);
+        leak_test(p, encode_krb5_priv, decode_krb5_priv, krb5_free_priv);
+        ktest_empty_priv(&p);
+    }
+  
+    /****************************************************************/
+    /* encode_krb5_enc_priv_part */
+    {
+        krb5_priv_enc_part ep, *tmp;
+
+        setup(ep, "priv_enc_part", ktest_make_sample_priv_enc_part);
+        leak_test(ep, encode_krb5_enc_priv_part, decode_krb5_enc_priv_part,
+                  krb5_free_priv_enc_part);
+
+        ep.timestamp = 0;
+        /* ep.usec should be opted out along with timestamp */
+        ep.seq_number = 0;
+        ktest_destroy_address(&(ep.r_address));
+        leak_test(ep, encode_krb5_enc_priv_part, decode_krb5_enc_priv_part,
+                  krb5_free_priv_enc_part);
+        ktest_empty_priv_enc_part(&ep);
+    }
+  
+    /****************************************************************/
+    /* encode_krb5_cred */
+    {
+        krb5_cred c, *tmp;
+
+        setup(c, "cred", ktest_make_sample_cred);
+        leak_test(c, encode_krb5_cred, decode_krb5_cred, krb5_free_cred);
+        ktest_empty_cred(&c);
+    }
+  
+    /****************************************************************/
+    /* encode_krb5_enc_cred_part */
+    {
+        krb5_cred_enc_part cep, *tmp;
+        
+        setup(cep, "cred_enc_part", ktest_make_sample_cred_enc_part);
+        leak_test(cep, encode_krb5_enc_cred_part, decode_krb5_enc_cred_part,
+                  krb5_free_cred_enc_part);
+
+        ktest_destroy_principal(&(cep.ticket_info[0]->client));
+        ktest_destroy_principal(&(cep.ticket_info[0]->server));
+        cep.ticket_info[0]->flags = 0;
+        cep.ticket_info[0]->times.authtime = 0;
+        cep.ticket_info[0]->times.starttime = 0;
+        cep.ticket_info[0]->times.endtime = 0;
+        cep.ticket_info[0]->times.renew_till = 0;
+        ktest_destroy_addresses(&(cep.ticket_info[0]->caddrs));
+        cep.nonce = 0;
+        cep.timestamp = 0;
+        ktest_destroy_address(&(cep.s_address));
+        ktest_destroy_address(&(cep.r_address));
+        leak_test(cep, encode_krb5_enc_cred_part, decode_krb5_enc_cred_part,
+                  krb5_free_cred_enc_part);
+        ktest_empty_cred_enc_part(&cep);
+    }
+  
+    /****************************************************************/
+    /* encode_krb5_error */
+    {
+        krb5_error kerr, *tmp;
+
+        setup(kerr, "error", ktest_make_sample_error);
+        leak_test(kerr, encode_krb5_error, decode_krb5_error, krb5_free_error);
+
+        kerr.ctime = 0;
+        ktest_destroy_principal(&(kerr.client));
+        ktest_empty_data(&(kerr.text));
+        ktest_empty_data(&(kerr.e_data));
+        leak_test(kerr, encode_krb5_error, decode_krb5_error, krb5_free_error);
+
+        ktest_empty_error(&kerr);
+    }
+  
+    /****************************************************************/
+    /* encode_krb5_authdata */
+    {
+        krb5_authdata **ad, **tmp;
+
+        setup(ad, "authorization_data", ktest_make_sample_authorization_data);
+        leak_test(*ad, encode_krb5_authdata, decode_krb5_authdata,
+                  krb5_free_authdata);
+        ktest_destroy_authorization_data(&ad);
+    }
+  
+    /****************************************************************/
+    /* encode_pwd_sequence */
+    {
+        passwd_phrase_element ppe, *tmp;
+
+        setup(ppe, "PasswdSequence", ktest_make_sample_passwd_phrase_element);
+        leak_test(ppe, encode_krb5_pwd_sequence, decode_krb5_pwd_sequence,
+                  krb5_free_passwd_phrase_element);
+        ktest_empty_passwd_phrase_element(&ppe);
+    }
+
+    /****************************************************************/
+    /* encode_passwd_data */
+    {
+        krb5_pwd_data pd, *tmp;
+
+        setup(pd, "PasswdData", ktest_make_sample_krb5_pwd_data);
+        leak_test(pd, encode_krb5_pwd_data, decode_krb5_pwd_data,
+                  krb5_free_pwd_data);
+        ktest_empty_pwd_data(&pd);
+    }
+
+    /****************************************************************/
+    /* encode_padata_sequence */
+    {
+        krb5_pa_data **pa, **tmp;
+    
+        setup(pa, "PreauthData", ktest_make_sample_pa_data_array);
+        leak_test(*pa, encode_krb5_padata_sequence,
+                  decode_krb5_padata_sequence, krb5_free_pa_data);
+        ktest_destroy_pa_data_array(&pa);
+    }
+
+    /****************************************************************/
+    /* encode_padata_sequence (empty) */
+    {
+        krb5_pa_data **pa, **tmp;
+    
+        setup(pa,"EmptyPreauthData",ktest_make_sample_empty_pa_data_array);
+        leak_test(*pa, encode_krb5_padata_sequence,
+                  decode_krb5_padata_sequence, krb5_free_pa_data);
+        ktest_destroy_pa_data_array(&pa);
+    }
+
+    /****************************************************************/
+    /* encode_alt_method */
+    {
+        krb5_alt_method am, *tmp;
+
+        setup(am, "AltMethod", ktest_make_sample_alt_method);
+        leak_test(am, encode_krb5_alt_method, decode_krb5_alt_method,
+                  krb5_free_alt_method);
+        am.length = 0;
+        if (am.data)
+            free(am.data);
+        am.data = 0;
+        leak_test(am, encode_krb5_alt_method, decode_krb5_alt_method,
+                  krb5_free_alt_method);
+        ktest_empty_alt_method(&am);
+    }
+
+    /****************************************************************/
+    /* encode_etype_info */
+    {
+        krb5_etype_info_entry **info, **tmp;
+    
+        setup(info, "etype_info", ktest_make_sample_etype_info);
+        leak_test(*info, encode_krb5_etype_info, decode_krb5_etype_info,
+                  krb5_free_etype_info);
+
+        ktest_destroy_etype_info_entry(info[2]);      info[2] = 0;
+        ktest_destroy_etype_info_entry(info[1]);      info[1] = 0;
+        leak_test(*info, encode_krb5_etype_info, decode_krb5_etype_info,
+                  krb5_free_etype_info);
+
+        ktest_destroy_etype_info_entry(info[0]);      info[0] = 0;
+        leak_test(*info, encode_krb5_etype_info, decode_krb5_etype_info,
+                  krb5_free_etype_info);
+
+        ktest_destroy_etype_info(info);
+    }
+
+    /* encode_etype_info 2*/
+    {
+        krb5_etype_info_entry **info, **tmp;
+    
+        setup(info, "etype_info2", ktest_make_sample_etype_info2);
+        leak_test(*info, encode_krb5_etype_info2, decode_krb5_etype_info2,
+                  krb5_free_etype_info);
+
+        ktest_destroy_etype_info_entry(info[2]);      info[2] = 0;
+        ktest_destroy_etype_info_entry(info[1]);      info[1] = 0;
+        leak_test(*info, encode_krb5_etype_info2, decode_krb5_etype_info2,
+                  krb5_free_etype_info);
+
+        ktest_destroy_etype_info(info);
+    }
+
+    /****************************************************************/
+    /* encode_pa_enc_ts */
+    {
+        krb5_pa_enc_ts pa_enc, *tmp;
+
+        setup(pa_enc, "pa_enc_ts", ktest_make_sample_pa_enc_ts);
+        leak_test(pa_enc, encode_krb5_pa_enc_ts, decode_krb5_pa_enc_ts,
+                  krb5_free_pa_enc_ts);
+        pa_enc.pausec = 0;
+        leak_test(pa_enc, encode_krb5_pa_enc_ts, decode_krb5_pa_enc_ts,
+                  krb5_free_pa_enc_ts);
+    }
+
+    /****************************************************************/
+    /* encode_enc_data */
+    {
+        krb5_enc_data enc_data, *tmp;
+
+        setup(enc_data, "enc_data", ktest_make_sample_enc_data);
+        leak_test(enc_data, encode_krb5_enc_data, decode_krb5_enc_data,
+                  krb5_free_enc_data);
+        ktest_destroy_enc_data(&enc_data);
+    }
+    /****************************************************************/
+    /* encode_krb5_sam_challenge */
+    {
+        krb5_sam_challenge sam_ch, *tmp;
+
+        setup(sam_ch, "sam_challenge", ktest_make_sample_sam_challenge);
+        leak_test(sam_ch, encode_krb5_sam_challenge, decode_krb5_sam_challenge,
+                  krb5_free_sam_challenge);
+        ktest_empty_sam_challenge(&sam_ch);
+    }
+    /****************************************************************/
+    /* encode_krb5_sam_response */
+    {
+        krb5_sam_response sam_ch, *tmp;
+
+        setup(sam_ch, "sam_response", ktest_make_sample_sam_response);
+        leak_test(sam_ch, encode_krb5_sam_response, decode_krb5_sam_response,
+                  krb5_free_sam_response);
+        ktest_empty_sam_response(&sam_ch);
+    }
+    /****************************************************************/
+    /* encode_krb5_enc_sam_response_enc */
+    {
+        krb5_enc_sam_response_enc sam_ch, *tmp;
+
+        setup(sam_ch, "enc_sam_response_enc",
+              ktest_make_sample_enc_sam_response_enc);
+        leak_test(sam_ch, encode_krb5_enc_sam_response_enc,
+                  decode_krb5_enc_sam_response_enc,
+                  krb5_free_enc_sam_response_enc);
+        ktest_empty_enc_sam_response_enc(&sam_ch);
+    }
+    /****************************************************************/
+    /* encode_krb5_predicted_sam_response */
+    {
+        krb5_predicted_sam_response sam_ch, *tmp;
+
+        setup(sam_ch, "predicted_sam_response",
+              ktest_make_sample_predicted_sam_response);
+        leak_test(sam_ch, encode_krb5_predicted_sam_response,
+                  decode_krb5_predicted_sam_response,
+                  krb5_free_predicted_sam_response);
+        ktest_empty_predicted_sam_response(&sam_ch);
+    }
+  /****************************************************************/
+  /* encode_krb5_sam_response_2 */
+    {
+        krb5_sam_response_2 sam_ch2, *tmp;
+
+        setup(sam_ch2, "sam_response_2", ktest_make_sample_sam_response_2);
+        leak_test(sam_ch2, encode_krb5_sam_response_2,
+                  decode_krb5_sam_response_2, krb5_free_sam_response_2);
+        ktest_empty_sam_response_2(&sam_ch2);
+    }
+    /****************************************************************/
+    /* encode_krb5_sam_response_enc_2 */
+    {
+        krb5_enc_sam_response_enc_2 sam_ch2, *tmp;
+
+        setup(sam_ch2, "enc_sam_response_enc_2",
+              ktest_make_sample_enc_sam_response_enc_2);
+        leak_test(sam_ch2, encode_krb5_enc_sam_response_enc_2,
+                  decode_krb5_enc_sam_response_enc_2,
+                  krb5_free_enc_sam_response_enc_2);
+        ktest_empty_enc_sam_response_enc_2(&sam_ch2);
+    }
+
+    krb5_free_context(test_context);
+    return 0;
+}