Hello, there
I've run into situation which looks like bug to me -
attached is the source and the executable, wich triggers
the buggy behaviour. The executable is compiled with
mingw32 cross-copiler based on linux and targeted to Win32.
The cross-compiler can be found at:
http://members.telering.at/jessich/mingw/mingwcross/mingw_cross.html
This is the output of the program being run with Wine on RedHat Linux
7.1:
Setting the URL base path to: file://C/Cygwin/bin/
Parsing relative URL of type file:
Authority: C
Path: Cygwin/bin//pinco/panco
fixme:msvcrt:MSVCRT_signal (11 (nil)):stub
err:seh:EXC_DefaultHandling Unhandled exception code c000013a flags 0
addr 0xffffffff
And here is the correct ouput as produced by native linux executable on
the
same system:
Setting the URL base path to: file://C/Cygwin/bin/
Parsing relative URL of type file:
Authority: C
Path: Cygwin/bin//pinco/panco
Parsing relative URL of type cygfile:
Authority: C
Path: Cygwin/bin//bin/passwd
Parsing absolute URL of type file:
Authority: (null)
Path: usr/bin/passwd
Parsing absolute URL of type cygfile:
Authority: (null)
Path: usr/bin/passwd
With Win the trouble starts as we come to line 229 of URLParser.cc -
trying to do malloc. Notice that the first time when it comes to this
line everything is ok - but the second time we have a trouble.
Pleass CC any replies to me since I dont follow the list.
-------------- next part --------------
/*
* Copyright (c) 2001, Pavel Tsekov.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* A copy of the GNU General Public License can be found at
* http://www.gnu.org/
*
* Written by Pavel Tsekov <ptsekov@fixity.net>
*
*/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "URLParser.h"
URLParser URLParser::baseURL;
URLParser::URLParser () : internalURL (0), internalURLlen (0), host (0),
port (0), user (0), pass (0), path (0)
{
}
URLParser::URLParser (const char *url) : internalURL (0), internalURLlen (0),
host (0), port (0), user (0), pass (0), path (0)
{
*this = url;
}
URLParser::~URLParser ()
{
*this = 0;
}
void
URLParser::parse ()
{
if (internalURL == NULL || *internalURL == '\0')
return;
char *start, *end, *authority = NULL, *schema = NULL;
start = internalURL;
end = internalURL + strlen (internalURL);
// Trim the leading and trailing whitespaces
for (;start < end && *start == ' '; start++);
for (;(end - 1) >= start && *(end - 1) == ' '; end--);
*end = '\0';
// Split the internal URL buffer in its building parts - authority (if any)
// and path. This are to be parsed later.
for (char *c = start; c < end && path == NULL; c++)
{
if (*c == '/')
{
char *p;
for (p = c; p < end && *p == '/'; p++);
switch (p - c)
{
case 2: // Network path separator (p points to the start of
// authority)
{
if (authority == NULL && *(c - 1) == ':')
{
*(c - 1) = '\0';
authority = p;
}
/* FIXME: There should be no // sequence in the URL, except
exactly after the schema separator ':', but
hey...
We need this for relative URLs to work, atm. As
soon as we are sure that we handle relative URLs,
without leaving any sequential path separators
('/')
in them we can uncomment this code.
else // Erronous URL (maybe)
return;
*/
break;
}
case 1: // Path separator (p points to the start of the path)
{
// FIXME: Doesn't look quite nice :)
if (authority != NULL || *(c - 1) == ':')
{
if (p < end)
path = p;
else
path = NULL;
*c = '\0';
if (authority == NULL && *(c - 1) == ':')
*(c - 1) = '\0';
}
break;
}
/* FIXME: Read the _BIG_ comment in 'case 2:' - it's
all there!
default:
return;
*/
}
c += p - c - 1;
}
else if (*c == ':')
{
if (schema == NULL)
schema = c;
}
}
parse_authority (authority);
// This is a special case, thus it may not look nor feel very well...
// But hey... :)
if (authority == 0 && path == 0 && schema != 0 &&
*(schema + 1) != '\0')
{
char *backupURL = internalURL;
internalURL = 0;
*this = baseURL;
internalURL = (char *) realloc (internalURL,
internalURLlen + strlen (schema + 1));
pfixup (baseURL);
*schema = '/';
strcat ((char *) path, schema);
free (backupURL);
}
}
void
URLParser::parse_authority (char *start)
{
if (start == NULL || *start == '\0')
return;
char *end = (char *) path, *c;
if (end == NULL)
end = start + strlen (start);
// Check if there is an user info embedded into the authority
// field.
for (c = start; c < end && *c != '@'; c++);
char * tport = 0;
if (*c == '@')
{
*c = '\0';
parse_colon_sep_string (start, c, (char **) &user, (char **)
&pass);
parse_colon_sep_string (c + 1, end, (char **) &host, (char **)
&tport);
}
else
{
parse_colon_sep_string (start, end, (char **) &host, (char **)
&tport);
}
if (tport)
port = abs (atoi (tport));
}
void
URLParser::parse_colon_sep_string (char *start, char *end, char **first, char
**second)
{
// FIXME: If end is NULL search upto the zero terminator.
if (start == NULL || *start == '\0' || end == NULL)
return;
if (first == NULL || second == NULL)
return;
char *c = start;
for (; c < end && *c != ':'; c++);
if ((c - start) != 0)
*first = start;
if (*c == ':')
{
*c = '\0';
if ((end - c) > 1)
*second = c + 1;
}
}
URLParser::Schema
URLParser::GetSchema (void) const
{
if (!strcasecmp ("file", internalURL))
return URLParser::file;
if (!strcasecmp ("cygfile", internalURL))
return URLParser::cygfile;
if (!strcasecmp ("ftp", internalURL))
return URLParser::ftp;
if (!strcasecmp ("http", internalURL))
return URLParser::http;
return URLParser::unknown;
}
void
URLParser::operator = (const char *src)
{
if (internalURL != 0)
{
if (user != NULL)
memset ((void *) user, '\0', strlen (user));
if (pass != NULL)
memset ((void *) pass, '\0', strlen (pass));
free (internalURL);
internalURL = 0;
internalURLlen = 0;
host = user = pass = path = 0;
port = 0;
}
if (src != 0 && *src != '\0')
{
internalURLlen = strlen (src) + 1;
internalURL = strdup (src);
parse ();
}
}
void
URLParser::operator = (const URLParser& src)
{
*this = 0;
if (src.GetSchema () != URLParser::unknown)
{
internalURL = (char *) malloc (src.internalURLlen);
memcpy (internalURL, src.internalURL, src.internalURLlen);
internalURLlen = src.internalURLlen;
port = src.port;
pfixup (src);
}
}
void
URLParser::pfixup (const URLParser& src)
{
char **p;
if (src.host != 0)
{
p = (char **) &host;
*p = internalURL + (src.host - src.internalURL);
}
if (src.user != 0)
{
p = (char **) &user;
*p = internalURL + (src.user - src.internalURL);
}
if (src.pass != 0)
{
p = (char **) &pass;
*p = internalURL + (src.pass - src.internalURL);
}
if (src.path != 0)
{
p = (char **) &path;
*p = internalURL + (src.path - src.internalURL);
}
}
// Converts absolute dos path to URL path.
char *
URLParser::dos_path_to_url_path (const char *path)
{
if (path == 0 || *path == '\0')
return 0;
int len = strlen (path);
if (len < 3 || !isalpha (path[0]) || path[1] != ':' || path[2] !=
'\\')
return 0;
// The code below could be replaced by a call to concat ()
char *rv = (char *) malloc (len + 8);
strcpy (rv, "file://");
rv[7] = *path;
int i = 2;
char *bp = rv + 8;
for (; path[i] != '\0'; i++, bp++)
{
if (path[i] == '\\' || path[i] == '/')
{
char *p;
for (p = (char *) &path[i]; *p != '\0' && (*p ==
'\\' || *p == '/'); p++);
*bp = '/';
i += p - &path[i] - 1;
}
else
*bp = path[i];
}
*bp = '\0';
return rv;
}
void
URLParser::SetBaseURL (const char *base)
{
char *url_path = dos_path_to_url_path (base);
baseURL = url_path;
if (url_path)
free (url_path);
}
-------------- next part --------------
/*
* Copyright (c) 2001, Pavel Tsekov.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* A copy of the GNU General Public License can be found at
* http://www.gnu.org/
*
* Written by Pavel Tsekov <ptsekov@fixity.net>
*
*/
#ifndef _URL_PARSER_H_
#define _URL_PARSER_H_
class URLParser
{
static URLParser baseURL; // Support for relative URLs
char *internalURL;
size_t internalURLlen;
const char *host;
unsigned int port;
const char *user;
const char *pass;
const char *path;
// Split the URL into smaller parts for easier parsing.
void parse ();
// Parse the authority part of the URL (user:info@host:port).
void parse_authority (char *start);
// Utility for parsing the user/pass and host/port pairs.
void parse_colon_sep_string (char *start, char *end, char **first, char
**second);
// Utility to fixup the pointers which point inside the internalURL
void pfixup (const URLParser& src);
public:
enum Schema { unknown = 0, file, cygfile, ftp, http };
static void SetBaseURL (const char *base);
static char *URLParser::dos_path_to_url_path (const char *path);
URLParser ();
URLParser (const char *url);
~URLParser ();
void operator = (const char *);
void operator = (const URLParser& src);
const char *GetHost (void) const { return host; }
unsigned int GetPort (void) const { return port; }
const char *GetUser (void) const { return user; }
const char *GetPass (void) const { return pass; }
const char *GetPath (void) const { return path; }
Schema GetSchema (void) const;
};
#endif
-------------- next part --------------
#include <stdio.h>
#include "URLParser.h"
int main (int argc, char *argv)
{
printf("Setting the URL base path to: %s\n",
URLParser::dos_path_to_url_path ("C:\\Cygwin\\////\\\\bin\\\\"));
URLParser::SetBaseURL ("C:\\Cygwin\\////\\\\bin\\\\");
URLParser rel_url_file ("file:pinco/panco");
printf ("Parsing relative URL of type file:\n");
printf ("Authority: %s\n", rel_url_file.GetHost ());
printf ("Path: %s\n", rel_url_file.GetPath ());
URLParser rel_url_cygfile ("cygfile:bin/passwd");
printf ("Parsing relative URL of type cygfile:\n");
printf ("Authority: %s\n", rel_url_cygfile.GetHost ());
printf ("Path: %s\n", rel_url_cygfile.GetPath ());
URLParser abs_url_file ("file:/usr/bin/passwd");
printf ("Parsing absolute URL of type file:\n");
printf ("Authority: %s\n", abs_url_file.GetHost ());
printf ("Path: %s\n", abs_url_file.GetPath ());
URLParser abs_url_cygfile ("cygfile:/usr/bin/passwd");
printf ("Parsing absolute URL of type cygfile:\n");
printf ("Authority: %s\n", abs_url_cygfile.GetHost ());
printf ("Path: %s\n", abs_url_cygfile.GetPath ());
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: tt.exe
Type: application/octet-stream
Size: 665867 bytes
Desc: not available
Url :
http://www.winehq.org/pipermail/wine-users/attachments/20011207/40d8f5fa/tt.obj