Commit 2de576e1 authored by Tzu-ping Chung's avatar Tzu-ping Chung Committed by Steve Dower

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).
parent 05e92213
""" 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): ...@@ -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): ...@@ -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")
......
Correctly handle string length in ``msilib.SummaryInfo.GetProperty()`` to
prevent it from truncating the last character.
...@@ -555,7 +555,7 @@ summary_getproperty(msiobj* si, PyObject *args) ...@@ -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) ...@@ -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) ...@@ -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*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment