mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
pidl: Correct string handling to use talloc and be in common
The previous string handling assumed the python variables referenced by PyString_AS_STRING had infinite life. When they were re-used the C structure started to point at unexpected things. We now check correctly for Unicode in every case, and we always duplicate the string with talloc_strdup() Signed-off-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
This commit is contained in:
parent
9e2c1f72e0
commit
f6c79072ca
@ -960,6 +960,55 @@ sub assign($$$)
|
||||
}
|
||||
}
|
||||
|
||||
sub ConvertStringFromPythonData($$$$$)
|
||||
{
|
||||
my ($self, $mem_ctx, $py_var, $target, $fail) = @_;
|
||||
|
||||
$self->pidl("{");
|
||||
$self->indent;
|
||||
$self->pidl("const char *test_str;");
|
||||
$self->pidl("const char *talloc_str;");
|
||||
$self->pidl("PyObject *unicode = NULL;");
|
||||
$self->pidl("if (PyUnicode_Check($py_var)) {");
|
||||
$self->indent;
|
||||
# FIXME: Use Unix charset setting rather than utf-8
|
||||
$self->pidl("unicode = PyUnicode_AsEncodedString($py_var, \"utf-8\", \"ignore\");");
|
||||
$self->pidl("if (unicode == NULL) {");
|
||||
$self->indent;
|
||||
$self->pidl("PyErr_NoMemory();");
|
||||
$self->pidl("$fail");
|
||||
$self->deindent;
|
||||
$self->pidl("}");
|
||||
|
||||
$self->pidl("test_str = PyString_AS_STRING(unicode);");
|
||||
$self->deindent;
|
||||
$self->pidl("} else if (PyString_Check($py_var)) {");
|
||||
$self->indent;
|
||||
$self->pidl("test_str = PyString_AS_STRING($py_var);");
|
||||
$self->deindent;
|
||||
$self->pidl("} else {");
|
||||
$self->indent;
|
||||
$self->pidl("PyErr_Format(PyExc_TypeError, \"Expected string or unicode object, got %s\", Py_TYPE($py_var)->tp_name);");
|
||||
$self->pidl("$fail");
|
||||
$self->deindent;
|
||||
$self->pidl("}");
|
||||
$self->pidl("talloc_str = talloc_strdup($mem_ctx, test_str);");
|
||||
$self->pidl("if (unicode != NULL) {");
|
||||
$self->indent;
|
||||
$self->pidl("Py_DECREF(unicode);");
|
||||
$self->deindent;
|
||||
$self->pidl("}");
|
||||
$self->pidl("if (talloc_str == NULL) {");
|
||||
$self->indent;
|
||||
$self->pidl("PyErr_NoMemory();");
|
||||
$self->pidl("$fail");
|
||||
$self->deindent;
|
||||
$self->pidl("}");
|
||||
$self->pidl("$target = talloc_str;");
|
||||
$self->deindent;
|
||||
$self->pidl("}");
|
||||
}
|
||||
|
||||
sub ConvertObjectFromPythonData($$$$$$;$)
|
||||
{
|
||||
my ($self, $mem_ctx, $cvar, $ctype, $target, $fail, $location) = @_;
|
||||
@ -1114,33 +1163,17 @@ sub ConvertObjectFromPythonData($$$$$$;$)
|
||||
}
|
||||
|
||||
if ($actual_ctype->{TYPE} eq "SCALAR" and
|
||||
($actual_ctype->{NAME} eq "string" or $actual_ctype->{NAME} eq "nbt_string" or $actual_ctype->{NAME} eq "nbt_name" or $actual_ctype->{NAME} eq "wrepl_nbt_name")) {
|
||||
$self->pidl("$target = talloc_strdup($mem_ctx, PyString_AS_STRING($cvar));");
|
||||
return;
|
||||
}
|
||||
|
||||
if ($actual_ctype->{TYPE} eq "SCALAR" and ($actual_ctype->{NAME} eq "dns_string" or $actual_ctype->{NAME} eq "dns_name")) {
|
||||
$self->pidl("$target = talloc_strdup($mem_ctx, PyString_AS_STRING($cvar));");
|
||||
return;
|
||||
}
|
||||
|
||||
if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "ipv4address") {
|
||||
$self->pidl("$target = PyString_AS_STRING($cvar);");
|
||||
return;
|
||||
}
|
||||
|
||||
if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "ipv6address") {
|
||||
$self->pidl("$target = PyString_AsString($cvar);");
|
||||
return;
|
||||
}
|
||||
|
||||
if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "dnsp_name") {
|
||||
$self->pidl("$target = PyString_AS_STRING($cvar);");
|
||||
return;
|
||||
}
|
||||
|
||||
if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "dnsp_string") {
|
||||
$self->pidl("$target = PyString_AS_STRING($cvar);");
|
||||
($actual_ctype->{NAME} eq "string"
|
||||
or $actual_ctype->{NAME} eq "nbt_string"
|
||||
or $actual_ctype->{NAME} eq "nbt_name"
|
||||
or $actual_ctype->{NAME} eq "wrepl_nbt_name"
|
||||
or $actual_ctype->{NAME} eq "dns_string"
|
||||
or $actual_ctype->{NAME} eq "dnsp_string"
|
||||
or $actual_ctype->{NAME} eq "dns_name"
|
||||
or $actual_ctype->{NAME} eq "ipv4address"
|
||||
or $actual_ctype->{NAME} eq "ipv6address"
|
||||
or $actual_ctype->{NAME} eq "dnsp_name")) {
|
||||
$self->ConvertStringFromPythonData($mem_ctx, $cvar, $target, $fail);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1218,21 +1251,7 @@ sub ConvertObjectFromPythonLevel($$$$$$$$)
|
||||
}
|
||||
|
||||
if (is_charset_array($e, $l)) {
|
||||
$self->pidl("if (PyUnicode_Check($py_var)) {");
|
||||
$self->indent;
|
||||
# FIXME: Use Unix charset setting rather than utf-8
|
||||
$self->pidl($var_name . " = PyString_AS_STRING(PyUnicode_AsEncodedString($py_var, \"utf-8\", \"ignore\"));");
|
||||
$self->deindent;
|
||||
$self->pidl("} else if (PyString_Check($py_var)) {");
|
||||
$self->indent;
|
||||
$self->pidl($var_name . " = PyString_AS_STRING($py_var);");
|
||||
$self->deindent;
|
||||
$self->pidl("} else {");
|
||||
$self->indent;
|
||||
$self->pidl("PyErr_Format(PyExc_TypeError, \"Expected string or unicode object, got %s\", Py_TYPE($py_var)->tp_name);");
|
||||
$self->pidl("$fail");
|
||||
$self->deindent;
|
||||
$self->pidl("}");
|
||||
$self->ConvertStringFromPythonData($mem_ctx, $py_var, $var_name, $fail);
|
||||
} else {
|
||||
my $counter = "$e->{NAME}_cntr_$l->{LEVEL_INDEX}";
|
||||
$self->pidl("PY_CHECK_TYPE(&PyList_Type, $py_var, $fail);");
|
||||
|
Loading…
Reference in New Issue
Block a user