bpo-1104: msilib.SummaryInfo.GetProperty() truncates the string by one character (GH-4517)
Add one char to MsiSummaryInfoGetProperty() output Based on the patch in bpo-1104 by Anthony Tuininga (atuining) and Mark McMahon (markm).
This commit is contained in:
parent
05e922136a
commit
2de576e16d
|
@ -1,5 +1,5 @@
|
||||||
""" Test suite for the code in msilib """
|
""" Test suite for the code in msilib """
|
||||||
import os.path
|
import os
|
||||||
import unittest
|
import unittest
|
||||||
from test.support import TESTFN, import_module, unlink
|
from test.support import TESTFN, import_module, unlink
|
||||||
msilib = import_module('msilib')
|
msilib = import_module('msilib')
|
||||||
|
@ -42,6 +42,29 @@ class MsiDatabaseTestCase(unittest.TestCase):
|
||||||
)
|
)
|
||||||
self.addCleanup(unlink, db_path)
|
self.addCleanup(unlink, db_path)
|
||||||
|
|
||||||
|
def test_summaryinfo_getproperty_issue1104(self):
|
||||||
|
db, db_path = init_database()
|
||||||
|
try:
|
||||||
|
sum_info = db.GetSummaryInformation(99)
|
||||||
|
title = sum_info.GetProperty(msilib.PID_TITLE)
|
||||||
|
self.assertEqual(title, b"Installation Database")
|
||||||
|
|
||||||
|
sum_info.SetProperty(msilib.PID_TITLE, "a" * 999)
|
||||||
|
title = sum_info.GetProperty(msilib.PID_TITLE)
|
||||||
|
self.assertEqual(title, b"a" * 999)
|
||||||
|
|
||||||
|
sum_info.SetProperty(msilib.PID_TITLE, "a" * 1000)
|
||||||
|
title = sum_info.GetProperty(msilib.PID_TITLE)
|
||||||
|
self.assertEqual(title, b"a" * 1000)
|
||||||
|
|
||||||
|
sum_info.SetProperty(msilib.PID_TITLE, "a" * 1001)
|
||||||
|
title = sum_info.GetProperty(msilib.PID_TITLE)
|
||||||
|
self.assertEqual(title, b"a" * 1001)
|
||||||
|
finally:
|
||||||
|
db = None
|
||||||
|
sum_info = None
|
||||||
|
os.unlink(db_path)
|
||||||
|
|
||||||
def test_database_open_failed(self):
|
def test_database_open_failed(self):
|
||||||
with self.assertRaises(msilib.MSIError) as cm:
|
with self.assertRaises(msilib.MSIError) as cm:
|
||||||
msilib.OpenDatabase('non-existent.msi', msilib.MSIDBOPEN_READONLY)
|
msilib.OpenDatabase('non-existent.msi', msilib.MSIDBOPEN_READONLY)
|
||||||
|
@ -92,7 +115,7 @@ class Test_make_id(unittest.TestCase):
|
||||||
def test_invalid_any_char(self):
|
def test_invalid_any_char(self):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
msilib.make_id(".s\x82ort"), "_.s_ort")
|
msilib.make_id(".s\x82ort"), "_.s_ort")
|
||||||
self.assertEqual (
|
self.assertEqual(
|
||||||
msilib.make_id(".s\x82o?*+rt"), "_.s_o___rt")
|
msilib.make_id(".s\x82o?*+rt"), "_.s_o___rt")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Correctly handle string length in ``msilib.SummaryInfo.GetProperty()`` to
|
||||||
|
prevent it from truncating the last character.
|
29
PC/_msi.c
29
PC/_msi.c
|
@ -555,7 +555,7 @@ summary_getproperty(msiobj* si, PyObject *args)
|
||||||
FILETIME fval;
|
FILETIME fval;
|
||||||
char sbuf[1000];
|
char sbuf[1000];
|
||||||
char *sval = sbuf;
|
char *sval = sbuf;
|
||||||
DWORD ssize = sizeof(sval);
|
DWORD ssize = sizeof(sbuf);
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "i:GetProperty", &field))
|
if (!PyArg_ParseTuple(args, "i:GetProperty", &field))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -563,6 +563,7 @@ summary_getproperty(msiobj* si, PyObject *args)
|
||||||
status = MsiSummaryInfoGetProperty(si->h, field, &type, &ival,
|
status = MsiSummaryInfoGetProperty(si->h, field, &type, &ival,
|
||||||
&fval, sval, &ssize);
|
&fval, sval, &ssize);
|
||||||
if (status == ERROR_MORE_DATA) {
|
if (status == ERROR_MORE_DATA) {
|
||||||
|
ssize++;
|
||||||
sval = malloc(ssize);
|
sval = malloc(ssize);
|
||||||
if (sval == NULL) {
|
if (sval == NULL) {
|
||||||
return PyErr_NoMemory();
|
return PyErr_NoMemory();
|
||||||
|
@ -572,21 +573,29 @@ summary_getproperty(msiobj* si, PyObject *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case VT_I2: case VT_I4:
|
case VT_I2:
|
||||||
return PyLong_FromLong(ival);
|
case VT_I4:
|
||||||
|
result = PyLong_FromLong(ival);
|
||||||
|
break;
|
||||||
case VT_FILETIME:
|
case VT_FILETIME:
|
||||||
PyErr_SetString(PyExc_NotImplementedError, "FILETIME result");
|
PyErr_SetString(PyExc_NotImplementedError, "FILETIME result");
|
||||||
return NULL;
|
result = NULL;
|
||||||
|
break;
|
||||||
case VT_LPSTR:
|
case VT_LPSTR:
|
||||||
result = PyBytes_FromStringAndSize(sval, ssize);
|
result = PyBytes_FromStringAndSize(sval, ssize);
|
||||||
if (sval != sbuf)
|
break;
|
||||||
free(sval);
|
|
||||||
return result;
|
|
||||||
case VT_EMPTY:
|
case VT_EMPTY:
|
||||||
Py_RETURN_NONE;
|
Py_INCREF(Py_None);
|
||||||
|
result = Py_None;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PyErr_Format(PyExc_NotImplementedError, "result of type %d", type);
|
||||||
|
result = NULL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
PyErr_Format(PyExc_NotImplementedError, "result of type %d", type);
|
if (sval != sbuf)
|
||||||
return NULL;
|
free(sval);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
|
|
Loading…
Reference in New Issue