1From de95947ae5db07e4589bb16bab30b6c8ba2b3106 Mon Sep 17 00:00:00 2001
2From: Roland Schatz <roland.schatz@oracle.com>
3Date: Tue, 24 May 2022 03:04:43 +0200
4Subject: [PATCH] Fix check for invalid varargs arguments. (#707)
5 
6Conflict:NA
7Reference:https://github.com/libffi/libffi/commit/de95947ae5db07e4589bb16bab30b6c8ba2b3106
8---
9 src/prep_cif.c               |   3 +-
10 testsuite/libffi.call/va_3.c | 154 +++++++++++++++++++++++++++++++++++
11 2 files changed, 156 insertions(+), 1 deletion(-)
12 create mode 100644 testsuite/libffi.call/va_3.c
13 
14diff --git a/src/prep_cif.c b/src/prep_cif.c
15index c1832b1..2d0f252 100644
16--- a/src/prep_cif.c
17+++ b/src/prep_cif.c
18@@ -1,6 +1,7 @@
19 /* -----------------------------------------------------------------------
20    prep_cif.c - Copyright (c) 2011, 2012, 2021  Anthony Green
21                 Copyright (c) 1996, 1998, 2007  Red Hat, Inc.
22+                Copyright (c) 2022 Oracle and/or its affiliates.
23 
24    Permission is hereby granted, free of charge, to any person obtaining
25    a copy of this software and associated documentation files (the
26@@ -240,7 +241,7 @@ ffi_status ffi_prep_cif_var(ffi_cif *cif,
27   if (rc != FFI_OK)
28     return rc;
29 
30-  for (i = 1; i < ntotalargs; i++)
31+  for (i = nfixedargs; i < ntotalargs; i++)
32     {
33       ffi_type *arg_type = atypes[i];
34       if (arg_type == &ffi_type_float
35diff --git a/testsuite/libffi.call/va_3.c b/testsuite/libffi.call/va_3.c
36new file mode 100644
37index 0000000..b3e73b5
38--- /dev/null
39+++ b/testsuite/libffi.call/va_3.c
40@@ -0,0 +1,154 @@
41+/* Area:		ffi_call
42+   Purpose:		Test function with multiple fixed args and variable argument list.
43+   Limitations:	none.
44+   PR:			none.
45+   Originator:	        ARM Ltd., Oracle */
46+
47+/* { dg-do run } */
48+/* { dg-output "" { xfail avr32*-*-* m68k-*-* } } */
49+
50+#include "ffitest.h"
51+#include <stdarg.h>
52+
53+/*
54+ * This is a modified version of va_2.c that has fixed arguments with "small" types that
55+ * are not allowed as variable arguments, but they should be still allowed as fixed args.
56+ */
57+
58+static int
59+test_fn (char a1, float a2, int n, ...)
60+{
61+  va_list ap;
62+  unsigned char uc;
63+  signed char sc;
64+  unsigned short us;
65+  signed short ss;
66+  unsigned int ui;
67+  signed int si;
68+  unsigned long ul;
69+  signed long sl;
70+  float f;
71+  double d;
72+
73+  va_start (ap, n);
74+
75+  uc = va_arg (ap, unsigned);
76+  sc = va_arg (ap, signed);
77+
78+  us = va_arg (ap, unsigned);
79+  ss = va_arg (ap, signed);
80+
81+  ui = va_arg (ap, unsigned int);
82+  si = va_arg (ap, signed int);
83+
84+  ul = va_arg (ap, unsigned long);
85+  sl = va_arg (ap, signed long);
86+
87+  f = va_arg (ap, double);	/* C standard promotes float->double
88+				   when anonymous */
89+  d = va_arg (ap, double);
90+
91+  printf ("%d %f uc=%u sc=%d %u %d %u %d %lu %ld %f %f\n",
92+	  a1, a2,
93+	  uc, sc,
94+	  us, ss,
95+	  ui, si,
96+	  ul, sl,
97+	  f, d);
98+
99+  va_end (ap);
100+
101+  CHECK(a1 == 1);
102+  CHECK((int)a2 == 2);
103+  CHECK(uc == 9);
104+  CHECK(sc == 10);
105+  CHECK(us == 11);
106+  CHECK(ss == 12);
107+  CHECK(ui == 13);
108+  CHECK(si == 14);
109+  CHECK(ul == 15);
110+  CHECK(sl == 16);
111+  CHECK((int)f == 2);
112+  CHECK((int)d == 3);
113+
114+  return n + 1;
115+}
116+
117+int
118+main (void)
119+{
120+  ffi_cif cif;
121+  void* args[14];
122+  ffi_type* arg_types[14];
123+
124+  char a1;
125+  float a2;
126+  int n;
127+  ffi_arg res;
128+
129+  unsigned int uc;
130+  signed int sc;
131+  unsigned int us;
132+  signed int ss;
133+  unsigned int ui;
134+  signed int si;
135+  unsigned long ul;
136+  signed long sl;
137+  double d1;
138+  double f1;
139+
140+  arg_types[0] = &ffi_type_schar;
141+  arg_types[1] = &ffi_type_float;
142+  arg_types[2] = &ffi_type_sint;
143+  arg_types[3] = &ffi_type_uint;
144+  arg_types[4] = &ffi_type_sint;
145+  arg_types[5] = &ffi_type_uint;
146+  arg_types[6] = &ffi_type_sint;
147+  arg_types[7] = &ffi_type_uint;
148+  arg_types[8] = &ffi_type_sint;
149+  arg_types[9] = &ffi_type_ulong;
150+  arg_types[10] = &ffi_type_slong;
151+  arg_types[11] = &ffi_type_double;
152+  arg_types[12] = &ffi_type_double;
153+  arg_types[13] = NULL;
154+
155+  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 3, 13, &ffi_type_sint, arg_types) == FFI_OK);
156+
157+  a1 = 1;
158+  a2 = 2.0f;
159+  n = 41;
160+
161+  uc = 9;
162+  sc = 10;
163+  us = 11;
164+  ss = 12;
165+  ui = 13;
166+  si = 14;
167+  ul = 15;
168+  sl = 16;
169+  f1 = 2.12;
170+  d1 = 3.13;
171+
172+  args[0] = &a1;
173+  args[1] = &a2;
174+  args[2] = &n;
175+  args[3] = &uc;
176+  args[4] = &sc;
177+  args[5] = &us;
178+  args[6] = &ss;
179+  args[7] = &ui;
180+  args[8] = &si;
181+  args[9] = &ul;
182+  args[10] = &sl;
183+  args[11] = &f1;
184+  args[12] = &d1;
185+  args[13] = NULL;
186+
187+  ffi_call(&cif, FFI_FN(test_fn), &res, args);
188+  /* { dg-output "1 2.000000 uc=9 sc=10 11 12 13 14 15 16 2.120000 3.130000" } */
189+  printf("res: %d\n", (int) res);
190+  /* { dg-output "\nres: 42" } */
191+  CHECK(res == 42);
192+
193+  return 0;
194+}
195-- 
1962.23.0
197