changeset 62:4a9f6c7c09c1 default tip

- fix inccorect overflow errors for int (and long on LLP64 systems)
author Tassilo Philipp
date Sat, 18 May 2024 15:33:54 +0200
parents c5a69c454963
children
files python/pydc/pydc.c python/pydc/setup.py
diffstat 2 files changed, 43 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/python/pydc/pydc.c	Mon Apr 03 19:06:07 2023 +0200
+++ b/python/pydc/pydc.c	Sat May 18 15:33:54 2024 +0200
@@ -239,6 +239,36 @@
 	return po;
 }
 
+static inline PyObject* py2dcint(DCint* i, PyObject* po, int u, int pos)
+{
+	long long ll;
+	if ( !DcPyInt_Check(po) )
+		return PyErr_Format( PyExc_RuntimeError, "arg %d - expecting an int", pos );
+	ll = (DClonglong) PyLong_AsLongLong(po);
+	if (u && (ll < 0 || ll > UINT_MAX))
+		return PyErr_Format( PyExc_RuntimeError, "arg %lld out of range - expecting 0 <= arg <= %ld, got %lld", pos, UINT_MAX, ll );
+	if (!u && (ll < INT_MIN || ll > INT_MAX))
+		return PyErr_Format( PyExc_RuntimeError, "arg %lld out of range - expecting %ld <= arg <= %ld, got %lld", pos, INT_MIN, INT_MAX, ll );
+
+	*i = (DCint)ll;
+	return po;
+}
+
+static inline PyObject* py2dclong(DClong* l, PyObject* po, int u, int pos)
+{
+	long long ll;
+	if ( !DcPyInt_Check(po) )
+		return PyErr_Format( PyExc_RuntimeError, "arg %d - expecting an int", pos );
+	ll = (DClonglong) PyLong_AsLongLong(po);
+	if (u && (ll < 0 || ll > ULONG_MAX))  //@@@ on lp64, this is a bad comparison
+		return PyErr_Format( PyExc_RuntimeError, "arg %lld out of range - expecting 0 <= arg <= %ld, got %lld", pos, ULONG_MAX, ll );
+	if (!u && (ll < LONG_MIN || ll > LONG_MAX))
+		return PyErr_Format( PyExc_RuntimeError, "arg %lld out of range - expecting %ld <= arg <= %ld, got %lld", pos, LONG_MIN, LONG_MAX, ll );
+
+	*l = (DClong)ll;
+	return po;
+}
+
 static inline PyObject* py2dclonglong(DClonglong* ll, PyObject* po, int pos)
 {
 #if PY_MAJOR_VERSION < 3
@@ -390,17 +420,21 @@
 
 			case DC_SIGCHAR_INT:
 			case DC_SIGCHAR_UINT:
-				if ( !DcPyInt_Check(po) )
-					return PyErr_Format( PyExc_RuntimeError, "arg %d - expecting an int", pos );
-				dcArgInt(gpCall, (DCint) DcPyInt_AS_LONG(po));
-				break;
+				{
+					DCint i;
+					if(!py2dcint(&i, po, ch == DC_SIGCHAR_UINT, pos))
+						return NULL;
+					dcArgInt(gpCall, i);
+				}
 
 			case DC_SIGCHAR_LONG:
 			case DC_SIGCHAR_ULONG:
-				if ( !DcPyInt_Check(po) )
-					return PyErr_Format( PyExc_RuntimeError, "arg %d - expecting an int", pos );
-				dcArgLong(gpCall, (DClong) PyLong_AsLong(po));
-				break;
+				{
+					DClong l;
+					if(!py2dclong(&l, po, ch == DC_SIGCHAR_ULONG, pos))
+						return NULL;
+					dcArgLong(gpCall, l);
+				}
 
 			case DC_SIGCHAR_LONGLONG:
 			case DC_SIGCHAR_ULONGLONG:
--- a/python/pydc/setup.py	Mon Apr 03 19:06:07 2023 +0200
+++ b/python/pydc/setup.py	Sat May 18 15:33:54 2024 +0200
@@ -7,7 +7,7 @@
 
 setup(
   name             = 'pydc'
-, version          = '1.4.0'
+, version          = '1.4.1'
 , author           = 'Daniel Adler, Tassilo Philipp'
 , author_email     = 'dadler@dyncall.org, tphilip@dyncall.org'
 , maintainer       = 'Daniel Adler, Tassilo Philipp'