diff -r 4c0affb3a7fc Lib/msilib/__init__.py --- a/Lib/msilib/__init__.py Sat Mar 26 19:17:15 2011 +0800 +++ b/Lib/msilib/__init__.py Sun Mar 27 12:03:36 2011 +0800 @@ -283,19 +283,36 @@ [(feature.id, component)]) def make_short(self, file): - parts = file.split(".") - if len(parts)>1: - suffix = parts[-1].upper() - else: - suffix = None - prefix = parts[0].upper() - if len(prefix) <= 8 and (not suffix or len(suffix)<=3): + disallow_chars = set(file).intersection(r'/\?|><:*"') + if disallow_chars: + # remove disallowed characters + for c in disallow_chars: + file = file.replace(c, "") + + replace_chars = set(file).intersection('+,;=[]') + if replace_chars: + # replace chars with underscore + for c in replace_chars: + file = file.replace(c, '_') + + prefix, suffix = os.path.splitext(file.upper()) + # remove extension separator character + suffix = suffix[1:] + + if not (disallow_chars or replace_chars or + '.' in prefix or ' ' in prefix or + prefix=="" or len(prefix)>8 or len(suffix)>3): if suffix: file = prefix+"."+suffix else: file = prefix assert file not in self.short_names else: + prefix = prefix.replace(".", "") + prefix = prefix.replace(" ", "") + if not prefix: + prefix = suffix + suffix = "" prefix = prefix[:6] if suffix: suffix = suffix[:3] diff -r 4c0affb3a7fc Lib/msilib/test/test___init__.py --- a/Lib/msilib/test/test___init__.py Sat Mar 26 19:17:15 2011 +0800 +++ b/Lib/msilib/test/test___init__.py Sun Mar 27 12:03:36 2011 +0800 @@ -43,6 +43,92 @@ self.assertEqual ( msilib.make_id(".s\x82o?*+rt"), "_.s_o___rt") +class Test_make_short(unittest.TestCase): + #http://msdn.microsoft.com/en-us/library/aa368590(v=vs.85).aspx + """Short and long file names must not contain the following characters: + slash (/) or (\) + question mark (?) + vertical bar (|) + right angle bracket (>) + left angle bracket (<) + colon (:) + asterisk (*) + quotation mark (") + + In addition, short file names must not contain the following characters: + plus sign (+) + comma (,) + semicolon (;) + equals sign (=) + left square bracket ([) + right square bracket (]) + + No space is allowed preceding the vertical bar (|) separator for the + short file name/long file name syntax. Short file names may not include + a space, although a long file name may. A space can exist after the + separator only if the long file name of the file name begins with the + space. No full-path syntax is allowed. + """ + + def setUp(self): + self.original_add_data_func = msilib.add_data + msilib.add_data = lambda db, t, v: None + + def tearDown(self): + msilib.add_data = self.original_add_data_func + + def test_simple(self): + # no short names already stored + test_dir = msilib.Directory(0, 0, 0, 0, "dir", 0) + self.assertEqual(test_dir.make_short("t\x82st"), "T\x82ST") + self.assertEqual( + test_dir.make_short("filename.ext"), "FILENAME.EXT") + self.assertEqual(test_dir.make_short("A"), "A") + + def test_shortening_required(self): + # no short names already stored + test_dir = msilib.Directory(0, 0, 0, 0, "dir", 0) + self.assertEqual(test_dir.make_short("with spc.txt"), "WITHSP~1.TXT") + self.assertEqual(test_dir.make_short("txt.longext"), "TXT~1.LON") + self.assertEqual(test_dir.make_short("LongFiles"), "LONGFI~1") + + self.assertEqual(test_dir.make_short("aixc++"), "AIXC__~1") + self.assertEqual(test_dir.make_short(".buildinfo"), "BUILDI~1") + self.assertEqual(test_dir.make_short("py.~1.5.~"), "PY~15~1.~") + self.assertEqual(test_dir.make_short("2.dots.TXT"), "2DOTS~1.TXT") + + def test_avoid_duplicates(self): + test_dir = msilib.Directory(0, 0, 0, 0, "dir", 0) + self.assertEqual(test_dir.make_short("with sp0.txt"), "WITHSP~1.TXT") + self.assertEqual(test_dir.make_short("with sp1.txt"), "WITHSP~2.TXT") + self.assertEqual(test_dir.make_short("with sp2.txt"), "WITHSP~3.TXT") + self.assertEqual(test_dir.make_short("with sp3.txt"), "WITHSP~4.TXT") + self.assertEqual(test_dir.make_short("with sp4.txt"), "WITHSP~5.TXT") + self.assertEqual(test_dir.make_short("with sp5.txt"), "WITHSP~6.TXT") + self.assertEqual(test_dir.make_short("with sp6.txt"), "WITHSP~7.TXT") + self.assertEqual(test_dir.make_short("with sp7.txt"), "WITHSP~8.TXT") + self.assertEqual(test_dir.make_short("with sp8.txt"), "WITHSP~9.TXT") + self.assertEqual(test_dir.make_short("with sp9.txt"), "WITHS~10.TXT") + self.assertEqual(test_dir.make_short("with sp0.txt1"), "WITHS~11.TXT") + self.assertEqual(test_dir.make_short("with sb0.txt"), "WITHSB~1.TXT") + + def test_bug_7639(self): + test_dir = msilib.Directory(0, 0, 0, 0, "dir", 0) + self.assertEqual(test_dir.make_short("data.seq.one.dat"), "DATASE~1.DAT") + self.assertEqual(test_dir.make_short("data.seq.two.dat"), "DATASE~2.DAT") + + def test_strange_make_short_with_tilde(self): + test_dir = msilib.Directory(0, 0, 0, 0, "dir", 0) + self.assertEqual(test_dir.make_short("data~1.dat"), "DATA~1.DAT") + self.assertEqual(test_dir.make_short("data.database"), "DATA~2.DAT") + + def test_strange_make_short_with_tilde2(self): + test_dir = msilib.Directory(0, 0, 0, 0, "dir", 0) + self.assertEqual(test_dir.make_short("data.database"), "DATA~1.DAT") + self.assertRaises( + AssertionError, test_dir.make_short, "data~1.dat") + + if __name__ == "__main__": unittest.main()