]> granicus.if.org Git - curl/commitdiff
Overhauled test suite getpart() function. Fixing potential out of bounds
authorYang Tse <yangsita@gmail.com>
Sun, 14 Feb 2010 13:14:17 +0000 (13:14 +0000)
committerYang Tse <yangsita@gmail.com>
Sun, 14 Feb 2010 13:14:17 +0000 (13:14 +0000)
stack and memory overwrites triggered with huge test case definitions.

CHANGES
tests/server/getpart.c
tests/server/getpart.h
tests/server/rtspd.c
tests/server/sws.c
tests/server/testpart.c
tests/server/tftpd.c

diff --git a/CHANGES b/CHANGES
index d606b6aefd871cd8a8f47a0156efea9ac5f45864..395ff5ebacbf85b7327f5ce0608ac8360f5949b1 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,10 @@
 
                                   Changelog
 
+Yang Tse (14 Feb 2010)
+- Overhauled test suite getpart() function. Fixing potential out of bounds
+  stack and memory overwrites triggered with huge test case definitions.
+
 Daniel Stenberg (13 Feb 2010)
 - Martin Hager reported and fixed a problem with a missing quote in libcurl.m4
 
index 59cb4ab4cccae5b47fecfe02fbfde212be60babe..ec4198cecde77e8b2f183c845ab9eba8cca8e91d 100644 (file)
@@ -41,11 +41,11 @@ struct SessionHandle {
 /* include memdebug.h last */
 #include "memdebug.h"
 
-#define EAT_SPACE(ptr) while( ptr && *ptr && ISSPACE(*ptr) ) ptr++
-#define EAT_WORD(ptr) while( ptr && *ptr && !ISSPACE(*ptr) && \
-                            ('>' != *ptr)) ptr++
+#define EAT_SPACE(p) while(*(p) && ISSPACE(*(p))) (p)++
 
-#ifdef DEBUG
+#define EAT_WORD(p)  while(*(p) && !ISSPACE(*(p)) && ('>' != *(p))) (p)++
+
+#ifdef DEBUG_GETPART
 #define show(x) printf x
 #else
 #define show(x)
@@ -65,191 +65,352 @@ curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc;
 #  pragma warning(default:4232) /* MSVC extension, dllimport identity */
 #endif
 
