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.
/* * 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); }
/* * 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
#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 ()); }
Attachment:
tt.exe
Description: Binary data