if ($ctype_alias =~ /^(dlong|char|int[0-9]*|time_t)$/x) {
$self->pidl("{");
$self->indent;
- $self->pidl("const long long int_max = ndr_sizeof2intmax(sizeof($target));");
- $self->pidl("const long long int_min = -int_max - 1;");
- $self->pidl("if (PyLong_Check($cvar)) {");
- $self->indent;
- $self->pidl("long long test_var;");
- $self->pidl("test_var = PyLong_AsLongLong($cvar);");
+ $self->pidl("long long ll_value;");
+ $self->pidl("ll_value = ndr_PyLong_AsCheckedLongLong($cvar, sizeof($target));");
$self->pidl("if (PyErr_Occurred() != NULL) {");
$self->indent;
$self->pidl($fail);
$self->deindent;
$self->pidl("}");
- $self->pidl("if (test_var < int_min || test_var > int_max) {");
- $self->indent;
- $self->pidl("PyErr_Format(PyExc_OverflowError, \"Expected type %s or %s within range %lld - %lld, got %lld\",\\");
- $self->pidl(" PyInt_Type.tp_name, PyLong_Type.tp_name, int_min, int_max, test_var);");
- $self->pidl($fail);
- $self->deindent;
- $self->pidl("}");
- $self->pidl("$target = test_var;");
- $self->deindent;
- $self->pidl("} else if (PyInt_Check($cvar)) {");
- $self->indent;
- $self->pidl("long test_var;");
- $self->pidl("test_var = PyInt_AsLong($cvar);");
- $self->pidl("if (test_var < int_min || test_var > int_max) {");
- $self->indent;
- $self->pidl("PyErr_Format(PyExc_OverflowError, \"Expected type %s or %s within range %lld - %lld, got %ld\",\\");
- $self->pidl(" PyInt_Type.tp_name, PyLong_Type.tp_name, int_min, int_max, test_var);");
- $self->pidl($fail);
- $self->deindent;
- $self->pidl("}");
- $self->pidl("$target = test_var;");
- $self->deindent;
- $self->pidl("} else {");
- $self->indent;
- $self->pidl("PyErr_Format(PyExc_TypeError, \"Expected type %s or %s\",\\");
- $self->pidl(" PyInt_Type.tp_name, PyLong_Type.tp_name);");
- $self->pidl($fail);
- $self->deindent;
- $self->pidl("}");
+ $self->pidl("$target = (" . mapTypeName($ctype_alias) . ")ll_value;");
$self->deindent;
$self->pidl("}");
return;
return 0;
}
+
+/*
+ * Confirm the signed python integer fits in the C type
+ * correctly. It is subtly different from the unsigned case
+ * above, so while it looks like a duplicate, it is not
+ * actually a duplicate.
+ */
+static inline long long ndr_PyLong_AsCheckedLongLong(PyObject *py_value,
+ size_t target_size)
+{
+ const long long int_max = ndr_sizeof2intmax(target_size);
+ const long long int_min = -int_max - 1;
+ long long ret_value;
+
+ if (PyLong_Check(py_value)) {
+ long long test_var;
+
+ test_var = PyLong_AsLongLong(py_value);
+ if (PyErr_Occurred() != NULL) {
+ return 0;
+ }
+
+ if (test_var < int_min || test_var > int_max) {
+ PyErr_Format(PyExc_OverflowError,
+ \"Expected type %s or %s within range %lld - %lld, got %lld\",
+ PyInt_Type.tp_name, PyLong_Type.tp_name, int_min, int_max, test_var);
+ return 0;
+ }
+
+ ret_value = test_var;
+
+ return ret_value;
+ }
+
+ if (PyInt_Check(py_value)) {
+ long test_var;
+
+ test_var = PyInt_AsLong(py_value);
+ if (test_var < int_min || test_var > int_max) {
+ PyErr_Format(PyExc_OverflowError,
+ \"Expected type %s or %s within range %lld - %lld, got %ld\",
+ PyInt_Type.tp_name, PyLong_Type.tp_name, int_min, int_max, test_var);
+ return 0;
+ }
+
+ ret_value = test_var;
+
+ return ret_value;
+ }
+
+ PyErr_Format(PyExc_TypeError,
+ \"Expected type %s or %s within range %lld - %lld\",
+ PyInt_Type.tp_name, PyLong_Type.tp_name, int_min, int_max);
+ return 0;
+}
+
");
foreach my $x (@$ndr) {