Welcome! Log In Create A New Profile

Advanced

sscanf problems, not the user the function

Posted by SteelSLasher 
sscanf problems, not the user the function
July 14, 2009 09:50PM
For some odd reason this gives an exception
sscanf (line, "Location: %s", read)

the variable line is retrieved from:
char *line = tcp_readln (s, 0xff, gettime(), HTTP_TIMEOUT);

which is called in a for loop until the end of the http response, the exception is only shown on the second loop when the "Location: [...]" is contained in the http response
Re: sscanf problems, not the user the function
July 14, 2009 10:57PM
Why are you using sscanf? Use either sprintf or str(n)cpy. You are using sscanf incorrectly, what you want instead is strcpy(read,line) or to be safer strncpy(read,line,size of read array)



Edited 1 time(s). Last edit at 07/17/2009 05:49AM by jsmaster.
Re: sscanf problems, not the user the function
July 16, 2009 09:59PM
btw, strcpy, strncpy and any other function does not work in the place i was going to but instead i transfer the second line to another variable which is later used to be processed.

my sscanf is completely fine
Re: sscanf problems, not the user the function
July 17, 2009 05:53AM
Quote
SteelSLasher
btw, strcpy, strncpy and any other function does not work in the place i was going to but instead i transfer the second line to another variable which is later used to be processed.

my sscanf is completely fine

