summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/rpc_parse/parse_prs.c66
1 files changed, 37 insertions, 29 deletions
diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c
index 7bc9578863..469de90434 100644
--- a/source3/rpc_parse/parse_prs.c
+++ b/source3/rpc_parse/parse_prs.c
@@ -730,7 +730,6 @@ BOOL prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str)
else { /* unmarshalling */
uint32 alloc_len = 0;
- len = -1;
q = prs_data_p(ps) + prs_offset(ps);
/*
@@ -738,43 +737,52 @@ BOOL prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str)
*/
max_len = (ps->buffer_size - ps->data_offset)/sizeof(uint16);
+ /* the test of the value of *ptr helps to catch the circumstance
+ where we have an emtpty (non-existent) string in the buffer */
for ( ptr = (uint16 *)q; *ptr && (alloc_len <= max_len); alloc_len++)
+ /* do nothing */
;
- if (alloc_len > 0)
- {
- str->buffer = (uint16 *)prs_alloc_mem(ps,alloc_len * sizeof(uint16));
- if (str->buffer == NULL)
- return False;
- p = (unsigned char *)str->buffer;
+ /* should we allocate anything at all? */
+ str->buffer = (uint16 *)prs_alloc_mem(ps,alloc_len * sizeof(uint16));
+ if ((str->buffer == NULL) && (alloc_len > 0))
+ return False;
+
+ p = (unsigned char *)str->buffer;
- do
+ len = 0;
+ /* the (len < alloc_len) test is to prevent us from overwriting
+ memory that is not ours...if we get that far, we have a non-null
+ terminated string in the buffer and have messed up somewhere */
+ while ((len < alloc_len) && (*q != '\0'))
+ {
+ if(ps->bigendian_data)
{
- len++;
-
- if(ps->bigendian_data)
- {
- RW_SVAL(ps->io, ps->bigendian_data, q, *p, 0);
- p += 2;
- q += 2;
- } else {
- RW_CVAL(ps->io, q, *p, 0);
- p++;
- q++;
- RW_CVAL(ps->io, q, *p, 0);
- p++;
- q++;
- }
- } while (len < alloc_len && str->buffer[len] != 0);
- }
- else
+ RW_SVAL(ps->io, ps->bigendian_data, q, *p, 0);
+ p += 2;
+ q += 2;
+ } else {
+ RW_CVAL(ps->io, q, *p, 0);
+ p++;
+ q++;
+ RW_CVAL(ps->io, q, *p, 0);
+ p++;
+ q++;
+ }
+
+ len++;
+ }
+ if (len < alloc_len)
{
- len = 0;
- str->buffer = NULL;
+ /* NULL terminate the UNISTR */
+ str->buffer[len++] = '\0';
}
}
- ps->data_offset += len*2;
+ /* set the offset in the prs_struct; 'len' points to the
+ terminiating NULL in the UNISTR so we need to go one more
+ uint16 */
+ ps->data_offset += (len)*2;
return True;
}