-static
-char *appendstring(char *string, /* original string */
-                   char *buffer, /* to append */
-                   size_t *stringlen, /* length of string */
-                   size_t *stralloc,  /* allocated size */
-                   char base64) /* 1 if base64 encoded */
+/*
+ * readline()
+ *
+ * Reads a complete line from a file into a dynamically allocated buffer.
+ *
+ * Calling function may call this multiple times with same 'buffer'
+ * and 'bufsize' pointers to avoid multiple buffer allocations. Buffer
+ * will be reallocated and 'bufsize' increased until whole line fits in
+ * buffer before returning it.
+ *
+ * Calling function is responsible to free allocated buffer.
+ *
+ * This function may return:
+ *   GPE_OUT_OF_MEMORY
+ *   GPE_END_OF_FILE
+ *   GPE_OK
+ */
+
+static int readline(char **buffer, size_t *bufsize, FILE *stream)
+{
+  size_t offset = 0;
+  size_t length;
+  char *newptr;
+
+  if(!*buffer) {
+    *buffer = malloc(128);
+    if(!*buffer)
+      return GPE_OUT_OF_MEMORY;
+    *bufsize = 128;
+  }
+
+  for(;;) {
+    if(!fgets(*buffer + offset, (int)(*bufsize - offset), stream))
+      return (offset != 0) ? GPE_OK : GPE_END_OF_FILE ;
+
+    length = offset + strlen(*buffer + offset);
+    if(*(*buffer + length - 1) == '\n')
+      break;
+    offset = length;
+    if(length < *bufsize - 1)
+      continue;
+
+    newptr = realloc(*buffer, *bufsize * 2);
+    if(!newptr)
+      return GPE_OUT_OF_MEMORY;
+    *buffer = newptr;
+    *bufsize *= 2;
+  }
+
+  return GPE_OK;
+}
+
+/*
+ * appenddata()
+ *
+ * This appends data from a given source buffer to the end of the used part of
+ * a destination buffer. Arguments relative to the destination buffer are, the
+ * address of a pointer to the destination buffer 'dst_buf', the length of data
+ * in destination buffer excluding potential null string termination 'dst_len',
+ * the allocated size of destination buffer 'dst_alloc'. All three destination
+ * buffer arguments may be modified by this function. Arguments relative to the
+ * source buffer are, a pointer to the source buffer 'src_buf' and indication
+ * whether the source buffer is base64 encoded or not 'src_b64'.
+ *
+ * If the source buffer is indicated to be base64 encoded, this appends the
+ * decoded data, binary or whatever, to the destination. The source buffer
+ * may not hold binary data, only a null terminated string is valid content.
+ *
+ * Destination buffer will be enlarged and relocated as needed.
+ *
+ * Calling function is responsible to provide preallocated destination
+ * buffer and also to deallocate it when no longer needed.
+ *
+ * This function may return:
+ *   GPE_OUT_OF_MEMORY
+ *   GPE_OK
+ */
+
+static int appenddata(char  **dst_buf,   /* dest buffer */
+                      size_t *dst_len,   /* dest buffer data length */
+                      size_t *dst_alloc, /* dest buffer allocated size */
+                      char   *src_buf,   /* source buffer */
+                      int     src_b64)   /* != 0 if source is base64 encoded */
 {
+  size_t need_alloc, src_len;
   union {
-    unsigned char * as_uchar;
-             char * as_char;
+    unsigned char *as_uchar;
+             char *as_char;
   } buf64;
 
-  size_t len = strlen(buffer);
-  size_t needed_len = len + *stringlen + 1;
+  src_len = strlen(src_buf);
+  if(!src_len)
+    return GPE_OK;
 
   buf64.as_char = NULL;
 
-  if(base64) {
-    /* decode the given buffer first */
-    len = Curl_base64_decode(buffer, &buf64.as_uchar); /* updated len */
-    buffer = buf64.as_char;
-    needed_len = len + *stringlen + 1; /* recalculate */
+  if(src_b64) {
+    /* base64 decode the given buffer */
+    src_len = Curl_base64_decode(src_buf, &buf64.as_uchar);
+    src_buf = buf64.as_char;
+    if(!src_len || !src_buf) {
+      /*
+      ** currently there is no way to tell apart an OOM condition in
+      ** Curl_base64_decode() from zero length decoded data. For now,
+      ** let's just assume it is an OOM condition, currently we have
+      ** no input for this function that decodes to zero length data.
+      */
+      if(buf64.as_char)
+        free(buf64.as_char);
+      return GPE_OUT_OF_MEMORY;
+    }
   }
 
-  if(needed_len >= *stralloc) {
-    char *newptr;
-    size_t newsize = needed_len*2; /* get twice the needed size */
+  need_alloc = src_len + *dst_len + 1;
 
-    newptr = realloc(string, newsize);
-    if(newptr) {
-      string = newptr;
-      *stralloc = newsize;
-    }
-    else {
+  /* enlarge destination buffer if required */
+  if(need_alloc > *dst_alloc) {
+    size_t newsize = need_alloc * 2;
+    char *newptr = realloc(*dst_buf, newsize);
+    if(!newptr) {
       if(buf64.as_char)
         free(buf64.as_char);
-      return NULL;
+      return GPE_OUT_OF_MEMORY;
     }
+    *dst_alloc = newsize;
+    *dst_buf = newptr;
   }
+
   /* memcpy to support binary blobs */
-  memcpy(&string[*stringlen], buffer, len);
-  *stringlen += len;
-  string[*stringlen]=0;
+  memcpy(*dst_buf + *dst_len, src_buf, src_len);
+  *dst_len += src_len;
+  *(*dst_buf + *dst_len) = '\0';
 
   if(buf64.as_char)
     free(buf64.as_char);
 
-  return string;
+  return GPE_OK;
 }
 
-const char *spitout(FILE *stream,
-                    const char *main,
-                    const char *sub, size_t *size)
+/*
+ * getpart()
+ *
+ * This returns whole contents of specified XML-like section and subsection
+ * from the given file. This is mostly used to retrieve a specific part from
+ * a test definition file for consumption by test suite servers.
+ *
+ * Data is returned in a dynamically allocated buffer, a pointer to this data
+ * and the size of the data is stored at the addresses that caller specifies.
+ *
+ * If the returned data is a string the returned size will be the length of
+ * the string excluding null termination. Otherwise it will just be the size
+ * of the returned binary data.
+ *
+ * Calling function is responsible to free returned buffer.
+ *
+ * This function may return:
+ *   GPE_NO_BUFFER_SPACE
+ *   GPE_OUT_OF_MEMORY
+ *   GPE_OK
+ */
+
+int getpart(char **outbuf, size_t *outlen,
+            const char *main, const char *sub, FILE *stream)
 {
-  char buffer[8192]; /* big enough for anything */
-  char cmain[128]=""; /* current main section */
-  char csub[128]="";  /* current sub section */
+# define MAX_TAG_LEN 79
+  char couter[MAX_TAG_LEN+1]; /* current outermost section */
+  char cmain[MAX_TAG_LEN+1];  /* current main section */
+  char csub[MAX_TAG_LEN+1];   /* current sub section */
+  char ptag[MAX_TAG_LEN+1];   /* potential tag */
+  char patt[MAX_TAG_LEN+1];   /* potential attributes */
+  char *buffer = NULL;
   char *ptr;
   char *end;
-  char display = 0;
-
-  char *string;
-  size_t stringlen=0;
-  size_t stralloc=256;
-  char base64 = 0; /* set to 1 if true */
+  size_t length;
+  size_t bufsize = 0;
+  size_t outalloc = 256;
+  int in_wanted_part = 0;
+  int base64 = 0;
+  int error;
 
   enum {
-    STATE_OUTSIDE,
-    STATE_OUTER,
-    STATE_INMAIN,
-    STATE_INSUB,
-    STATE_ILLEGAL
+    STATE_OUTSIDE = 0,
+    STATE_OUTER   = 1,
+    STATE_INMAIN  = 2,
+    STATE_INSUB   = 3,
+    STATE_ILLEGAL = 4
   } state = STATE_OUTSIDE;
 
-  string = malloc(stralloc);
-  if(!string)
-    return NULL;
+  *outlen = 0;
+  *outbuf = malloc(outalloc);
+  if(!*outbuf)
+    return GPE_OUT_OF_MEMORY;
+  *(*outbuf) = '\0';
 
-  string[0] = 0; /* zero first byte in case of no data */
+  couter[0] = cmain[0] = csub[0] = ptag[0] = patt[0] = '\0';
 
-  while(fgets(buffer, sizeof(buffer), stream)) {
+  while((error = readline(&buffer, &bufsize, stream)) == GPE_OK) {
 
     ptr = buffer;
-
-    /* pass white spaces */
     EAT_SPACE(ptr);
 
     if('<' != *ptr) {
-      if(display) {
+      if(in_wanted_part) {
         show(("=> %s", buffer));
-        string = appendstring(string, buffer, &stringlen, &stralloc, base64);
-        show(("* %s\n", buffer));
+        error = appenddata(outbuf, outlen, &outalloc, buffer, base64);
+        if(error)
+          break;
       }
       continue;
     }
 
     ptr++;
-    EAT_SPACE(ptr);
 
     if('/' == *ptr) {
-      /* end of a section */
-      ptr++;
-      EAT_SPACE(ptr);
+      /*
+      ** closing section tag
+      */
 
+      ptr++;
       end = ptr;
       EAT_WORD(end);
-      *end = 0;
-
-      if((state == STATE_INSUB) &&
-         !strcmp(csub, ptr)) {
-        /* this is the end of the currently read sub section */
-        state--;
-        csub[0]=0; /* no sub anymore */
-        display=0;
+      if((length = end - ptr) > MAX_TAG_LEN) {
+        error = GPE_NO_BUFFER_SPACE;
+        break;
       }
-      else if((state == STATE_INMAIN) &&
-              !strcmp(cmain, ptr)) {
-        /* this is the end of the currently read main section */
-        state--;
-        cmain[0]=0; /* no main anymore */
-        display=0;
+      memcpy(ptag, ptr, length);
+      ptag[length] = '\0';
+
+      if((STATE_INSUB == state) && !strcmp(csub, ptag)) {
+        /* end of current sub section */
+        state = STATE_INMAIN;
+        csub[0] = '\0';
+        if(in_wanted_part) {
+          /* end of wanted part */
+          in_wanted_part = 0;
+          break;
+        }
+      }
+      else if((STATE_INMAIN == state) && !strcmp(cmain, ptag)) {
+        /* end of current main section */
+        state = STATE_OUTER;
+        cmain[0] = '\0';
+        if(in_wanted_part) {
+          /* end of wanted part */
+          in_wanted_part = 0;
+          break;
+        }
       }
-      else if(state == STATE_OUTER) {
-        /* this is the end of the outermost file section */
-        state--;
+      else if((STATE_OUTER == state) && !strcmp(couter, ptag)) {
+        /* end of outermost file section */
+        state = STATE_OUTSIDE;
+        couter[0] = '\0';
+        if(in_wanted_part) {
+          /* end of wanted part */
+          in_wanted_part = 0;
+          break;
+        }
       }
+
     }
-    else if(!display) {
-      /* this is the beginning of a section */
+    else if(!in_wanted_part) {
+      /*
+      ** opening section tag
+      */
+
+      /* get potential tag */
       end = ptr;
       EAT_WORD(end);
-
-      *end = 0;
-      switch(state) {
-      case STATE_OUTSIDE:
-        /* Skip over the outermost element (<testcase>), but if it turns out
-           to be a comment, completely ignore it below */
-        strcpy(cmain, ptr);
-        state = STATE_OUTER;
-        break;
-      case STATE_OUTER:
-        strcpy(cmain, ptr);
-        state = STATE_INMAIN;
-        break;
-      case STATE_INMAIN:
-        strcpy(csub, ptr);
-        state = STATE_INSUB;
+      if((length = end - ptr) > MAX_TAG_LEN) {
+        error = GPE_NO_BUFFER_SPACE;
         break;
-      default:
+      }
+      memcpy(ptag, ptr, length);
+      ptag[length] = '\0';
+
+      /* ignore comments, doctypes and xml declarations */
+      if(('!' == ptag[0]) || ('?' == ptag[0])) {
+        show(("* ignoring (%s)", buffer));
+        continue;
+      }
+
+      /* get all potential attributes */
+      ptr = end;
+      EAT_SPACE(ptr);
+      end = ptr;
+      while(*end && ('>' != *end))
+        end++;
+      if((length = end - ptr) > MAX_TAG_LEN) {
+        error = GPE_NO_BUFFER_SPACE;
         break;
       }
+      memcpy(patt, ptr, length);
+      patt[length] = '\0';
 
-      if(!end[1] != '>') {
-        /* There might be attributes here. Check for those we know of and care
-           about. */
-        if(strstr(&end[1], "base64=")) {
-          /* rough and dirty, but "mostly" functional */
-          /* Treat all data as base64 encoded */
-          base64 = 1;
+      if(STATE_OUTSIDE == state) {
+        /* outermost element (<testcase>) */
+        strcpy(couter, ptag);
+        state = STATE_OUTER;
+        continue;
+      }
+      else if(STATE_OUTER == state) {
+        /* start of a main section */
+        strcpy(cmain, ptag);
+        state = STATE_INMAIN;
+        continue;
+      }
+      else if(STATE_INMAIN == state) {
+        /* start of a sub section */
+        strcpy(csub, ptag);
+        state = STATE_INSUB;
+        if(!strcmp(cmain, main) && !strcmp(csub, sub)) {
+          /* start of wanted part */
+          in_wanted_part = 1;
+          if(strstr(patt, "base64="))
+              /* bit rough test, but "mostly" functional, */
+              /* treat wanted part data as base64 encoded */
+              base64 = 1;
         }
+        continue;
       }
-    }
-    if(display) {
-      string = appendstring(string, buffer, &stringlen, &stralloc, base64);
-      show(("* %s\n", buffer));
-    }
 
-    if((STATE_INSUB == state) &&
-       !strcmp(cmain, main) &&
-       !strcmp(csub, sub)) {
-      show(("* (%d bytes) %s\n", stringlen, buffer));
-      display = 1; /* start displaying */
     }
-    else if ((*cmain == '?') || (*cmain == '!') || (*csub == '!')) {
-        /* Ignore comments, DOCTYPEs and XML declarations */
-        show(("%d ignoring (%s/%s)\n", state, cmain, csub));
-        state--;
+
+    if(in_wanted_part) {
+      show(("=> %s", buffer));
+      error = appenddata(outbuf, outlen, &outalloc, buffer, base64);
+      if(error)
+        break;
     }
+
+  } /* while */
+
+  if(buffer)
+    free(buffer);
+
+  if(error != GPE_OK) {
+    if(error == GPE_END_OF_FILE)
+      error = GPE_OK;
     else {
-      show(("%d (%s/%s): %s\n", state, cmain, csub, buffer));
-      display = 0; /* no display */
+      if(*outbuf)
+        free(*outbuf);
+      *outbuf = NULL;
+      *outlen = 0;
     }
   }
 
-  *size = stringlen;
-  return string;
+  return error;
 }
 
index a13badb9f5c665597026023dd438cc4a158ec11f..276d41de7665d1974c41fd8402225ab5123b562f 100644 (file)
@@ -1,3 +1,5 @@
+#ifndef HEADER_SERVER_GETPART_H
+#define HEADER_SERVER_GETPART_H
 /***************************************************************************
  *                                  _   _ ____  _
  *  Project                     ___| | | |  _ \| |
@@ -5,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
  *
  * $Id$
  ***************************************************************************/
-const char *
-spitout(FILE *stream,
-        const char *main,
-        const char *sub,
-        size_t *size);
+
+#define GPE_NO_BUFFER_SPACE -2
+#define GPE_OUT_OF_MEMORY   -1
+#define GPE_OK               0
+#define GPE_END_OF_FILE      1
+
+int getpart(char **outbuf, size_t *outlen,
+            const char *main, const char *sub, FILE *stream);
+
+#endif /* HEADER_SERVER_GETPART_H */
index 5bc88a27ff5f6e5ddbe360935b14435221af1355..c2910e07a626753f49f57bf675493d3ab0477cf4 100644 (file)
@@ -423,9 +423,14 @@ static int ProcessRequest(struct httprequest *req)
         char *rtp_scratch = NULL;
 
         /* get the custom server control "commands" */
-        cmd = (char *)spitout(stream, "reply", "servercmd", &cmdsize);
-        ptr = cmd;
+        error = getpart(&cmd, &cmdsize, "reply", "servercmd", stream);
         fclose(stream);
+        if(error) {
+          logmsg("getpart() failed with error: %d", error);
+          req->open = FALSE; /* closes connection */
+          return 1; /* done */
+        }
+        ptr = cmd;
 
         if(cmdsize) {
           logmsg("Found a reply-servercmd section!");
@@ -505,6 +510,8 @@ static int ProcessRequest(struct httprequest *req)
           } while(ptr && *ptr);
           logmsg("Done parsing server commands");
         }
+        if(cmd)
+          free(cmd);
       }
     }
     else {
@@ -950,13 +957,20 @@ static int send_doc(curl_socket_t sock, struct httprequest *req)
       return 0;
     }
     else {
-      buffer = spitout(stream, "reply", partbuf, &count);
-      ptr = (char *)buffer;
+      error = getpart(&buffer, &count, "reply", partbuf, stream);
       fclose(stream);
+      if(error) {
+        logmsg("getpart() failed with error: %d", error);
+        return 0;
+      }
+      ptr = (char *)buffer;
     }
 
-    if(got_exit_signal)
+    if(got_exit_signal) {
+      if(ptr)
+        free(ptr);
       return -1;
+    }
 
     /* re-open the same file again */
     stream=fopen(filename, "rb");
@@ -965,17 +979,30 @@ static int send_doc(curl_socket_t sock, struct httprequest *req)
       logmsg("fopen() failed with error: %d %s", error, strerror(error));
       logmsg("Error opening file: %s", filename);
       logmsg("Couldn't open test file");
+      if(ptr)
+        free(ptr);
       return 0;
     }
     else {
       /* get the custom server control "commands" */
-      cmd = (char *)spitout(stream, "reply", "postcmd", &cmdsize);
+      error = getpart(&cmd, &cmdsize, "reply", "postcmd", stream);
       fclose(stream);
+      if(error) {
+        logmsg("getpart() failed with error: %d", error);
+        if(ptr)
+          free(ptr);
+        return 0;
+      }
     }
   }
 
-  if(got_exit_signal)
+  if(got_exit_signal) {
+    if(ptr)
+      free(ptr);
+    if(cmd)
+      free(cmd);
     return -1;
+  }
 
   /* If the word 'swsclose' is present anywhere in the reply chunk, the
      connection will be closed after the data has been sent to the requesting
@@ -997,6 +1024,10 @@ static int send_doc(curl_socket_t sock, struct httprequest *req)
     logmsg("fopen() failed with error: %d %s", error, strerror(error));
     logmsg("Error opening file: %s", RESPONSE_DUMP);
     logmsg("couldn't create logfile: " RESPONSE_DUMP);
+    if(ptr)
+      free(ptr);
+    if(cmd)
+      free(cmd);
     return -1;
   }
 
@@ -1045,7 +1076,6 @@ static int send_doc(curl_socket_t sock, struct httprequest *req)
     req->rtp_buffersize = 0;
   }
 
-
   do {
     res = fclose(dump);
   } while(res && ((error = ERRNO) == EINTR));
@@ -1053,8 +1083,13 @@ static int send_doc(curl_socket_t sock, struct httprequest *req)
     logmsg("Error closing file %s error: %d %s",
            RESPONSE_DUMP, error, strerror(error));
 
-  if(got_exit_signal)
+  if(got_exit_signal) {
+    if(ptr)
+      free(ptr);
+    if(cmd)
+      free(cmd);
     return -1;
+  }
 
   if(sendfailure) {
     logmsg("Sending response failed. Only (%zu bytes) of (%zu bytes) were sent",
index 16485f2f9cd82412f25ce0211ddc885f3d5b0db2..e1dfe45d84bbcf977443e1726182e3a2a12caa70 100644 (file)
@@ -389,8 +389,13 @@ static int ProcessRequest(struct httprequest *req)
         int num=0;
 
         /* get the custom server control "commands" */
-        cmd = (char *)spitout(stream, "reply", "servercmd", &cmdsize);
+        error = getpart(&cmd, &cmdsize, "reply", "servercmd", stream);
         fclose(stream);
+        if(error) {
+          logmsg("getpart() failed with error: %d", error);
+          req->open = FALSE; /* closes connection */
+          return 1; /* done */
+        }
 
         if(cmdsize) {
           logmsg("Found a reply-servercmd section!");
@@ -423,8 +428,9 @@ static int ProcessRequest(struct httprequest *req)
           else {
             logmsg("funny instruction found: %s", cmd);
           }
-          free(cmd);
         }
+        if(cmd)
+          free(cmd);
       }
     }
     else {
@@ -863,13 +869,20 @@ static int send_doc(curl_socket_t sock, struct httprequest *req)
       return 0;
     }
     else {
-      buffer = spitout(stream, "reply", partbuf, &count);
-      ptr = (char *)buffer;
+      error = getpart(&ptr, &count, "reply", partbuf, stream);
       fclose(stream);
+      if(error) {
+        logmsg("getpart() failed with error: %d", error);
+        return 0;
+      }
+      buffer = ptr;
     }
 
-    if(got_exit_signal)
+    if(got_exit_signal) {
+      if(ptr)
+        free(ptr);
       return -1;
+    }
 
     /* re-open the same file again */
     stream=fopen(filename, "rb");
@@ -878,17 +891,30 @@ static int send_doc(curl_socket_t sock, struct httprequest *req)
       logmsg("fopen() failed with error: %d %s", error, strerror(error));
       logmsg("Error opening file: %s", filename);
       logmsg("Couldn't open test file");
+      if(ptr)
+        free(ptr);
       return 0;
     }
     else {
       /* get the custom server control "commands" */
-      cmd = (char *)spitout(stream, "reply", "postcmd", &cmdsize);
+      error = getpart(&cmd, &cmdsize, "reply", "postcmd", stream);
       fclose(stream);
+      if(error) {
+        logmsg("getpart() failed with error: %d", error);
+        if(ptr)
+          free(ptr);
+        return 0;
+      }
     }
   }
 
-  if(got_exit_signal)
+  if(got_exit_signal) {
+    if(ptr)
+      free(ptr);
+    if(cmd)
+      free(cmd);
     return -1;
+  }
 
   /* If the word 'swsclose' is present anywhere in the reply chunk, the
      connection will be closed after the data has been sent to the requesting
@@ -910,6 +936,10 @@ static int send_doc(curl_socket_t sock, struct httprequest *req)
     logmsg("fopen() failed with error: %d %s", error, strerror(error));
     logmsg("Error opening file: %s", RESPONSE_DUMP);
     logmsg("couldn't create logfile: " RESPONSE_DUMP);
+    if(ptr)
+      free(ptr);
+    if(cmd)
+      free(cmd);
     return -1;
   }
 
@@ -945,8 +975,13 @@ static int send_doc(curl_socket_t sock, struct httprequest *req)
     logmsg("Error closing file %s error: %d %s",
            RESPONSE_DUMP, error, strerror(error));
 
-  if(got_exit_signal)
+  if(got_exit_signal) {
+    if(ptr)
+      free(ptr);
+    if(cmd)
+      free(cmd);
     return -1;
+  }
 
   if(sendfailure) {
     logmsg("Sending response failed. Only (%zu bytes) of (%zu bytes) were sent",
index d2be529dec7f5d5ad56d7b80c51eee7a6b493b78..a78799ca7ad5ad2ba66632fd3b309c0e8b46c9e5 100644 (file)
 
 int main(int argc, char **argv)
 {
+  int rc;
+  char  *part;
+  size_t partlen, i;
+
   if(argc< 3) {
     printf("./testpart main sub\n");
   }
   else {
-    size_t size;
-    unsigned int i;
-    const char *buffer = spitout(stdin, argv[1], argv[2], &size);
-    for(i=0; i< size; i++)
-      printf("%c", buffer[i]);
+    rc = getpart(&part, &partlen, argv[1], argv[2], stdin);
+    if(rc)
+      return(rc);
+    for(i = 0; i < partlen; i++)
+      printf("%c", part[i]);
+    free(part);
   }
   return 0;
 }
index 91e51cf42d40d8008830a36291dd7c907dbd1c4f..152324904b263a6320d0bd049aa2837cb2f81cc3 100644 (file)
@@ -1051,8 +1051,12 @@ static int validate_access(struct testcase *test,
       }
       else {
         size_t count;
-        test->buffer = (char *)spitout(stream, "reply", partbuf, &count);
+        error = getpart(&test->buffer, &count, "reply", partbuf, stream);
         fclose(stream);
+        if(error) {
+          logmsg("getpart() failed with error: %d", error);
+          return EACCESS;
+        }
         if(test->buffer) {
           test->rptr = test->buffer; /* set read pointer */
           test->bufsize = count;    /* set total count */