Sorry, my fault. But your sscanf is still wrong (http://www.cplusplus.com/reference/clibrary/cstdio/sscanf/). Here's what you want:
sprintf(read,"Location: %s",line);



Edited 1 time(s). Last edit at 07/17/2009 05:54AM by jsmaster.
Re: sscanf problems, not the user the function
July 17, 2009 08:32AM
actually, you are wrong, sprintf is the opposite of sscanf and its sscanf use is perfectly fine: he's actually trying to read part of of string, not writing to it

about your problem, you might check that "read" is properly allocated (probably is but you never know) and the tcp_readln function (if this is called in a loop, the same variable "line" might be allocated each time you call this)
seeing the whole code would probaly help more
Re: sscanf problems, not the user the function
July 17, 2009 11:22AM
Here is the for loop in which i get stuck: btw i commented out the sscanf since it causes an exception but left it there for reference
	for (linecount=0; linecount < 32; linecount++) {
		Debugs("tcp_readIn");
		char *line = tcp_readln (s, 0xff, gettime(), HTTP_TIMEOUT);
//		debug_printf("tcp_readln returned %p (%s)\n", line, line?line:"(null)");
		if (!line) {
			http_status = 404;
			result = HTTPR_ERR_REQUEST;
			break;
		}

		if (strlen (line) < 1) {
			free (line);
			line = NULL;
			break;
		}
		Debugs("sscanf");
		sscanf (line, "HTTP/1.%*u %u", &http_status);
		sscanf (line, "Content-Length: %u", &content_length);
		Debugs("error");
		//sscanf (line, "Location: %s", read);
		if(linecount == 1)
		{
		redirect = line;  //set the second line of the response which contains the redirect location to redirect for processing later (workaround that fails since the sscanf fails later as well
		Debugs(redirect);
		}
		free (line);
		line = NULL;

	}

here is the entire function, its a bit large and may not be needed
int http_request (const char *url, const u32 max_size) {
	int linecount;
	Debugs("Split");	
	if (!http_split_url(&http_host, &http_path, url)) return false;

	http_port = 80;
	http_max_size = max_size;
	
	http_status = 404;
	content_length = 0;
	http_data = NULL;
	Debugs("tcp_connect");	
	int s = tcp_connect (http_host, http_port);
//	debug_printf("tcp_connect(%s, %hu) = %d\n", http_host, http_port, s);
	if (s < 0) {
		result = HTTPR_ERR_CONNECT;
		Debugs("s is less than 0???");	
		return false;
	}

	char *request = (char *) malloc (1024);
	char *r = request;
	r += sprintf (r, "GET %s HTTP/1.1\r\n", http_path);
	r += sprintf (r, "Host: %s\r\n", http_host);
	r += sprintf (r, "Cache-Control: no-cache\r\n\r\n");
	Debugs(r);
//	debug_printf("request = %s\n", request);
	Debugs("tcp_write");	
	bool b = tcp_write (s, (u8 *) request, strlen (request));
//	debug_printf("tcp_write returned %d\n", b);

	free (request);
	linecount = 0;
	Debugs("linecount");
	for (linecount=0; linecount < 32; linecount++) {
		Debugs("tcp_readIn");
		char *line = tcp_readln (s, 0xff, gettime(), HTTP_TIMEOUT);
//		debug_printf("tcp_readln returned %p (%s)\n", line, line?line:"(null)");
		if (!line) {
			http_status = 404;
			result = HTTPR_ERR_REQUEST;
			break;
		}

		if (strlen (line) < 1) {
			free (line);
			line = NULL;
			break;
		}
		Debugs("sscanf");
		sscanf (line, "HTTP/1.%*u %u", &http_status);
		sscanf (line, "Content-Length: %u", &content_length);
		Debugs("error");
		//sscanf (line, "Location: %s", read);
		if(linecount == 1)
		{
		redirect = line;
		Debugs(redirect);
		}
		free (line);
		line = NULL;

	}
	Debugs(redirect);
//	debug_printf("content_length = %d, status = %d, linecount = %d\n", content_length, http_status, linecount);
	if (linecount == 32 || !content_length) http_status = 404;
char*read = NULL;
Debugs("If this is the last debug message please don't bother");
if(redirect != NULL)
{
Debugs("redirect");
char * pos = strchr ( redirect, 'Location: ');
strcpy(read, pos);
redirect = read;
Debugs(redirect);
if(sscanf(redirect, "http://%*s"))
{
Debugs("http1");
	result = HTTPR_ERR_MOVED;
	report = redirect;
	Debugs("http");
return HTTPR_ERR_MOVED;
}
if(strchr ( redirect, '/') == 1)
{
	Debugs("path");
	result = HTTPR_ERR_MOVED;
	sprintf(report, "http://%s%s", http_path, redirect);
return HTTPR_ERR_MOVED;	
}
}

/*	if (399 > http_status < 200) {
		result = HTTPR_ERR_STATUS;
		net_close (s);
		return false;
	}*/

	
	if (content_length > http_max_size) {
		result = HTTPR_ERR_TOOBIG;
		net_close (s);
		return false;
	}
	http_data = (u8 *) malloc (content_length);
	Debugs("tcp_read");
	b = tcp_read (s, &http_data, content_length);
	if (!b) {
		free (http_data);
		http_data = NULL;
		result = HTTPR_ERR_RECEIVE;
		net_close (s);
		return false;
	}

	result = HTTPR_OK;

	net_close (s);
	Debugs("request complete");
	return true;
}



Edited 1 time(s). Last edit at 07/17/2009 11:23AM by SteelSLasher.
Re: sscanf problems, not the user the function
July 17, 2009 05:43PM
I don't see where the "read" variable that is used in the first sscanf function is allocated/declared

also, this:

char*read = NULL;
char * pos = strchr ( redirect, 'Location: ');
strcpy(read, pos);

is most likely going to give you a crash since read is unallocated (strcpy does not allocate any memory, it's pretty like a memcpy)


you are also doing this:

		if(linecount == 1)
		{
		redirect = line;
		Debugs(redirect);
		}
		free (line);
		line = NULL;

To me (unless I'm mistaken), this means "redirect" would points to some unallocated memory (you cannot duplicate memory by simply copying pointer value)

It seems you have taken the original "http_request" code from other projects and are trying to add some of your stuff but unfortunately, you might want to double-check all your pointer allocations because they are going to cause exceptions all over the place ;-)

Also, it's always a good idea to pay good attention to compiler warnings as they can detect this kind of mistake for you.



Edited 1 time(s). Last edit at 07/17/2009 05:44PM by ekeeke.
Re: sscanf problems, not the user the function
July 17, 2009 08:10PM
the code was originally made by bushing for patchmii, used in wiiearth, and now here, i guess these errors occur because i finally understood what the "*" thing is unless that has nothing to with a pointer

i think i can fix it now, thanks

and now to learn a bit about variables before getting back to work

also, i made read null to stop a warning, god the irony



Edited 1 time(s). Last edit at 07/17/2009 08:19PM by SteelSLasher.
Re: sscanf problems, not the user the function
July 17, 2009 09:44PM
Its more awkward now, a http response is returned which has nothing in it and this causes "break;" to be called and this causes an exception

i updated the code in SVN [code.google.com] the link takes you directly to the line
Sorry, only registered users may post in this forum.

Click here to login