tools/trace-malloc/formdata.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  *
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 /*
     8 **  formdata.c
     9 **
    10 **  Play utility to parse up form get data into name value pairs.
    11 */
    13 #include "formdata.h"
    15 #include <stdlib.h>
    16 #include <string.h>
    17 #include <ctype.h>
    20 static void unhexcape(char* inPlace)
    21 /*
    22 **  Real low tech unhexcaper....
    23 **
    24 **  inPlace     string to decode, in place as it were.
    25 */
    26 {
    27     if(NULL != inPlace)
    28     {
    29         int index1 = 0;
    30         int index2 = 0;
    31         int theLen = strlen(inPlace);
    33         for(; index1 <= theLen; index1++)
    34         {
    35             if('%' == inPlace[index1] && '\0' != inPlace[index1 + 1] && '\0' != inPlace[index1 + 2])
    36             {
    37                 int unhex = 0;
    39                 if('9' >= inPlace[index1 + 1])
    40                 {
    41                     unhex |= ((inPlace[index1 + 1] - '0') << 4);
    42                 }
    43                 else
    44                 {
    45                     unhex |= ((toupper(inPlace[index1 + 1]) - 'A' + 10) << 4);
    46                 }
    48                 if('9' >= inPlace[index1 + 2])
    49                 {
    50                     unhex |= (inPlace[index1 + 2] - '0');
    51                 }
    52                 else
    53                 {
    54                     unhex |= (toupper(inPlace[index1 + 2]) - 'A' + 10);
    55                 }
    57                 index1 += 2;
    58                 inPlace[index1] = unhex;
    59             }
    61             inPlace[index2++] = inPlace[index1];
    62         }
    63     }
    64 }
    67 FormData* FormData_Create(const char* inFormData)
    68 {
    69     FormData* retval = NULL;
    71     if(NULL != inFormData)
    72     {
    73         FormData* container = NULL;
    75         /*
    76         **  Allocate form data container.
    77         */
    78         container = (FormData*)calloc(1, sizeof(FormData));
    79         if(NULL != container)
    80         {
    81             /*
    82             **  Dup the incoming form data.
    83             */
    84             container->mStorage = strdup(inFormData);
    85             if(NULL != container->mStorage)
    86             {
    87                 char* traverse = NULL;
    88                 unsigned nvpairs = 1;
    89                 unsigned storeLen = 0;
    91                 /*
    92                 **  Count the number of pairs we are going to have.
    93                 **  We do this by counting '&' + 1.
    94                 */
    95                 for(traverse = container->mStorage; '\0' != *traverse; traverse++)
    96                 {
    97                     if('&' == *traverse)
    98                     {
    99                         nvpairs++;
   100                     }
   101                 }
   102                 storeLen = (unsigned)(traverse - container->mStorage);
   104                 /*
   105                 **  Allocate space for our names and values.
   106                 */
   107                 container->mNArray = (char**)calloc(nvpairs * 2, sizeof(char*));
   108                 if(NULL != container->mNArray)
   109                 {
   110                     char* amp = NULL;
   111                     char* equ = NULL;
   113                     container->mVArray = &container->mNArray[nvpairs];
   115                     /*
   116                     **  Go back over the storage.
   117                     **  Fill in the names and values as we go.
   118                     **  Terminate on dividing '=' and '&' characters.
   119                     **  Increase the count of items as we go.
   120                     */
   121                     for(traverse = container->mStorage; NULL != traverse; container->mNVCount++)
   122                     {
   123                         container->mNArray[container->mNVCount] = traverse;
   125                         amp = strchr(traverse, '&');
   126                         equ = strchr(traverse, '=');
   127                         traverse = NULL;
   129                         if(NULL != equ && (NULL == amp || equ < amp))
   130                         {
   131                             *equ++ = '\0';
   133                             container->mVArray[container->mNVCount] = equ;
   134                         }
   135                         else
   136                         {
   137                             container->mVArray[container->mNVCount] = (container->mStorage + storeLen);
   138                         }
   140                         if(NULL != amp)
   141                         {
   142                             *amp++ = '\0';
   144                             traverse = amp;
   145                         }
   147                         unhexcape(container->mNArray[container->mNVCount]);
   148                         unhexcape(container->mVArray[container->mNVCount]);
   149                     }
   151                     retval = container;
   152                 }
   153             }
   154         }
   156         /*
   157         **  If we failed, cleanup.
   158         */
   159         if(NULL == retval)
   160         {
   161             FormData_Destroy(container);
   162         }
   163     }
   165     return retval;
   166 }
   169 void FormData_Destroy(FormData* inDestroy)
   170 {
   171     if(NULL != inDestroy)
   172     {
   173         unsigned traverse = 0;
   175         for(traverse = 0; traverse < inDestroy->mNVCount; traverse++)
   176         {
   177             if(NULL != inDestroy->mNArray)
   178             {
   179                 inDestroy->mNArray[traverse] = NULL;
   180             }
   181             if(NULL != inDestroy->mVArray)
   182             {
   183                 inDestroy->mVArray[traverse] = NULL;
   184             }
   185         }
   186         inDestroy->mNVCount = 0;
   188         if(NULL != inDestroy->mStorage)
   189         {
   190             free(inDestroy->mStorage);
   191             inDestroy->mStorage = NULL;
   192         }
   194         if(NULL != inDestroy->mNArray)
   195         {
   196             free(inDestroy->mNArray);
   197             inDestroy->mNArray = NULL;
   198             inDestroy->mVArray = NULL;
   199         }
   201         free(inDestroy);
   202         inDestroy = NULL;
   203     }
   204 }

mercurial