Fixes a bug introduced in a previous commit in http_SendMessage.

The variable num_read was beeing used without beeing initialized.

Also, clean up the function return path and make sure va_end()
is beeing called.
This commit is contained in:
Marcelo Roberto Jimenez
2010-11-24 11:26:00 -02:00
parent bfbd07cb40
commit 9a28fcc95b
2 changed files with 54 additions and 84 deletions

View File

@@ -418,51 +418,22 @@ ExitFunction:
return ret; return ret;
} }
int http_SendMessage(SOCKINFO *info, int *TimeOut, const char *fmt, ...)
/************************************************************************
* Function: http_SendMessage
*
* Parameters:
* IN SOCKINFO *info ; Socket information object
* IN OUT int * TimeOut ; time out value
* IN const char* fmt, ... Pattern format to take actions upon
*
* Description:
* Sends a message to the destination based on the
* IN const char* fmt parameter
* fmt types:
* 'f': arg = const char * file name
* 'm': arg1 = const char * mem_buffer; arg2= size_t buf_length
* E.g.:
* char *buf = "POST /xyz.cgi http/1.1\r\n\r\n";
* char *filename = "foo.dat";
* int status = http_SendMessage( tcpsock, "mf",
* buf, strlen(buf),
* filename );
*
* Returns:
* UPNP_E_OUTOF_MEMORY
* UPNP_E_FILE_READ_ERROR
* UPNP_E_SUCCESS
************************************************************************/
int http_SendMessage(IN SOCKINFO * info, IN OUT int *TimeOut,
IN const char *fmt, ...)
{ {
FILE *Fp; FILE *Fp;
va_list argp; va_list argp;
struct SendInstruction *Instr = NULL; struct SendInstruction *Instr = NULL;
size_t num_read;
size_t num_written;
int nr;
int nw;
int RetVal = 0;
char c;
char *buf = NULL; char *buf = NULL;
size_t buf_length;
char *filename = NULL; char *filename = NULL;
char *file_buf = NULL; char *file_buf = NULL;
char *ChunkBuf = NULL; char *ChunkBuf = NULL;
char Chunk_Header[CHUNK_HEADER_SIZE]; char Chunk_Header[CHUNK_HEADER_SIZE];
char c;
int nw;
int RetVal = 0;
size_t buf_length;
size_t num_read;
size_t num_written;
size_t amount_to_be_read = 0; size_t amount_to_be_read = 0;
/* 10 byte allocated for chunk header. */ /* 10 byte allocated for chunk header. */
size_t Data_Buf_Size = WEB_SERVER_BUF_SIZE; size_t Data_Buf_Size = WEB_SERVER_BUF_SIZE;
@@ -471,9 +442,6 @@ int http_SendMessage(IN SOCKINFO * info, IN OUT int *TimeOut,
while ((c = *fmt++) != 0) { while ((c = *fmt++) != 0) {
if (c == 'I') { if (c == 'I') {
Instr = va_arg(argp, struct SendInstruction *); Instr = va_arg(argp, struct SendInstruction *);
assert(Instr);
if (Instr->ReadSendSize >= 0) if (Instr->ReadSendSize >= 0)
amount_to_be_read = (size_t)Instr->ReadSendSize; amount_to_be_read = (size_t)Instr->ReadSendSize;
else else
@@ -483,8 +451,10 @@ int http_SendMessage(IN SOCKINFO * info, IN OUT int *TimeOut,
ChunkBuf = malloc((size_t) ChunkBuf = malloc((size_t)
(Data_Buf_Size + CHUNK_HEADER_SIZE + (Data_Buf_Size + CHUNK_HEADER_SIZE +
CHUNK_TAIL_SIZE)); CHUNK_TAIL_SIZE));
if (!ChunkBuf) if (!ChunkBuf) {
return UPNP_E_OUTOF_MEMORY; RetVal = UPNP_E_OUTOF_MEMORY;
goto ExitFunction;
}
file_buf = ChunkBuf + CHUNK_HEADER_SIZE; file_buf = ChunkBuf + CHUNK_HEADER_SIZE;
} else if (c == 'f') { } else if (c == 'f') {
/* file name */ /* file name */
@@ -494,32 +464,33 @@ int http_SendMessage(IN SOCKINFO * info, IN OUT int *TimeOut,
else else
Fp = fopen(filename, "rb"); Fp = fopen(filename, "rb");
if (Fp == NULL) { if (Fp == NULL) {
free(ChunkBuf); RetVal = UPNP_E_FILE_READ_ERROR;
return UPNP_E_FILE_READ_ERROR; goto ExitFunction;
} }
if (Instr && Instr->IsRangeActive && Instr->IsVirtualFile) { if (Instr && Instr->IsRangeActive && Instr->IsVirtualFile) {
if (virtualDirCallback.seek(Fp, Instr->RangeOffset, if (virtualDirCallback.seek(Fp, Instr->RangeOffset,
SEEK_CUR) != 0) { SEEK_CUR) != 0) {
free(ChunkBuf); RetVal = UPNP_E_FILE_READ_ERROR;
return UPNP_E_FILE_READ_ERROR; goto ExitFunction;
} }
} else if (Instr && Instr->IsRangeActive) { } else if (Instr && Instr->IsRangeActive) {
if (fseeko(Fp, Instr->RangeOffset, SEEK_CUR) != 0) { if (fseeko(Fp, Instr->RangeOffset, SEEK_CUR) != 0) {
free(ChunkBuf); RetVal = UPNP_E_FILE_READ_ERROR;
return UPNP_E_FILE_READ_ERROR; goto ExitFunction;
} }
} }
while (amount_to_be_read) { while (amount_to_be_read) {
if (Instr) { if (Instr) {
int nr;
size_t n = amount_to_be_read >= Data_Buf_Size ? size_t n = amount_to_be_read >= Data_Buf_Size ?
Data_Buf_Size : amount_to_be_read; Data_Buf_Size : amount_to_be_read;
if (Instr->IsVirtualFile) { if (Instr->IsVirtualFile) {
nr = virtualDirCallback.read(Fp, file_buf, n); nr = virtualDirCallback.read(Fp, file_buf, n);
amount_to_be_read -= (size_t)nr; num_read = (size_t)nr;
} else { } else {
num_read = fread(file_buf, 1, n, Fp); num_read = fread(file_buf, 1, n, Fp);
amount_to_be_read -= num_read;
} }
amount_to_be_read -= num_read;
if (Instr->ReadSendSize < 0) { if (Instr->ReadSendSize < 0) {
/* read until close */ /* read until close */
amount_to_be_read = Data_Buf_Size; amount_to_be_read = Data_Buf_Size;
@@ -576,14 +547,12 @@ int http_SendMessage(IN SOCKINFO * info, IN OUT int *TimeOut,
} }
} /* while */ } /* while */
Cleanup_File: Cleanup_File:
va_end(argp);
if (Instr && Instr->IsVirtualFile) { if (Instr && Instr->IsVirtualFile) {
virtualDirCallback.close(Fp); virtualDirCallback.close(Fp);
} else { } else {
fclose(Fp); fclose(Fp);
} }
free(ChunkBuf); goto ExitFunction;
return RetVal;
} else if (c == 'b') { } else if (c == 'b') {
/* memory buffer */ /* memory buffer */
buf = va_arg(argp, char *); buf = va_arg(argp, char *);
@@ -596,16 +565,17 @@ int http_SendMessage(IN SOCKINFO * info, IN OUT int *TimeOut,
"%.*s\nbuf_length=%zd, num_written=%zd\n""------------\n", "%.*s\nbuf_length=%zd, num_written=%zd\n""------------\n",
(int)buf_length, buf, buf_length, num_written); (int)buf_length, buf, buf_length, num_written);
if (num_written != buf_length) { if (num_written != buf_length) {
goto end; RetVal = 0;
goto ExitFunction;
} }
} }
} }
} }
end: ExitFunction:
va_end(argp); va_end(argp);
free(ChunkBuf); free(ChunkBuf);
return 0; return RetVal;
} }

View File

@@ -122,37 +122,37 @@ int http_RecvMessage( IN SOCKINFO *info, OUT http_parser_t* parser,
OUT int* http_error_code ); OUT int* http_error_code );
/************************************************************************ /*!
* Function: http_SendMessage * \brief Sends a message to the destination based on the format parameter.
* *
* Parameters:
* IN SOCKINFO *info ; Socket information object
* IN OUT int * TimeOut ; time out value
* IN const char* fmt, ... Pattern format to take actions upon
*
* Description:
* Sends a message to the destination based on the
* IN const char* fmt parameter
* fmt types: * fmt types:
* 'f': arg = const char * file name * \li \c 'f': arg = "const char *" file name
* 'm': arg1 = const char * mem_buffer; arg2= size_t buf_length * \li \c 'b': arg1 = "const char *" mem_buffer; arg2 = "size_t" buffer length.
* E.g.: * \li \c 'I': arg = "struct SendInstruction *"
* char *buf = "POST /xyz.cgi http/1.1\r\n\r\n";
* char *filename = "foo.dat";
* int status = http_SendMessage( tcpsock, "mf",
* buf, strlen(buf), // args for memory buffer
* filename ); // arg for file
* *
* Returns: * E.g.:
* UPNP_E_OUTOF_MEMORY \verbatim
* UPNP_E_FILE_READ_ERROR char *buf = "POST /xyz.cgi http/1.1\r\n\r\n";
* UPNP_E_SUCCESS char *filename = "foo.dat";
************************************************************************/ int status = http_SendMessage(tcpsock, "bf",
buf, strlen(buf), // args for memory buffer
filename); // arg for file
\endverbatim
*
* \return
* \li \c UPNP_E_OUTOF_MEMORY
* \li \c UPNP_E_FILE_READ_ERROR
* \li \c UPNP_E_SUCCESS
*/
int http_SendMessage( int http_SendMessage(
IN SOCKINFO *info, /* [in] Socket information object. */
IN OUT int* timeout_secs, SOCKINFO *info,
IN const char* fmt, ... ); /* [in,out] Time out value. */
int* timeout_secs,
/* [in] Pattern format to take actions upon. */
const char* fmt,
/* [in] Variable parameter list. */
...);
/************************************************************************ /************************************************************************
* Function: http_RequestAndResponse * Function: http_RequestAndResponse