widl: Detect conformant arrays of user types correctly.
This commit is contained in:
parent
4fb7a0e40e
commit
1d0f9378bc
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue