* Memory Overright problem. (sorry if this is a repeat )
@ 2004-06-02 4:07 John T. Williams
2004-06-02 6:30 ` Jan-Benedict Glaw
0 siblings, 1 reply; 2+ messages in thread
From: John T. Williams @ 2004-06-02 4:07 UTC (permalink / raw)
To: linux-c-programming
[-- Attachment #1: Type: text/plain, Size: 4086 bytes --]
While trying to write a function to parse a http url, I ran accross a
strange problem, which is that when I malloc some memory, suddenly some
memory already allocated changes its contents. I can't figure out where
the problem is so I was hoping someone might point me at it.
I'm including the code here, and as an attachment
The problem line is pointed out with at
***************here********************
***************end here ***************
and its affecting the memory pointed at by http_addr->abspath
#####################################################
#include <string.h>
#ifndef NULL
#define NULL (void*) 0
#endif
typedef struct _http {
char* query; // query string
int port; // port number if other then 80
char* abspath;// absolute path of file on serve
char* host; // domain ex: www.something.com
} http_url;
int parsehttp( http_url*, char* );
int initurl(http_url*);
int cleanurl(http_url*);
int
initurl( http_url* url)
{
if( !url ) return -1;
url->host = NULL;
url->query = NULL;
url->abspath = NULL;
url->port = 80;
}
int cleanurl(http_url* url) {
if( !url ) return -1;
if(url->host) {
free(url->host);
url->host = NULL;
}
if(url->query) {
free(url->query);
url->query = NULL;
}
if(url->abspath) {
free(url->abspath);
url->abspath = NULL;
}
url->port = 80;
}
int
parsehttp( http_url* http_addr, char* urlstr )
{
char* host_ptr;
char* abspath_ptr;
char* port_ptr;
char* query_ptr;
int host_len,
abspath_len,
port_len,
query_len,
total_len;
//check for null parameters:
if( !http_addr || !urlstr ) {
perror("error called parsehttp with NULL\n");
return -1;
}
//check for http:// head
if( strncmp(urlstr, "http://", 7) ) {
perror("url not propperly formatted: %s\n", urlstr);
return -2;
}
// find the starting point for each string
// if there indicating character is missing *ptr == NULL;
port_ptr = abspath_ptr = query_ptr = host_ptr = &urlstr[7];
while(port_ptr && *port_ptr != ':') port_ptr++; //search for ':'
indicating
// a port in this url
while(abspath_ptr && *abspath_ptr != '/') abspath_ptr++;
// search for a '/' indicating
// a absolute path listed
while(query_ptr && *query_ptr != '?') query_ptr++;
// search for a '?' indicating
// a query is listed
// Parse out the query if any and record its length
if(*query_ptr) {
query_len = strlen(query_ptr);
http_addr->query = (char*) malloc( sizeof( query_len + 128 ) );
strncpy(http_addr->query, &query_ptr[1], query_len - 1 );
http_addr->query[query_len - 1] = '\0';
} else query_len = 0;
// Parse out the abspath if any and record its length
if(*abspath_ptr) {
abspath_len = strlen(abspath_ptr) - query_len;
http_addr->abspath = (char*) malloc( sizeof( abspath_len + 128 ) );
strncpy(http_addr->abspath, abspath_ptr, abspath_len);
http_addr->abspath[abspath_len] = '\0';
} else abspath_len = 0;
// Parse out the port number if any
if(*port_ptr) { // if a port was found
port_len = strlen( port_ptr) - abspath_len - query_len;
port_ptr++; //move past ':'
http_addr->port = atoi(port_ptr);
} else port_len = 0;
printf("port length: %i\n", port_len);
// Parse out the host str if any
if(*host_ptr) {
host_len = strlen(host_ptr) - port_len - abspath_len - query_len;
/***************here********************/
http_addr->host = (char*) malloc( sizeof( host_len + 128 ) );
/***************end here ***************/
strncpy(http_addr->host, host_ptr, host_len );
http_addr->host[host_len] = '\0';
}
return 0;
}
int
main(int argC, char** argV, char** envp)
{
http_url url;
initurl( &url );
parsehttp( &url,
"http://www.vt.edu:23/users/jowillia/index.html?t=12");
printf("http://");
// if(url.host) printf("%s", url.host);
if(url.port != 80) printf(":%i", url.port);
if(url.abspath) printf("%s", url.abspath);
if(url.query) printf("?%s", url.query);
printf("\n");
cleanurl( &url );
return 0;
}
[-- Attachment #2: connect.zip --]
[-- Type: application/zip, Size: 2158 bytes --]
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: Memory Overright problem. (sorry if this is a repeat )
2004-06-02 4:07 Memory Overright problem. (sorry if this is a repeat ) John T. Williams
@ 2004-06-02 6:30 ` Jan-Benedict Glaw
0 siblings, 0 replies; 2+ messages in thread
From: Jan-Benedict Glaw @ 2004-06-02 6:30 UTC (permalink / raw)
To: linux-c-programming
[-- Attachment #1: Type: text/plain, Size: 5593 bytes --]
On Wed, 2004-06-02 00:07:24 -0400, John T. Williams <jowillia@vt.edu>
wrote in message <1086149244.22758.17.camel@localhost>:
> #####################################################
> #include <string.h>
>
> #ifndef NULL
> #define NULL (void*) 0
> #endif
There's a header file for NULL:)
> typedef struct _http {
> char* query; // query string
> int port; // port number if other then 80
> char* abspath;// absolute path of file on serve
> char* host; // domain ex: www.something.com
>
> } http_url;
>
> int parsehttp( http_url*, char* );
> int initurl(http_url*);
> int cleanurl(http_url*);
>
> int
> initurl( http_url* url)
> {
> if( !url ) return -1;
> url->host = NULL;
> url->query = NULL;
> url->abspath = NULL;
> url->port = 80;
> }
>
> int cleanurl(http_url* url) {
> if( !url ) return -1;
> if(url->host) {
> free(url->host);
> url->host = NULL;
> }
> if(url->query) {
> free(url->query);
> url->query = NULL;
> }
> if(url->abspath) {
> free(url->abspath);
> url->abspath = NULL;
> }
> url->port = 80;
> }
>
> int
> parsehttp( http_url* http_addr, char* urlstr )
> {
> char* host_ptr;
> char* abspath_ptr;
> char* port_ptr;
> char* query_ptr;
>
> int host_len,
> abspath_len,
> port_len,
> query_len,
> total_len;
>
>
> //check for null parameters:
> if( !http_addr || !urlstr ) {
> perror("error called parsehttp with NULL\n");
perror does only make sense if you call it after a system call, that
failed. In this case, I'd use fprintf (stderr, "message"); .
> return -1;
> }
>
> //check for http:// head
> if( strncmp(urlstr, "http://", 7) ) {
> perror("url not propperly formatted: %s\n", urlstr);
> return -2;
> }
>
> // find the starting point for each string
> // if there indicating character is missing *ptr == NULL;
> port_ptr = abspath_ptr = query_ptr = host_ptr = &urlstr[7];
> while(port_ptr && *port_ptr != ':') port_ptr++; //search for ':'
So if there's no ':' (like in "http://somehost.com/index.html", you'll
see your first crash while overstepping the final '\0'. You probably
intended to do
while (*port_ptr && *port_ptr != ':')
port_ptr++;
This'll pay attention to the final zero.
> indicating
> // a port in this url
> while(abspath_ptr && *abspath_ptr != '/') abspath_ptr++;
> // search for a '/' indicating
> // a absolute path listed
> while(query_ptr && *query_ptr != '?') query_ptr++;
> // search for a '?' indicating
> // a query is listed
Same here.
> // Parse out the query if any and record its length
> if(*query_ptr) {
> query_len = strlen(query_ptr);
It's still pointing to the leading '?' of the supplied arguments, right?
> http_addr->query = (char*) malloc( sizeof( query_len + 128 ) );
Here's a servere one! It will probably allocate 4 bytes - query_len is
an integer! This should have been
http_addr->query = (char *) malloc (query_len + 128);
> strncpy(http_addr->query, &query_ptr[1], query_len - 1 );
...and a check for malloc's return value (if it failed, it might have
returned NULL) is missing, too. However, you're properly dealing with
the initial '?'.
> http_addr->query[query_len - 1] = '\0';
> } else query_len = 0;
>
> // Parse out the abspath if any and record its length
> if(*abspath_ptr) {
> abspath_len = strlen(abspath_ptr) - query_len;
> http_addr->abspath = (char*) malloc( sizeof( abspath_len + 128 ) );
> strncpy(http_addr->abspath, abspath_ptr, abspath_len);
Same here - you allocated 4 bytes, forgot to check and write the full
path (which is probably longer than 3 bytes + '\0') to it.
> http_addr->abspath[abspath_len] = '\0';
> } else abspath_len = 0;
>
> // Parse out the port number if any
> if(*port_ptr) { // if a port was found
> port_len = strlen( port_ptr) - abspath_len - query_len;
> port_ptr++; //move past ':'
> http_addr->port = atoi(port_ptr);
> } else port_len = 0;
> printf("port length: %i\n", port_len);
>
> // Parse out the host str if any
> if(*host_ptr) {
> host_len = strlen(host_ptr) - port_len - abspath_len - query_len;
This looks fragile. Don't ask me why, but I'd probably written that
using strcspn().
> /***************here********************/
> http_addr->host = (char*) malloc( sizeof( host_len + 128 ) );
> /***************end here ***************/
You're only allocating 4 bytes and forget to check:)
> strncpy(http_addr->host, host_ptr, host_len );
> http_addr->host[host_len] = '\0';
> }
>
>
> return 0;
> }
>
>
> int
> main(int argC, char** argV, char** envp)
> {
> http_url url;
>
> initurl( &url );
> parsehttp( &url,
> "http://www.vt.edu:23/users/jowillia/index.html?t=12");
>
>
> printf("http://");
> // if(url.host) printf("%s", url.host);
> if(url.port != 80) printf(":%i", url.port);
> if(url.abspath) printf("%s", url.abspath);
> if(url.query) printf("?%s", url.query);
> printf("\n");
>
> cleanurl( &url );
>
>
> return 0;
> }
>
>
--
Jan-Benedict Glaw jbglaw@lug-owl.de . +49-172-7608481
"Eine Freie Meinung in einem Freien Kopf | Gegen Zensur | Gegen Krieg
fuer einen Freien Staat voll Freier Bürger" | im Internet! | im Irak!
ret = do_actions((curr | FREE_SPEECH) & ~(NEW_COPYRIGHT_LAW | DRM | TCPA));
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2004-06-02 6:30 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-06-02 4:07 Memory Overright problem. (sorry if this is a repeat ) John T. Williams
2004-06-02 6:30 ` Jan-Benedict Glaw
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).