14cffe588Sopenharmony_ciFrom de95947ae5db07e4589bb16bab30b6c8ba2b3106 Mon Sep 17 00:00:00 2001
24cffe588Sopenharmony_ciFrom: Roland Schatz <roland.schatz@oracle.com>
34cffe588Sopenharmony_ciDate: Tue, 24 May 2022 03:04:43 +0200
44cffe588Sopenharmony_ciSubject: [PATCH] Fix check for invalid varargs arguments. (#707)
54cffe588Sopenharmony_ci 
64cffe588Sopenharmony_ciConflict:NA
74cffe588Sopenharmony_ciReference:https://github.com/libffi/libffi/commit/de95947ae5db07e4589bb16bab30b6c8ba2b3106
84cffe588Sopenharmony_ci---
94cffe588Sopenharmony_ci src/prep_cif.c               |   3 +-
104cffe588Sopenharmony_ci testsuite/libffi.call/va_3.c | 154 +++++++++++++++++++++++++++++++++++
114cffe588Sopenharmony_ci 2 files changed, 156 insertions(+), 1 deletion(-)
124cffe588Sopenharmony_ci create mode 100644 testsuite/libffi.call/va_3.c
134cffe588Sopenharmony_ci 
144cffe588Sopenharmony_cidiff --git a/src/prep_cif.c b/src/prep_cif.c
154cffe588Sopenharmony_ciindex c1832b1..2d0f252 100644
164cffe588Sopenharmony_ci--- a/src/prep_cif.c
174cffe588Sopenharmony_ci+++ b/src/prep_cif.c
184cffe588Sopenharmony_ci@@ -1,6 +1,7 @@
194cffe588Sopenharmony_ci /* -----------------------------------------------------------------------
204cffe588Sopenharmony_ci    prep_cif.c - Copyright (c) 2011, 2012, 2021  Anthony Green
214cffe588Sopenharmony_ci                 Copyright (c) 1996, 1998, 2007  Red Hat, Inc.
224cffe588Sopenharmony_ci+                Copyright (c) 2022 Oracle and/or its affiliates.
234cffe588Sopenharmony_ci 
244cffe588Sopenharmony_ci    Permission is hereby granted, free of charge, to any person obtaining
254cffe588Sopenharmony_ci    a copy of this software and associated documentation files (the
264cffe588Sopenharmony_ci@@ -240,7 +241,7 @@ ffi_status ffi_prep_cif_var(ffi_cif *cif,
274cffe588Sopenharmony_ci   if (rc != FFI_OK)
284cffe588Sopenharmony_ci     return rc;
294cffe588Sopenharmony_ci 
304cffe588Sopenharmony_ci-  for (i = 1; i < ntotalargs; i++)
314cffe588Sopenharmony_ci+  for (i = nfixedargs; i < ntotalargs; i++)
324cffe588Sopenharmony_ci     {
334cffe588Sopenharmony_ci       ffi_type *arg_type = atypes[i];
344cffe588Sopenharmony_ci       if (arg_type == &ffi_type_float
354cffe588Sopenharmony_cidiff --git a/testsuite/libffi.call/va_3.c b/testsuite/libffi.call/va_3.c
364cffe588Sopenharmony_cinew file mode 100644
374cffe588Sopenharmony_ciindex 0000000..b3e73b5
384cffe588Sopenharmony_ci--- /dev/null
394cffe588Sopenharmony_ci+++ b/testsuite/libffi.call/va_3.c
404cffe588Sopenharmony_ci@@ -0,0 +1,154 @@
414cffe588Sopenharmony_ci+/* Area:		ffi_call
424cffe588Sopenharmony_ci+   Purpose:		Test function with multiple fixed args and variable argument list.
434cffe588Sopenharmony_ci+   Limitations:	none.
444cffe588Sopenharmony_ci+   PR:			none.
454cffe588Sopenharmony_ci+   Originator:	        ARM Ltd., Oracle */
464cffe588Sopenharmony_ci+
474cffe588Sopenharmony_ci+/* { dg-do run } */
484cffe588Sopenharmony_ci+/* { dg-output "" { xfail avr32*-*-* m68k-*-* } } */
494cffe588Sopenharmony_ci+
504cffe588Sopenharmony_ci+#include "ffitest.h"
514cffe588Sopenharmony_ci+#include <stdarg.h>
524cffe588Sopenharmony_ci+
534cffe588Sopenharmony_ci+/*
544cffe588Sopenharmony_ci+ * This is a modified version of va_2.c that has fixed arguments with "small" types that
554cffe588Sopenharmony_ci+ * are not allowed as variable arguments, but they should be still allowed as fixed args.
564cffe588Sopenharmony_ci+ */
574cffe588Sopenharmony_ci+
584cffe588Sopenharmony_ci+static int
594cffe588Sopenharmony_ci+test_fn (char a1, float a2, int n, ...)
604cffe588Sopenharmony_ci+{
614cffe588Sopenharmony_ci+  va_list ap;
624cffe588Sopenharmony_ci+  unsigned char uc;
634cffe588Sopenharmony_ci+  signed char sc;
644cffe588Sopenharmony_ci+  unsigned short us;
654cffe588Sopenharmony_ci+  signed short ss;
664cffe588Sopenharmony_ci+  unsigned int ui;
674cffe588Sopenharmony_ci+  signed int si;
684cffe588Sopenharmony_ci+  unsigned long ul;
694cffe588Sopenharmony_ci+  signed long sl;
704cffe588Sopenharmony_ci+  float f;
714cffe588Sopenharmony_ci+  double d;
724cffe588Sopenharmony_ci+
734cffe588Sopenharmony_ci+  va_start (ap, n);
744cffe588Sopenharmony_ci+
754cffe588Sopenharmony_ci+  uc = va_arg (ap, unsigned);
764cffe588Sopenharmony_ci+  sc = va_arg (ap, signed);
774cffe588Sopenharmony_ci+
784cffe588Sopenharmony_ci+  us = va_arg (ap, unsigned);
794cffe588Sopenharmony_ci+  ss = va_arg (ap, signed);
804cffe588Sopenharmony_ci+
814cffe588Sopenharmony_ci+  ui = va_arg (ap, unsigned int);
824cffe588Sopenharmony_ci+  si = va_arg (ap, signed int);
834cffe588Sopenharmony_ci+
844cffe588Sopenharmony_ci+  ul = va_arg (ap, unsigned long);
854cffe588Sopenharmony_ci+  sl = va_arg (ap, signed long);
864cffe588Sopenharmony_ci+
874cffe588Sopenharmony_ci+  f = va_arg (ap, double);	/* C standard promotes float->double
884cffe588Sopenharmony_ci+				   when anonymous */
894cffe588Sopenharmony_ci+  d = va_arg (ap, double);
904cffe588Sopenharmony_ci+
914cffe588Sopenharmony_ci+  printf ("%d %f uc=%u sc=%d %u %d %u %d %lu %ld %f %f\n",
924cffe588Sopenharmony_ci+	  a1, a2,
934cffe588Sopenharmony_ci+	  uc, sc,
944cffe588Sopenharmony_ci+	  us, ss,
954cffe588Sopenharmony_ci+	  ui, si,
964cffe588Sopenharmony_ci+	  ul, sl,
974cffe588Sopenharmony_ci+	  f, d);
984cffe588Sopenharmony_ci+
994cffe588Sopenharmony_ci+  va_end (ap);
1004cffe588Sopenharmony_ci+
1014cffe588Sopenharmony_ci+  CHECK(a1 == 1);
1024cffe588Sopenharmony_ci+  CHECK((int)a2 == 2);
1034cffe588Sopenharmony_ci+  CHECK(uc == 9);
1044cffe588Sopenharmony_ci+  CHECK(sc == 10);
1054cffe588Sopenharmony_ci+  CHECK(us == 11);
1064cffe588Sopenharmony_ci+  CHECK(ss == 12);
1074cffe588Sopenharmony_ci+  CHECK(ui == 13);
1084cffe588Sopenharmony_ci+  CHECK(si == 14);
1094cffe588Sopenharmony_ci+  CHECK(ul == 15);
1104cffe588Sopenharmony_ci+  CHECK(sl == 16);
1114cffe588Sopenharmony_ci+  CHECK((int)f == 2);
1124cffe588Sopenharmony_ci+  CHECK((int)d == 3);
1134cffe588Sopenharmony_ci+
1144cffe588Sopenharmony_ci+  return n + 1;
1154cffe588Sopenharmony_ci+}
1164cffe588Sopenharmony_ci+
1174cffe588Sopenharmony_ci+int
1184cffe588Sopenharmony_ci+main (void)
1194cffe588Sopenharmony_ci+{
1204cffe588Sopenharmony_ci+  ffi_cif cif;
1214cffe588Sopenharmony_ci+  void* args[14];
1224cffe588Sopenharmony_ci+  ffi_type* arg_types[14];
1234cffe588Sopenharmony_ci+
1244cffe588Sopenharmony_ci+  char a1;
1254cffe588Sopenharmony_ci+  float a2;
1264cffe588Sopenharmony_ci+  int n;
1274cffe588Sopenharmony_ci+  ffi_arg res;
1284cffe588Sopenharmony_ci+
1294cffe588Sopenharmony_ci+  unsigned int uc;
1304cffe588Sopenharmony_ci+  signed int sc;
1314cffe588Sopenharmony_ci+  unsigned int us;
1324cffe588Sopenharmony_ci+  signed int ss;
1334cffe588Sopenharmony_ci+  unsigned int ui;
1344cffe588Sopenharmony_ci+  signed int si;
1354cffe588Sopenharmony_ci+  unsigned long ul;
1364cffe588Sopenharmony_ci+  signed long sl;
1374cffe588Sopenharmony_ci+  double d1;
1384cffe588Sopenharmony_ci+  double f1;
1394cffe588Sopenharmony_ci+
1404cffe588Sopenharmony_ci+  arg_types[0] = &ffi_type_schar;
1414cffe588Sopenharmony_ci+  arg_types[1] = &ffi_type_float;
1424cffe588Sopenharmony_ci+  arg_types[2] = &ffi_type_sint;
1434cffe588Sopenharmony_ci+  arg_types[3] = &ffi_type_uint;
1444cffe588Sopenharmony_ci+  arg_types[4] = &ffi_type_sint;
1454cffe588Sopenharmony_ci+  arg_types[5] = &ffi_type_uint;
1464cffe588Sopenharmony_ci+  arg_types[6] = &ffi_type_sint;
1474cffe588Sopenharmony_ci+  arg_types[7] = &ffi_type_uint;
1484cffe588Sopenharmony_ci+  arg_types[8] = &ffi_type_sint;
1494cffe588Sopenharmony_ci+  arg_types[9] = &ffi_type_ulong;
1504cffe588Sopenharmony_ci+  arg_types[10] = &ffi_type_slong;
1514cffe588Sopenharmony_ci+  arg_types[11] = &ffi_type_double;
1524cffe588Sopenharmony_ci+  arg_types[12] = &ffi_type_double;
1534cffe588Sopenharmony_ci+  arg_types[13] = NULL;
1544cffe588Sopenharmony_ci+
1554cffe588Sopenharmony_ci+  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 3, 13, &ffi_type_sint, arg_types) == FFI_OK);
1564cffe588Sopenharmony_ci+
1574cffe588Sopenharmony_ci+  a1 = 1;
1584cffe588Sopenharmony_ci+  a2 = 2.0f;
1594cffe588Sopenharmony_ci+  n = 41;
1604cffe588Sopenharmony_ci+
1614cffe588Sopenharmony_ci+  uc = 9;
1624cffe588Sopenharmony_ci+  sc = 10;
1634cffe588Sopenharmony_ci+  us = 11;
1644cffe588Sopenharmony_ci+  ss = 12;
1654cffe588Sopenharmony_ci+  ui = 13;
1664cffe588Sopenharmony_ci+  si = 14;
1674cffe588Sopenharmony_ci+  ul = 15;
1684cffe588Sopenharmony_ci+  sl = 16;
1694cffe588Sopenharmony_ci+  f1 = 2.12;
1704cffe588Sopenharmony_ci+  d1 = 3.13;
1714cffe588Sopenharmony_ci+
1724cffe588Sopenharmony_ci+  args[0] = &a1;
1734cffe588Sopenharmony_ci+  args[1] = &a2;
1744cffe588Sopenharmony_ci+  args[2] = &n;
1754cffe588Sopenharmony_ci+  args[3] = &uc;
1764cffe588Sopenharmony_ci+  args[4] = &sc;
1774cffe588Sopenharmony_ci+  args[5] = &us;
1784cffe588Sopenharmony_ci+  args[6] = &ss;
1794cffe588Sopenharmony_ci+  args[7] = &ui;
1804cffe588Sopenharmony_ci+  args[8] = &si;
1814cffe588Sopenharmony_ci+  args[9] = &ul;
1824cffe588Sopenharmony_ci+  args[10] = &sl;
1834cffe588Sopenharmony_ci+  args[11] = &f1;
1844cffe588Sopenharmony_ci+  args[12] = &d1;
1854cffe588Sopenharmony_ci+  args[13] = NULL;
1864cffe588Sopenharmony_ci+
1874cffe588Sopenharmony_ci+  ffi_call(&cif, FFI_FN(test_fn), &res, args);
1884cffe588Sopenharmony_ci+  /* { dg-output "1 2.000000 uc=9 sc=10 11 12 13 14 15 16 2.120000 3.130000" } */
1894cffe588Sopenharmony_ci+  printf("res: %d\n", (int) res);
1904cffe588Sopenharmony_ci+  /* { dg-output "\nres: 42" } */
1914cffe588Sopenharmony_ci+  CHECK(res == 42);
1924cffe588Sopenharmony_ci+
1934cffe588Sopenharmony_ci+  return 0;
1944cffe588Sopenharmony_ci+}
1954cffe588Sopenharmony_ci-- 
1964cffe588Sopenharmony_ci2.23.0
1974cffe588Sopenharmony_ci