test/harness/testcaseio.c
author ali <ali@juiblex.co.uk>
Fri Sep 06 22:35:23 2013 +0100 (2013-09-06)
changeset 82 0df25c7f4ed7
parent 11 4a80c6053a66
child 101 f44c530f80da
permissions -rw-r--r--
Add some resilence against unexpected input
     1 #include <stdlib.h>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <glib.h>
     5 #include <bl/bl.h>
     6 #include "testcaseparser.h"
     7 #include "testcaseinput.h"
     8 #include "testcaseio.h"
     9 #include "warningsparser.h"
    10 
    11 /*
    12  * Read a testcase in from a file.
    13  * On error, print a suitable message using g_printerr and return NULL.
    14  * The returned testcase should be freed with testcase_free().
    15  */
    16 Testcase *testcase_parse_file(const char *filename)
    17 {
    18     Testcase *testcase;
    19     TestcaseParser *parser;
    20     TestcaseInput *input=NULL;
    21     GMarkupParseContext *context;
    22     GError *err=NULL;
    23     char *s,*arg;
    24     const char *tag,*text;
    25     gboolean found_tag=FALSE;
    26     parser=testcase_parser_new_from_file(filename);
    27     if (!parser)
    28 	return NULL;
    29     if (!*testcase_parser_get_flag(parser))
    30     {
    31 	g_printerr("%s: Not a valid testcase (flag)\n",filename);
    32 	testcase_parser_free(parser);
    33 	return NULL;
    34     }
    35     testcase=g_new0(Testcase,1);
    36     testcase->basename=g_path_get_basename(filename);
    37     s=strrchr(testcase->basename,'.');
    38     if (s)
    39 	*s='\0';
    40     while(testcase_parser_get_next_tag(parser,&tag,&text))
    41     {
    42 	if (!input && !strcmp(tag,"INPUT"))
    43 	    input=testcase_input_new("TEST-XXXXXX",text);
    44 	else if (g_str_has_prefix(tag,"INPUT(") && tag[strlen(tag)-1]==')')
    45 	{
    46 	    arg=g_strndup(tag+6,strlen(tag)-7);
    47 	    s=g_path_get_dirname(arg);
    48 	    if (strcmp(s,"."))
    49 	    {
    50 		/*
    51 		 * Otherwise it would be possible to overwrite an arbitary
    52 		 * file on somebody's computer by getting them to run a
    53 		 * testcase!
    54 		 */
    55 		g_printerr(
    56 		  "%s: Input files may not have a directory component\n",arg);
    57 		g_free(s);
    58 		g_free(arg);
    59 		testcase_free(testcase);
    60 		testcase_parser_free(parser);
    61 		return NULL;
    62 	    }
    63 	    g_free(s);
    64 	    testcase->inputs=g_slist_prepend(testcase->inputs,
    65 	      testcase_input_new(arg,text));
    66 	    if (!strstr(arg,"XXXXXX"))
    67 		testcase->flags|=TESTCASE_TMP_DIR;
    68 	    g_free(arg);
    69 	}
    70 	else if (!testcase->expected && !testcase->warnings &&
    71 	  !strcmp(tag,"EXPECTED"))
    72 	    testcase->expected=g_strdup(text);
    73 	else if (!testcase->expected && !testcase->warnings &&
    74 	  !strcmp(tag,"WARNINGS"))
    75 	{
    76 	    context=warnings_parse_context_new(testcase);
    77 	    if (!g_markup_parse_context_parse(context,text,-1,&err) ||
    78 	      !g_markup_parse_context_end_parse(context,&err))
    79 	    {
    80 		g_markup_parse_context_free(context);
    81 		g_printerr("%s\n",err->message);
    82 		g_clear_error(&err);
    83 		testcase_free(testcase);
    84 		testcase_parser_free(parser);
    85 		return NULL;
    86 	    }
    87 	    g_markup_parse_context_free(context);
    88 	}
    89 	else if (!testcase->encoding && !strcmp(tag,"ENCODING"))
    90 	    testcase->encoding=g_strchomp(g_strdup(text));
    91 	else if (!testcase->encoding && !strcmp(tag,"OPTIONS"))
    92 	{
    93 	    testcase->options=g_strsplit(text,"\n",0);
    94 	    g_free(testcase->options[g_strv_length(testcase->options)-1]);
    95 	    testcase->options[g_strv_length(testcase->options)-1]=NULL;
    96 	}
    97 	else
    98 	{
    99 	    g_printerr("%s: Not a valid testcase (%s)\n",filename,tag);
   100 	    testcase_free(testcase);
   101 	    testcase_parser_free(parser);
   102 	    return NULL;
   103 	}
   104 	found_tag=TRUE;
   105     }
   106     if (!testcase_parser_at_eof(parser))
   107     {
   108 	if (found_tag)
   109 	    g_printerr("%s: Not a valid testcase (garbage at end)\n",
   110 	      filename);
   111 	else
   112 	    g_printerr("%s: Not a valid testcase (no valid tags)\n",
   113 	      filename);
   114 	testcase_free(testcase);
   115 	testcase_parser_free(parser);
   116 	return NULL;
   117     }
   118     if (!input)
   119 	input=testcase_input_new("TEST-XXXXXX",NULL);
   120     testcase->inputs=g_slist_prepend(testcase->inputs,input);
   121     testcase_parser_free(parser);
   122     return testcase;
   123 }