diff --git a/src/mkheader.c b/src/mkheader.c index 77826da..1d2ea20 100644 --- a/src/mkheader.c +++ b/src/mkheader.c @@ -1,779 +1,780 @@ /* mkheader.c - Create a header file for libgpg-error * Copyright (C) 2010 Free Software Foundation, Inc. * Copyright (C) 2014 g10 Code GmbH * * This file is free software; as a special exception the author gives * unlimited permission to copy and/or distribute it, with or without * modifications, as long as this notice is preserved. * * This file is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include #include #include #define PGM "mkheader" #define LINESIZE 1024 static char *host_triplet; /* malloced. */ static char *host_os; /* points into host_triplet. */ static char *srcdir; static const char *hdr_version; static const char *hdr_version_number; static int cross_building; /* Command line flag. */ /* Values take from the supplied config.h. */ static int have_stdint_h; static int have_sys_types_h; static int have_w32_system; static int have_w64_system; static char *replacement_for_off_type; static int use_posix_threads; /* Various state flags. */ static int stdint_h_included; static int sys_types_h_included; /* The usual free wrapper. */ static void xfree (void *a) { if (a) free (a); } static char * xmalloc (size_t n) { char *p; p = malloc (n); if (!p) { fputs (PGM ": out of core\n", stderr); exit (1); } return p; } static char * xstrdup (const char *string) { char *p; size_t len = strlen (string) + 1; p = xmalloc (len); memcpy (p, string, len); return p; } /* Return a malloced string with TRIPLET. If TRIPLET has an alias * return that instead. In general build-aux/config.sub should do the * aliasing but some returned triplets are anyway identical and thus * we use this function to map it to the canonical form. A pointer to * the OS part of the returned value is stored at R_OS. * NO_VENDOR_HACK is for internal use; caller must call with 0. */ static char * canon_host_triplet (const char *triplet, int no_vendor_hack, char **r_os) { struct { const char *name; const char *alias; } tbl[] = { {"i486-pc-linux-gnu", "i686-unknown-linux-gnu" }, {"i586-pc-linux-gnu" }, {"i686-pc-linux-gnu" }, {"arc-oe-linux-gnu" }, /* Other CPU but same struct. */ {"arc-oe-linux-uclibc" }, /* and uclibc is also the same. */ {"i486-pc-gnu", "i686-unknown-gnu"}, {"i586-pc-gnu"}, {"i686-pc-gnu"}, {"i486-pc-kfreebsd-gnu", "i686-unknown-kfreebsd-gnu"}, {"i586-pc-kfreebsd-gnu"}, {"i686-pc-kfreebsd-gnu"}, {"x86_64-pc-linux-gnuhardened1", "x86_64-unknown-linux-gnu" }, {"x86_64-pc-linux-gnu" }, {"powerpc-unknown-linux-gnuspe", "powerpc-unknown-linux-gnu" }, {"arm-unknown-linux-gnueabihf", "arm-unknown-linux-gnueabi" }, {"armv7-unknown-linux-gnueabihf" }, {"armv7a-unknown-linux-gnueabihf" }, {"armv5-unknown-linux-musleabi" }, {"armv6-unknown-linux-musleabihf" }, { NULL } }; int i; const char *lastalias = NULL; const char *s; char *p; char *result; for (i=0; tbl[i].name; i++) { if (tbl[i].alias) lastalias = tbl[i].alias; if (!strcmp (tbl[i].name, triplet)) { if (!lastalias) break; /* Ooops: first entry has no alias. */ result = xstrdup (lastalias); goto leave; } } for (i=0, s=triplet; *s; s++) if (*s == '-') i++; if (i > 2 && !no_vendor_hack) { /* We have a 4 part "triplet": CPU-VENDOR-KERNEL-SYSTEM where * the last two parts replace the OS part of a real triplet. * The VENDOR part is then in general useless because * KERNEL-SYSTEM is specific enough. We now do a second pass by * replacing VENDOR with "unknown". */ char *buf = xmalloc (strlen (triplet) + 7 + 1); for (p=buf,s=triplet,i=0; *s; s++) { *p++ = *s; if (*s == '-' && ++i == 1) { memcpy (p, "unknown-",8); p += 8; for (s++; *s != '-'; s++) ; } } *p = 0; result = canon_host_triplet (buf, 1, NULL); xfree (buf); goto leave; } result = xstrdup (triplet); leave: /* Find the OS part. */ if (r_os) { *r_os = result + strlen (result); /* Default to the empty string. */ for (i=0, p=result; *p; p++) if (*p == '-' && ++i == 2) { *r_os = p+1; break; } } return result; } /* Parse the supplied config.h file and extract required info. Returns 0 on success. */ static int parse_config_h (const char *fname) { FILE *fp; char line[LINESIZE]; int lnr = 0; char *p1; fp = fopen (fname, "r"); if (!fp) { fprintf (stderr, "%s:%d: can't open file: %s\n", fname, lnr, strerror (errno)); return 1; } while (fgets (line, LINESIZE, fp)) { size_t n = strlen (line); lnr++; if (!n || line[n-1] != '\n') { fprintf (stderr, "%s:%d: trailing linefeed missing, line too long or " "embedded nul character\n", fname, lnr); break; } line[--n] = 0; if (strncmp (line, "#define ", 8)) continue; /* We are only interested in define lines. */ p1 = strtok (line + 8, " \t"); if (!*p1) continue; /* oops */ if (!strcmp (p1, "HAVE_STDINT_H")) have_stdint_h = 1; else if (!strcmp (p1, "HAVE_SYS_TYPES_H")) have_sys_types_h = 1; else if (!strcmp (p1, "HAVE_W32_SYSTEM")) have_w32_system = 1; else if (!strcmp (p1, "HAVE_W64_SYSTEM")) have_w64_system = 1; else if (!strcmp (p1, "REPLACEMENT_FOR_OFF_T")) { p1 = strtok (NULL, "\""); if (!*p1) continue; /* oops */ xfree (replacement_for_off_type); replacement_for_off_type = xstrdup (p1); } else if (!strcmp (p1, "USE_POSIX_THREADS")) use_posix_threads = 1; } if (ferror (fp)) { fprintf (stderr, "%s:%d: error reading file: %s\n", fname, lnr, strerror (errno)); + fclose (fp); return 1; } fclose (fp); return 0; } /* Write LINE to stdout. The function is allowed to modify LINE. */ static void write_str (char *line) { if (fputs (line, stdout) == EOF) { fprintf (stderr, PGM ": error writing to stdout: %s\n", strerror (errno)); exit (1); } } static void write_line (char *line) { if (puts (line) == EOF) { fprintf (stderr, PGM ": error writing to stdout: %s\n", strerror (errno)); exit (1); } } /* Write SOURCE or CODES line to stdout. The function is allowed to modify LINE. Trailing white space is already removed. Passing NULL resets the internal state. */ static void write_sources_or_codes (char *line) { static int in_intro; char *p1, *p2; if (!line) { in_intro = 1; return; } if (!*line) return; if (in_intro) { if (!strchr ("0123456789", *line)) return; in_intro = 0; } p1 = strtok (line, " \t"); p2 = p1? strtok (NULL, " \t") : NULL; if (p1 && p2 && strchr ("0123456789", *p1) && *p2) { write_str (" "); write_str (p2); write_str (" = "); write_str (p1); write_str (",\n"); } } /* Write system errnos to stdout. The function is allowed to modify LINE. Trailing white space is already removed. Passing NULL resets the internal state. */ static void write_errnos_in (char *line) { static int state; char *p1, *p2; if (!line) { state = 0; return; } if (!*line) return; if (!state && strchr ("0123456789", *line)) state = 1; else if (state == 1 && !strchr ("0123456789", *line)) state = 2; if (state != 1) return; p1 = strtok (line, " \t"); p2 = p1? strtok (NULL, " \t") : NULL; if (p1 && p2 && strchr ("0123456789", *p1) && *p2) { write_str (" GPG_ERR_"); write_str (p2); write_str (" = GPG_ERR_SYSTEM_ERROR | "); write_str (p1); write_str (",\n"); } } /* Create the full file name for NAME and return a newly allocated string with it. If name contains a '&' and REPL is not NULL replace '&' with REPL. */ static char * mk_include_name (const char *name, const char *repl) { FILE *fp; char *incfname, *p; const char *s; incfname = malloc (strlen (srcdir) + strlen (name) + (repl?strlen (repl):0) + 1); if (!incfname) { fputs (PGM ": out of core\n", stderr); exit (1); } if (*name == '.' && name[1] == '/') *incfname = 0; else strcpy (incfname, srcdir); p = incfname + strlen (incfname); for (s=name; *s; s++) { if (*s == '&' && repl) { while (*repl) *p++ = *repl++; repl = NULL; /* Replace only once. */ } else *p++ = *s; } *p = 0; return incfname; } /* Include the file NAME from the source directory. The included file is not further expanded. It may have comments indicated by a double hash mark at the begin of a line. OUTF is called for each read line and passed a buffer with the content of line sans line line endings. If NAME is prefixed with "./" it is included from the current directory and not from the source directory. */ static void include_file (const char *fname, int lnr, const char *name, void (*outf)(char*)) { FILE *fp; char *incfname; int inclnr; char line[LINESIZE]; int repl_flag; repl_flag = !!strchr (name, '&'); incfname = mk_include_name (name, repl_flag? host_triplet : NULL); fp = fopen (incfname, "r"); if (!fp && repl_flag) { /* Try again using the OS string. */ free (incfname); incfname = mk_include_name (name, host_os); fp = fopen (incfname, "r"); } if (!fp) { fprintf (stderr, "%s:%d: error including `%s': %s\n", fname, lnr, incfname, strerror (errno)); exit (1); } if (repl_flag) fprintf (stderr,"%s:%d: note: including '%s'\n", fname, lnr, incfname); inclnr = 0; while (fgets (line, LINESIZE, fp)) { size_t n = strlen (line); inclnr++; if (!n || line[n-1] != '\n') { fprintf (stderr, "%s:%d: trailing linefeed missing, line too long or " "embedded nul character\n", incfname, inclnr); fprintf (stderr,"%s:%d: note: file '%s' included from here\n", fname, lnr, incfname); exit (1); } line[--n] = 0; while (line[n] == ' ' || line[n] == '\t' || line[n] == '\r') { line[n] = 0; if (!n) break; n--; } if (line[0] == '#' && line[1] == '#') { if (!strncmp (line+2, "EOF##", 5)) break; /* Forced EOF. */ } else outf (line); } if (ferror (fp)) { fprintf (stderr, "%s:%d: error reading `%s': %s\n", fname, lnr, incfname, strerror (errno)); exit (1); } fclose (fp); free (incfname); } /* Try to include the file NAME. Returns true if it does not exist. */ static int try_include_file (const char *fname, int lnr, const char *name, void (*outf)(char*)) { int rc; char *incfname; int repl_flag; repl_flag = !!strchr (name, '&'); incfname = mk_include_name (name, repl_flag? host_triplet : NULL); rc = access (incfname, R_OK); if (rc && repl_flag) { free (incfname); incfname = mk_include_name (name, host_os); rc = access (incfname, R_OK); } if (!rc) include_file (fname, lnr, name, outf); free (incfname); return rc; } static int write_special (const char *fname, int lnr, const char *tag) { if (!strcmp (tag, "version")) { putchar ('\"'); fputs (hdr_version, stdout); putchar ('\"'); } else if (!strcmp (tag, "version-number")) { fputs (hdr_version_number, stdout); } else if (!strcmp (tag, "define:gpgrt_off_t")) { if (!replacement_for_off_type) { fprintf (stderr, "%s:%d: replacement for off_t not defined\n", fname, lnr); exit (1); } else { if (!strcmp (replacement_for_off_type, "int64_t") && !stdint_h_included && have_stdint_h) { fputs ("#include \n\n", stdout); stdint_h_included = 1; } printf ("typedef %s gpgrt_off_t;\n", replacement_for_off_type); } } else if (!strcmp (tag, "define:gpgrt_ssize_t")) { if (have_w64_system) { if (!stdint_h_included && have_stdint_h) { fputs ("# include \n", stdout); stdint_h_included = 1; } fputs ("typedef int64_t gpgrt_ssize_t;\n", stdout); } else if (have_w32_system) { fputs ("typedef long gpgrt_ssize_t;\n", stdout); } else { if (!sys_types_h_included) { fputs ("#include \n", stdout); sys_types_h_included = 1; } fputs ("typedef ssize_t gpgrt_ssize_t;\n", stdout); } } else if (!strcmp (tag, "api_ssize_t")) { if (have_w32_system) fputs ("gpgrt_ssize_t", stdout); else fputs ("ssize_t", stdout); } else if (!strcmp (tag, "define:pid_t")) { if (have_sys_types_h) { if (!sys_types_h_included) { fputs ("#include \n", stdout); sys_types_h_included = 1; } } else if (have_w64_system) { if (!stdint_h_included && have_stdint_h) { fputs ("#include \n", stdout); stdint_h_included = 1; } fputs ("typedef int64_t pid_t\n", stdout); } else { fputs ("typedef int pid_t\n", stdout); } } else if (!strcmp (tag, "include:err-sources")) { write_sources_or_codes (NULL); include_file (fname, lnr, "err-sources.h.in", write_sources_or_codes); } else if (!strcmp (tag, "include:err-codes")) { write_sources_or_codes (NULL); include_file (fname, lnr, "err-codes.h.in", write_sources_or_codes); } else if (!strcmp (tag, "include:errnos")) { include_file (fname, lnr, "errnos.in", write_errnos_in); } else if (!strcmp (tag, "include:os-add")) { if (!strcmp (host_os, "mingw32")) { include_file (fname, lnr, "w32-add.h", write_line); } else if (!strcmp (host_os, "mingw32ce")) { include_file (fname, lnr, "w32-add.h", write_line); include_file (fname, lnr, "w32ce-add.h", write_line); } } else if (!strcmp (tag, "include:lock-obj")) { /* If we are not cross compiling and the native file exists we * prefer that over one from syscfg. */ if (cross_building || try_include_file (fname, lnr, "./lock-obj-pub.native.h", write_line)) include_file (fname, lnr, "syscfg/lock-obj-pub.&.h", write_line); } else return 0; /* Unknown tag. */ return 1; /* Tag processed. */ } int main (int argc, char **argv) { FILE *fp = NULL; char line[LINESIZE]; int lnr = 0; const char *fname, *s; char *p1, *p2; const char *config_h; const char *host_triplet_raw; if (argc) { argc--; argv++; } if (argc && !strcmp (argv[0], "--cross")) { cross_building = 1; argc--; argv++; } if (argc == 1) { /* Print just the canonicalized host triplet. */ host_triplet = canon_host_triplet (argv[0], 0, &host_os); printf ("%s\n", host_triplet); goto leave; } else if (argc == 5) ; /* Standard operation. */ else { fputs ("usage: " PGM " host_triplet template.h config.h version version_number\n" " " PGM " host_triplet\n", stderr); return 1; } host_triplet_raw = argv[0]; fname = argv[1]; config_h = argv[2]; hdr_version = argv[3]; hdr_version_number = argv[4]; host_triplet = canon_host_triplet (host_triplet_raw, 0, &host_os); srcdir = malloc (strlen (fname) + 2 + 1); if (!srcdir) { fputs (PGM ": out of core\n", stderr); return 1; } strcpy (srcdir, fname); p1 = strrchr (srcdir, '/'); if (p1) p1[1] = 0; else strcpy (srcdir, "./"); if (parse_config_h (config_h)) return 1; fp = fopen (fname, "r"); if (!fp) { fprintf (stderr, "%s:%d: can't open file: %s\n", fname, lnr, strerror (errno)); return 1; } while (fgets (line, LINESIZE, fp)) { size_t n = strlen (line); lnr++; if (!n || line[n-1] != '\n') { fprintf (stderr, "%s:%d: trailing linefeed missing, line too long or " "embedded nul character\n", fname, lnr); break; } line[--n] = 0; p1 = strchr (line, '@'); p2 = p1? strchr (p1+1, '@') : NULL; if (!p1 || !p2 || p2-p1 == 1) { puts (line); continue; } *p1++ = 0; *p2++ = 0; fputs (line, stdout); if (!strcmp (p1, "configure_input")) { s = strrchr (fname, '/'); printf ("Do not edit. Generated from %s for:\n%*s", s? s+1 : fname, (int)(p1 - line) + 13, ""); if (!strcmp (host_triplet, host_triplet_raw)) printf ("%s", host_triplet); else printf ("%s (%s)", host_triplet, host_triplet_raw); if (!use_posix_threads && !have_w32_system && !have_w64_system) fputs (" NO-THREADS", stdout); fputs (p2, stdout); } else if (!write_special (fname, lnr, p1)) { putchar ('@'); fputs (p1, stdout); putchar ('@'); fputs (p2, stdout); } else if (*p2) { fputs (p2, stdout); } putchar ('\n'); } if (ferror (fp)) { fprintf (stderr, "%s:%d: error reading file: %s\n", fname, lnr, strerror (errno)); return 1; } fputs ("/*\n" "Loc" "al Variables:\n" "buffer-read-only: t\n" "End:\n" "*/\n", stdout); leave: if (ferror (stdout)) { fprintf (stderr, PGM ": error writing to stdout: %s\n", strerror (errno)); return 1; } if (fp) fclose (fp); xfree (host_triplet); return 0; } diff --git a/tests/t-b64.c b/tests/t-b64.c index 0171909..db08fc0 100644 --- a/tests/t-b64.c +++ b/tests/t-b64.c @@ -1,374 +1,376 @@ /* t-b64.c - b64dec tests. * Copyright (C) 2017, 2018 g10 Code GmbH * * This file is part of Libgpg-error. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This file 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, see . * SPDX-License-Identifier: LGPL-2.1-or-later */ #if HAVE_CONFIG_H #include #endif #include #include #if HAVE_STDLIB_H #include #endif #define PGM "t-b64" #include "t-common.h" static const char *test_string = "libgpg-error is free software; " "you can redistribute it and/or modify it under the terms of " "the GNU Lesser General Public License as published by the Free " "Software Foundation; either version 2.1 of the License, or " "(at your option) any later version."; static const char *test_string_b64_0 = "bGliZ3BnLWVycm9yIGlzIGZyZWUgc29" "mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgd" "W5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIEx" "pY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb" "247IGVpdGhlciB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXI" "gb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4="; static const char *test_string_b64_1 = "bGliZ3BnLWVycm9yIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmli\n" "dXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBH\n" "TlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5\n" "IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIu\n" "MSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIg\n" "dmVyc2lvbi4=\n"; static const char *test_string_b64_2 = "-----BEGIN DATA-----\n" "bGliZ3BnLWVycm9yIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmli\n" "dXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBH\n" "TlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5\n" "IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIu\n" "MSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIg\n" "dmVyc2lvbi4=\n" "-----END DATA-----\n"; static const char *test_string_b64_3 = "-----BEGIN PGP ARMORED FILE-----\n" "\n" "bGliZ3BnLWVycm9yIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmli\n" "dXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBH\n" "TlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5\n" "IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIu\n" "MSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIg\n" "dmVyc2lvbi4=\n" "=4BMJ\n" "-----END PGP ARMORED FILE-----\n"; static const char *test_blob_1 = "\x01\x03\x04\xff"; static const char *test_blob_1_b64_0 = "AQME/w=="; static const char *test_blob_2 = "\x01\x03\x04\xff""A"; static const char *test_blob_2_b64_0 = "AQME/0E="; static const char *test_blob_3 = "\x01\x03\x04\xff""AB"; static const char *test_blob_3_b64_0 = "AQME/0FC"; #define FAIL(a) do { fail ("line %d: test %d failed\n", __LINE__, (a)); \ } while(0) static gpg_error_t test_b64enc_string (const char *string, const char *expected, const char *title) { gpg_err_code_t err; estream_t fp; gpgrt_b64state_t state; char *result; fp = es_fopenmem (0, "rwb"); if (!fp) die ("es_fopenmem failed: %s\n", gpg_strerror (gpg_error_from_syserror ())); state = gpgrt_b64enc_start (fp, title); if (!state) { err = gpg_err_code_from_syserror (); fail ("gpgrt_b64enc_start failed: %s\n", gpg_strerror (err)); return err; } err = gpgrt_b64enc_write (state, string, strlen (string)); if (err) { + free (state); fail ("gpgrt_b64enc_write failed: %s\n", gpg_strerror (err)); return err; } err = gpgrt_b64enc_finish (state); if (err) { fail ("gpgrt_b64enc_finish failed: %s\n", gpg_strerror (err)); return err; } es_fputc (0, fp); if (es_fclose_snatch (fp, (void**)&result, NULL)) die ("es_fclose_snatch failed: %s\n", gpg_strerror (gpg_error_from_syserror ())); if (strcmp (result, expected)) { if (verbose) { gpgrt_log_debug_string (result, "result: "); gpgrt_log_debug_string (expected, "expect: "); } return GPG_ERR_FALSE; } es_free (result); return 0; } static gpg_error_t test_b64dec_string (const char *string, const char *expected, const char *title) { gpg_error_t err; gpgrt_b64state_t state; char *buffer; size_t len; len = strlen (string); buffer = malloc (strlen (string) + 1); if (!buffer) { err = gpg_error_from_syserror (); return err; } strcpy (buffer, string); state = gpgrt_b64dec_start (title); if (!state) { err = gpg_err_code_from_syserror (); fail ("gpgrt_b64dec_start failed: %s\n", gpg_strerror (err)); free (buffer); return err; } err = gpgrt_b64dec_proc (state, buffer, len, &len); if (err) { if (gpg_err_code (err) != GPG_ERR_EOF) { free (buffer); free (state); return err; } } err = gpgrt_b64dec_finish (state); if (err) { free (buffer); return err; } if (len != strlen (expected) || strncmp (buffer, expected, len)) { if (verbose) { gpgrt_log_debug_string (buffer, "result(len=%zu): ", len); gpgrt_log_debug_string (expected, "expect(len=%zu): ", strlen (expected)); } + free (buffer); return GPG_ERR_FALSE; } free (buffer); return 0; } static void encoder_tests (void) { gpg_err_code_t err; if (verbose) show ("running encoder tests\n"); err = test_b64enc_string (test_string, test_string_b64_0, ""); if (err) fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); err = test_b64enc_string (test_string, test_string_b64_1, NULL); if (err) fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); err = test_b64enc_string (test_string, test_string_b64_2, "DATA"); if (err) fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); err = test_b64enc_string (test_string, test_string_b64_3, "PGP ARMORED FILE"); if (err) fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); /* Note that the _test_ function dows not allow to provide a string * with an empdded Nul. */ err = test_b64enc_string (test_blob_1, test_blob_1_b64_0, ""); if (err) fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); err = test_b64enc_string (test_blob_2, test_blob_2_b64_0, ""); if (err) fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); err = test_b64enc_string (test_blob_3, test_blob_3_b64_0, ""); if (err) fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); err = test_b64enc_string ("@", "QA==", ""); if (err) fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); err = test_b64enc_string ("@", "QA==\n", NULL); if (err) fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); err = test_b64enc_string ("@", "-----BEGIN PGP SOMETHING-----\n" "\n" "QA==\n" "=eMoB\n" "-----END PGP SOMETHING-----\n", "PGP SOMETHING"); if (err) fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); err = test_b64enc_string ("", "", ""); if (err) fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); err = test_b64enc_string ("", "", NULL); if (err) fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); err = test_b64enc_string ("", "", "PGP SOMETHING"); if (err) fail ("encoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); } static void decoder_tests (void) { gpg_err_code_t err; if (verbose) show ("running decoder tests\n"); err = test_b64dec_string (test_string_b64_0, test_string, NULL); if (err) fail ("decoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); err = test_b64dec_string (test_string_b64_1, test_string, NULL); if (err) fail ("decoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); err = test_b64dec_string (test_string_b64_2, test_string, ""); if (err) fail ("decoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); err = test_b64dec_string (test_string_b64_2, test_string, NULL); if (err != GPG_ERR_BAD_DATA) fail ("decoder test at line %d failed: %s\n", __LINE__, gpg_strerror (err)); } static gpg_error_t extra_tests (void) { gpg_err_code_t err; gpgrt_b64state_t state; if (verbose) show ("running extra tests\n"); /* Check that we detect mismacthed use of enc and dec functions. */ state = gpgrt_b64enc_start (es_stdout, NULL); if (!state) { err = gpg_err_code_from_syserror (); fail ("gpgrt_b64enc_start failed: %s\n", gpg_strerror (err)); return err; } err = gpgrt_b64dec_finish (state); if (err != GPG_ERR_CONFLICT) { fail ("gpgrt_b64dec_finish failed: %s\n", gpg_strerror (err)); return err; } state = gpgrt_b64dec_start (NULL); if (!state) { err = gpg_err_code_from_syserror (); fail ("gpgrt_b64dec_start failed: %s\n", gpg_strerror (err)); return err; } err = gpgrt_b64enc_finish (state); if (err != GPG_ERR_CONFLICT) { fail ("gpgrt_b64enc_finish failed: %s\n", gpg_strerror (err)); return err; } return 0; } int main (int argc, char **argv) { int last_argc = -1; if (argc) { argc--; argv++; } while (argc && last_argc != argc ) { last_argc = argc; if (!strcmp (*argv, "--help")) { puts ( "usage: ./" PGM " [options]\n" "\n" "Options:\n" " --verbose Show what is going on\n" " --debug Flyswatter\n" ); exit (0); } if (!strcmp (*argv, "--verbose")) { verbose = 1; argc--; argv++; } else if (!strcmp (*argv, "--debug")) { verbose = debug = 1; argc--; argv++; } } encoder_tests (); decoder_tests (); extra_tests (); return !!errorcount; } diff --git a/tests/t-syserror.c b/tests/t-syserror.c index a4cb983..93264dd 100644 --- a/tests/t-syserror.c +++ b/tests/t-syserror.c @@ -1,87 +1,88 @@ /* t-syserror.c - System error specific regression test. Copyright (C) 2006 g10 Code GmbH This file is part of libgpg-error. libgpg-error is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. libgpg-error 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with libgpgme-error; if not, write to the Free Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #if HAVE_CONFIG_H #include #endif #include #if HAVE_STDLIB_H #include #endif #include #include int main (int argc, char *argv[]) { FILE *fp; int save_errno; gpg_err_code_t ec; (void)argc; (void)argv; fp = fopen ("/does-not-exist/110761/nowhere.foo", "r"); if (fp) { fclose (fp); fp = fopen (" no this file does not exists foo 4711", "r"); } if (fp) { + fclose (fp); fprintf (stderr, "unable to run test\n"); return 1; } save_errno = errno; ec = gpg_err_code_from_syserror (); if (ec != GPG_ERR_ENOENT) { fprintf (stderr, "fopen failed with bad code: %d\n", save_errno); return 1; } if (ec != gpg_err_code_from_errno (save_errno)) { fprintf (stderr, "oops at %d\n",__LINE__); return 1; } gpg_err_set_errno (0); ec = gpg_err_code_from_syserror (); if (ec != GPG_ERR_MISSING_ERRNO) { fprintf (stderr, "oops at %d\n",__LINE__); return 1; } if ( gpg_err_code_from_errno (0) ) { fprintf (stderr, "oops at %d\n",__LINE__); return 1; } return 0; }