widl: Detect conformant arrays of user types correctly.

This commit is contained in:
Dan Hipschman 2007-10-17 18:06:26 -07:00 committed by Alexandre Julliard
parent 4fb7a0e40e
commit 1d0f9378bc
5 changed files with 107 additions and 24 deletions

View File

@ -48,6 +48,14 @@ midl_user_free(void __RPC_FAR *p)
free(p);
}
static char *
xstrdup(const char *s)
{
char *d = HeapAlloc(GetProcessHeap(), 0, strlen(s) + 1);
strcpy(d, s);
return d;
}
int
s_int_return(void)
{
@ -263,6 +271,26 @@ s_square_puint(puint_t p)
return n * n;
}
int
s_sum_puints(puints_t *p)
{
int sum = 0;
int i;
for (i = 0; i < p->n; ++i)
sum += atoi(p->ps[i]);
return sum;
}
int
s_sum_cpuints(cpuints_t *p)
{
int sum = 0;
int i;
for (i = 0; i < p->n; ++i)
sum += atoi(p->ps[i]);
return sum;
}
int
s_dot_copy_vectors(vector_t u, vector_t v)
{
@ -724,9 +752,35 @@ pointer_tests(void)
test_list_t *list = make_list(make_list(make_list(null_list())));
test_us_t tus = {{p1}};
int *pa[4];
puints_t pus;
cpuints_t cpus;
ok(test_list_length(list) == 3, "RPC test_list_length\n");
ok(square_puint(p1) == 121, "RPC square_puint\n");
pus.n = 4;
pus.ps = HeapAlloc(GetProcessHeap(), 0, pus.n * sizeof pus.ps[0]);
pus.ps[0] = xstrdup("5");
pus.ps[1] = xstrdup("6");
pus.ps[2] = xstrdup("7");
pus.ps[3] = xstrdup("8");
ok(sum_puints(&pus) == 26, "RPC sum_puints\n");
HeapFree(GetProcessHeap(), 0, pus.ps[0]);
HeapFree(GetProcessHeap(), 0, pus.ps[1]);
HeapFree(GetProcessHeap(), 0, pus.ps[2]);
HeapFree(GetProcessHeap(), 0, pus.ps[3]);
HeapFree(GetProcessHeap(), 0, pus.ps);
cpus.n = 4;
cpus.ps = HeapAlloc(GetProcessHeap(), 0, cpus.n * sizeof cpus.ps[0]);
cpus.ps[0] = xstrdup("5");
cpus.ps[1] = xstrdup("6");
cpus.ps[2] = xstrdup("7");
cpus.ps[3] = xstrdup("8");
ok(sum_cpuints(&cpus) == 26, "RPC sum_puints\n");
HeapFree(GetProcessHeap(), 0, cpus.ps[0]);
HeapFree(GetProcessHeap(), 0, cpus.ps[1]);
HeapFree(GetProcessHeap(), 0, cpus.ps[2]);
HeapFree(GetProcessHeap(), 0, cpus.ps[3]);
HeapFree(GetProcessHeap(), 0, cpus.ps);
ok(square_test_us(&tus) == 121, "RPC square_test_us\n");
pa[0] = &a[0];

View File

@ -153,6 +153,22 @@ cpp_quote("#endif")
typedef [wire_marshal(int)] void *puint_t;
int square_puint(puint_t p);
typedef struct
{
[size_is(n)] puint_t *ps;
int n;
} puints_t;
/* Same thing as puints_t, but make it complex (needs padding). */
typedef struct
{
[size_is(n)] puint_t *ps;
char n;
} cpuints_t;
int sum_puints(puints_t *p);
int sum_cpuints(cpuints_t *p);
int dot_copy_vectors(vector_t u, vector_t v);
typedef struct wire_us *wire_us_t;

View File

@ -101,7 +101,9 @@ int is_void(const type_t *t)
int is_conformant_array(const type_t *t)
{
return t->type == RPC_FC_CARRAY || t->type == RPC_FC_CVARRAY;
return t->type == RPC_FC_CARRAY
|| t->type == RPC_FC_CVARRAY
|| (t->type == RPC_FC_BOGUS_ARRAY && t->size_is);
}
void write_guid(FILE *f, const char *guid_prefix, const char *name, const UUID *uuid)

View File

@ -1434,24 +1434,24 @@ static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr,
if (is_array(v->type))
{
const type_t *rt = v->type->ref;
switch (rt->type)
{
case RPC_FC_BOGUS_STRUCT:
case RPC_FC_NON_ENCAPSULATED_UNION:
case RPC_FC_ENCAPSULATED_UNION:
case RPC_FC_ENUM16:
if (is_user_type(rt))
v->type->type = RPC_FC_BOGUS_ARRAY;
break;
/* FC_RP should be above, but widl overuses these, and will break things. */
case RPC_FC_UP:
case RPC_FC_RP:
if (rt->ref->type == RPC_FC_IP)
v->type->type = RPC_FC_BOGUS_ARRAY;
break;
default:
if (is_user_type(rt))
v->type->type = RPC_FC_BOGUS_ARRAY;
}
else
switch (rt->type)
{
case RPC_FC_BOGUS_STRUCT:
case RPC_FC_NON_ENCAPSULATED_UNION:
case RPC_FC_ENCAPSULATED_UNION:
case RPC_FC_ENUM16:
v->type->type = RPC_FC_BOGUS_ARRAY;
break;
/* FC_RP should be above, but widl overuses these, and will break things. */
case RPC_FC_UP:
case RPC_FC_RP:
if (rt->ref->type == RPC_FC_IP)
v->type->type = RPC_FC_BOGUS_ARRAY;
break;
}
}
}
@ -1859,6 +1859,7 @@ static int get_struct_type(var_list_t *fields)
case RPC_FC_OP:
case RPC_FC_CARRAY:
case RPC_FC_CVARRAY:
case RPC_FC_BOGUS_ARRAY:
has_pointer = 1;
break;
@ -1897,15 +1898,9 @@ static int get_struct_type(var_list_t *fields)
/* fallthru - treat it as complex */
/* as soon as we see one of these these members, it's bogus... */
case RPC_FC_IP:
case RPC_FC_ENCAPSULATED_UNION:
case RPC_FC_NON_ENCAPSULATED_UNION:
case RPC_FC_TRANSMIT_AS:
case RPC_FC_REPRESENT_AS:
case RPC_FC_PAD:
case RPC_FC_EMBEDDED_COMPLEX:
case RPC_FC_BOGUS_STRUCT:
case RPC_FC_BOGUS_ARRAY:
return RPC_FC_BOGUS_STRUCT;
}
}

View File

@ -1744,6 +1744,22 @@ static size_t write_struct_tfs(FILE *file, type_t *type,
type_t *ft = f->type;
if (is_ptr(ft))
write_pointer_tfs(file, ft, tfsoff);
else if (!ft->declarray && is_conformant_array(ft))
{
unsigned int absoff = ft->typestring_offset;
short reloff = absoff - (*tfsoff + 2);
int ptr_type = get_attrv(f->attrs, ATTR_POINTERTYPE);
/* FIXME: We need to store pointer attributes for arrays
so we don't lose pointer_default info. */
if (ptr_type == 0)
ptr_type = RPC_FC_UP;
print_file(file, 0, "/* %d */\n", *tfsoff);
print_file(file, 2, "0x%x, 0x0,\t/* %s */\n", ptr_type,
string_of_type(ptr_type));
print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%u) */\n",
reloff, reloff, absoff);
*tfsoff += 4;
}
}
if (type->ptrdesc == *tfsoff)
type->ptrdesc = 0;