Skip to content
Snippets Groups Projects
Commit f7d2b24d authored by Rob Swindell's avatar Rob Swindell :speech_balloon:
Browse files

smb_putmsghdr() now supports expanding message headers beyond allocated blocks

The old "illegal header length increase" error goes away and now
smb_putmsghdr() will re-allocate a header if needs to be moved to accommodate
new header fields or header fields with increase data lengths.

We can consider getting rid of the MsgBase "expand_fields" concept now.

This fixes issue #404
parent d5e8981d
No related branches found
No related tags found
1 merge request!463MRC mods by Codefenix (2024-10-20)
Pipeline #4254 passed
......@@ -299,6 +299,9 @@ int smb_freemsghdr(smb_t* smb, off_t offset, uint length)
int l,blocks;
off_t sha_offset;
if(smb->status.attr&SMB_HYPERALLOC) /* Nothing to do */
return(SMB_SUCCESS);
if(smb->sha_fp==NULL) {
safe_snprintf(smb->last_error, sizeof(smb->last_error), "%s msgbase not open", __FUNCTION__);
return(SMB_ERR_NOT_OPEN);
......
......@@ -1597,6 +1597,10 @@ int smb_addcrc(smb_t* smb, uint32_t crc)
/* This function will UN-lock the SMB header */
/****************************************************************************/
int smb_addmsghdr(smb_t* smb, smbmsg_t* msg, int storage)
{
return smb_new_msghdr(smb, msg, storage, /* new_msg: */TRUE);
}
int smb_new_msghdr(smb_t* smb, smbmsg_t* msg, int storage, BOOL new_msg)
{
int i;
off_t l;
......@@ -1635,6 +1639,7 @@ int smb_addmsghdr(smb_t* smb, smbmsg_t* msg, int storage)
return SMB_ERR_FILE_LEN;
}
if(new_msg) {
msg->hdr.number=smb->status.last_msg+1;
if(msg->hdr.thread_id==0) /* new thread being started */
......@@ -1646,7 +1651,7 @@ int smb_addmsghdr(smb_t* smb, smbmsg_t* msg, int storage)
smb_unlocksmbhdr(smb);
return(i); /* error updating hash table */
}
}
if(storage!=SMB_HYPERALLOC && (i=smb_open_ha(smb))!=SMB_SUCCESS) {
smb_unlocksmbhdr(smb);
return(i);
......@@ -1669,10 +1674,11 @@ int smb_addmsghdr(smb_t* smb, smbmsg_t* msg, int storage)
}
msg->idx.offset=(uint32_t)(smb->status.header_offset + l);
if(new_msg)
msg->idx_offset=smb->status.total_msgs;
msg->hdr.attr &= ~MSG_DELETE;
i=smb_putmsg(smb,msg);
if(i==SMB_SUCCESS) {
if(i==SMB_SUCCESS && new_msg) {
smb->status.last_msg++;
smb->status.total_msgs++;
smb_putstatus(smb);
......@@ -1916,11 +1922,23 @@ int smb_putmsghdr(smb_t* smb, smbmsg_t* msg)
return(SMB_ERR_HDR_LEN);
}
if(smb_hdrblocks(hdrlen) > smb_hdrblocks(msg->hdr.length)) {
off_t offset = msg->idx.offset;
int result = smb_new_msghdr(smb, msg, (smb->status.attr&SMB_HYPERALLOC) ? SMB_HYPERALLOC : SMB_SELFPACK, FALSE);
if(result != SMB_SUCCESS)
return result;
if(fseeko(smb->shd_fp, offset, SEEK_SET) != 0) {
safe_snprintf(smb->last_error,sizeof(smb->last_error)
,"%s illegal header length increase: %u (%u blocks, %hu hfields, %hu dfields) vs %hu (%u blocks)", __FUNCTION__
,hdrlen, smb_hdrblocks(hdrlen), msg->total_hfields, msg->hdr.total_dfields
,msg->hdr.length, smb_hdrblocks(msg->hdr.length));
return(SMB_ERR_HDR_LEN);
,"%s %d '%s' seeking to %u in header file (to delete)", __FUNCTION__
,get_errno(),STRERROR(get_errno()), (uint)msg->idx.offset);
return(SMB_ERR_SEEK);
}
msg->hdr.attr |= MSG_DELETE;
if(fwrite(&msg->hdr, sizeof(msg->hdr), 1, smb->shd_fp) != 1) {
safe_snprintf(smb->last_error,sizeof(smb->last_error)
,"%s writing fixed portion of header record (to delete)", __FUNCTION__);
return(SMB_ERR_WRITE);
}
return smb_freemsghdr(smb, msg->idx.offset-smb->status.header_offset, msg->hdr.length);
}
msg->hdr.length=(uint16_t)hdrlen; /* store the actual header length */
/**********************************/
......
......@@ -151,6 +151,7 @@ SMBEXPORT int smb_dfield(smbmsg_t*, uint16_t type, uint length);
SMBEXPORT void* smb_get_hfield(smbmsg_t*, uint16_t type, hfield_t** hfield);
SMBEXPORT int smb_new_hfield(smbmsg_t*, uint16_t type, size_t, void* data);
SMBEXPORT int smb_new_hfield_str(smbmsg_t*, uint16_t type, const char*);
SMBEXPORT int smb_new_msghdr(smb_t*, smbmsg_t*, int storage, BOOL new_msg);
SMBEXPORT int smb_addmsghdr(smb_t*, smbmsg_t*, int storage);
SMBEXPORT int smb_putmsg(smb_t*, smbmsg_t*);
SMBEXPORT int smb_putmsgidx(smb_t*, smbmsg_t*);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment