diff options
-rw-r--r-- | source3/rpc_parse/parse_prs.c | 66 |
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; } |