From 9cff4cfb7592f1af008bc8c19b5c6140795278bc Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Mar 2023 12:27:27 -0500 Subject: [PATCH 001/335] Update module_base.py --- vbaProjectCompiler/Models/Entities/module_base.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/vbaProjectCompiler/Models/Entities/module_base.py b/vbaProjectCompiler/Models/Entities/module_base.py index e6676e25d..a0cf1bf78 100644 --- a/vbaProjectCompiler/Models/Entities/module_base.py +++ b/vbaProjectCompiler/Models/Entities/module_base.py @@ -27,6 +27,18 @@ def __init__(self, name): self._fileSize = 0 self._size = 0 + # GUIDs + self._guid = [] + + def set_guid(self, guid): + if isinstance(guid, list): + self._guid = guid + else: + self._guid = [guid] + + def add_guid(self, guid): + self._guid += guid + def set_cache(self, cache): self._cache = cache From 7f898c43e8148b253b19abda0e2982c2f7913292 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Mar 2023 12:33:35 -0500 Subject: [PATCH 002/335] Update test_doc_module.py --- tests/Unit/Models/Entities/test_doc_module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_doc_module.py b/tests/Unit/Models/Entities/test_doc_module.py index 133087dff..3aa4a7f11 100644 --- a/tests/Unit/Models/Entities/test_doc_module.py +++ b/tests/Unit/Models/Entities/test_doc_module.py @@ -11,7 +11,7 @@ def test_normalize(): cache.module_cookie = 0xB81C cache.misc = [0x0316, 0x0123, 0x88, 8, 0x18, "00000000", 1] guid = uuid.UUID('0002081900000000C000000000000046') - cache.guid = bytes(("0{" + str(guid) + "}").upper(), "utf_16_le") + cache.guid = [guid] indirect_table = ("02 80 FE FF FF FF FF FF 20 00 00 00 FF FF FF FF", "30 00 00 00 02 01 FF FF 00 00 00 00 00 00 00 00", From eaf1863bacc57c3ca524ad83254c3af998bd4b0e Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Mar 2023 21:04:25 -0500 Subject: [PATCH 003/335] Update dirStream.py --- vbaProjectCompiler/Views/dirStream.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/vbaProjectCompiler/Views/dirStream.py b/vbaProjectCompiler/Views/dirStream.py index 7b9316aa4..685fd7ef7 100644 --- a/vbaProjectCompiler/Views/dirStream.py +++ b/vbaProjectCompiler/Views/dirStream.py @@ -1,4 +1,5 @@ import struct +from ms_ovba_compression import MsOvba from vbaProjectCompiler.Models.Fields.idSizeField import IdSizeField from vbaProjectCompiler.Models.Fields.doubleEncodedString import ( DoubleEncodedString @@ -69,3 +70,10 @@ def to_bytes(self): output += record.pack(codePageName, endien) output += struct.pack(packSymbol + "HI", 16, 0) return output + + def write_file(self): + bin_f = open("dir.bin", "wb") + ms_ovba = MsOvba() + compressed = ms_ovba.compress(self.to_bytes()) + bin_f.write(compressed) + bin_f.close() From 7a967fb3b50541146a2f6a772a513168fdda77a7 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Mon, 6 Mar 2023 08:06:48 -0500 Subject: [PATCH 004/335] Write all views (#99) * Write Views --- tests/Functional/test_dirObject.py | 4 +-- tests/Functional/test_fullFile.py | 28 +++++++++++++++++-- tests/Unit/Models/Entities/test_doc_module.py | 2 -- tests/Views/test_projectWm.py | 4 +-- tests/Views/test_vba_project.py | 6 ++-- vbaProjectCompiler/Views/dirStream.py | 2 +- vbaProjectCompiler/Views/project.py | 5 ++++ vbaProjectCompiler/Views/projectWm.py | 7 ++++- vbaProjectCompiler/Views/vba_Project.py | 7 ++++- vbaProjectCompiler/vbaProject.py | 12 ++++++-- 10 files changed, 60 insertions(+), 17 deletions(-) diff --git a/tests/Functional/test_dirObject.py b/tests/Functional/test_dirObject.py index 66eee039f..4078bb4d4 100644 --- a/tests/Functional/test_dirObject.py +++ b/tests/Functional/test_dirObject.py @@ -65,14 +65,14 @@ def test_dirStream(): module_cache.cookie = this_workbook.cookie.value guid = uuid.UUID('0002081900000000C000000000000046') this_workbook.set_guid(guid) - module_cache.guid = bytes(("0{" + str(guid) + "}").upper(), "utf_16_le") + module_cache.guid = [guid] this_workbook.set_cache(module_cache.to_bytes()) sheet1 = DocModule("Sheet1") sheet1.cookie.value = 0x9B9A module_cache.cookie = sheet1.cookie.value guid = uuid.UUID('0002082000000000C000000000000046') - module_cache.guid = bytes(("0{" + str(guid) + "}").upper(), "utf_16_le") + module_cache.guid = [guid] sheet1.set_guid(guid) sheet1.set_cache(module_cache.to_bytes()) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 85a9449d5..4a11fda8b 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -1,3 +1,5 @@ +import os +import pytest import struct import unittest.mock import uuid @@ -22,6 +24,28 @@ def randint(cls, param1, param2): return cls._rand.pop(0) +@pytest.fixture(autouse=True) +def run_around_tests(): + # Code that will run before your test, for example: + + # A test function will be run at this point + yield + # Code that will run after your test + root = "vbaProjectCompiler/blank_files/" + root2 = "tests/blank/" + names = [root + "ThisWorkbook.cls", root + "Sheet1.cls", + root2 + "Module1.bas"] + remove_module(names) + names = ["dir.bin", "projectWm.bin", "project.bin", "vba_project.bin"] + map(os.remove, names) + + +def remove_module(names): + for name in names: + os.remove(name + ".new") + os.remove(name + ".bin") + + def module_matches_bin(module_path, cache_size, bin_path, @@ -85,7 +109,7 @@ def test_fullFile(): this_workbook.cookie.value = 0xB81C module_cache.module_cookie = 0xB81C guid = uuid.UUID("0002081900000000C000000000000046") - module_cache.guid = bytes(("0{" + str(guid) + "}").upper(), "utf_16_le") + module_cache.guid = [guid] this_workbook.set_guid(guid) module_path = "vbaProjectCompiler/blank_files/ThisWorkbook.cls" this_workbook.add_file(module_path) @@ -96,7 +120,7 @@ def test_fullFile(): sheet1.cookie.value = 0x9B9A module_cache.module_cookie = 0x9B9A guid = uuid.UUID("0002082000000000C000000000000046") - module_cache.guid = bytes(("0{" + str(guid) + "}").upper(), "utf_16_le") + module_cache.guid = [guid] sheet1.set_guid(guid) module_path = "vbaProjectCompiler/blank_files/Sheet1.cls" sheet1.add_file(module_path) diff --git a/tests/Unit/Models/Entities/test_doc_module.py b/tests/Unit/Models/Entities/test_doc_module.py index 3aa4a7f11..fe32951c9 100644 --- a/tests/Unit/Models/Entities/test_doc_module.py +++ b/tests/Unit/Models/Entities/test_doc_module.py @@ -1,4 +1,3 @@ -import os import uuid from ms_ovba_compression.ms_ovba import MsOvba from ms_pcode_assembler.module_cache import ModuleCache @@ -25,7 +24,6 @@ def test_normalize(): module = DocModule("foo") path1 = "vbaProjectCompiler/blank_files/ThisWorkbook.cls" - os.remove(path1 + ".new") module.add_file(path1) module.cookie.value = 0xB81C guid = uuid.UUID('0002081900000000C000000000000046') diff --git a/tests/Views/test_projectWm.py b/tests/Views/test_projectWm.py index d0e92f036..1ac72f687 100644 --- a/tests/Views/test_projectWm.py +++ b/tests/Views/test_projectWm.py @@ -17,6 +17,6 @@ def test_projectWm(): + b'\x00o\x00o\x00k\x00\x00\x00Sheet1\x00S\x00h\x00e\x00e\x00' + b't\x001\x00\x00\x00Module1\x00M\x00o\x00d\x00u\x00l\x00e' + b'\x001\x00\x00\x00\x00\x00') - result = projectWm.toBytes() + result = projectWm.to_bytes() assert len(result) == 86 - assert projectWm.toBytes() == expected + assert result == expected diff --git a/tests/Views/test_vba_project.py b/tests/Views/test_vba_project.py index 0f18a0e37..78ca5c57d 100644 --- a/tests/Views/test_vba_project.py +++ b/tests/Views/test_vba_project.py @@ -2,12 +2,12 @@ from vbaProjectCompiler.Views.vba_Project import Vba_Project -def test_projectWm(): +def test_vba_project(): vbaProject = VbaProject() vba_Project = Vba_Project(vbaProject) expected = b'\xCC\x61\xFF\xFF\x00\x03\x00' - assert vba_Project.toBytes() == expected + assert vba_Project.to_bytes() == expected vbaProject.setPerformanceCache(b'\x00\x01\x02\x03') vbaProject.setPerformanceCacheVersion(0x00B5) expected = b'\xCC\x61\xB5\x00\x00\x03\x00\x00\x01\x02\x03' - assert vba_Project.toBytes() == expected + assert vba_Project.to_bytes() == expected diff --git a/vbaProjectCompiler/Views/dirStream.py b/vbaProjectCompiler/Views/dirStream.py index 685fd7ef7..e7ea8baee 100644 --- a/vbaProjectCompiler/Views/dirStream.py +++ b/vbaProjectCompiler/Views/dirStream.py @@ -1,5 +1,5 @@ import struct -from ms_ovba_compression import MsOvba +from ms_ovba_compression.ms_ovba import MsOvba from vbaProjectCompiler.Models.Fields.idSizeField import IdSizeField from vbaProjectCompiler.Models.Fields.doubleEncodedString import ( DoubleEncodedString diff --git a/vbaProjectCompiler/Views/project.py b/vbaProjectCompiler/Views/project.py index 082d9c3f9..690299357 100644 --- a/vbaProjectCompiler/Views/project.py +++ b/vbaProjectCompiler/Views/project.py @@ -61,6 +61,11 @@ def to_bytes(self): result += eol return result + def write_file(self): + bin_f = open("project.bin", "wb") + bin_f.write(self.to_bytes()) + bin_f.close() + def _attr(self, name, value): codePageName = self.project.getCodePageName() eol = b'\x0D\x0A' diff --git a/vbaProjectCompiler/Views/projectWm.py b/vbaProjectCompiler/Views/projectWm.py index 76f60a57c..3922ca66b 100644 --- a/vbaProjectCompiler/Views/projectWm.py +++ b/vbaProjectCompiler/Views/projectWm.py @@ -5,7 +5,7 @@ class ProjectWm: def __init__(self, project): self.project = project - def toBytes(self): + def to_bytes(self): output = b'' for module in self.project.modules: output += (bytes(module.modName.value, 'ascii') @@ -14,3 +14,8 @@ def toBytes(self): + b'\x00\x00') output += b'\x00\x00' return output + + def write_file(self): + bin_f = open("project.bin", "wb") + bin_f.write(self.to_bytes()) + bin_f.close() diff --git a/vbaProjectCompiler/Views/vba_Project.py b/vbaProjectCompiler/Views/vba_Project.py index 9543458d9..eeb2dad6d 100644 --- a/vbaProjectCompiler/Views/vba_Project.py +++ b/vbaProjectCompiler/Views/vba_Project.py @@ -8,7 +8,7 @@ class Vba_Project: def __init__(self, project): self.project = project - def toBytes(self): + def to_bytes(self): endienSymbol = '<' if self.project.endien == 'little' else '>' format = endienSymbol + "HHBH" output = b'' @@ -20,3 +20,8 @@ def toBytes(self): output += struct.pack(format, reserved1, cache_version, reserved2, reserved3) return output + self.project.getPerformanceCache() + + def write_file(self): + bin_f = open("vba_project.bin", "wb") + bin_f.write(self.to_bytes()) + bin_f.close() diff --git a/vbaProjectCompiler/vbaProject.py b/vbaProjectCompiler/vbaProject.py index c22da84d0..8840fb6a9 100644 --- a/vbaProjectCompiler/vbaProject.py +++ b/vbaProjectCompiler/vbaProject.py @@ -2,10 +2,10 @@ # from ms_cfb.Models.Directories.storage_directory import StorageDirectory # from ms_cfb.Models.Directories.stream_directory import StreamDirectory -# from vbaProjectCompiler.Views.dirStream import DirStream +from vbaProjectCompiler.Views.dirStream import DirStream # from vbaProjectCompiler.Views.vba_Project import Vba_Project -# from vbaProjectCompiler.Views.project import Project -# from vbaProjectCompiler.Views.projectWm import ProjectWm +from vbaProjectCompiler.Views.project import Project +from vbaProjectCompiler.Views.projectWm import ProjectWm class VbaProject: @@ -89,6 +89,12 @@ def addReference(self, ref): def _create_binary_files(self): for module in self.modules: module.write_file() + dir = DirStream(self) + dir.write_file() + project = Project(self) + project.write_file() + projectWm = ProjectWm(self) + projectWm.write_file() # views = ("_VBA_PROJECT", "dir", "projectWm", "Project") # Create views and write From e9a08a1c38f7b5e9b4be8827dbce866bf74d32b3 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Mon, 6 Mar 2023 08:09:33 -0500 Subject: [PATCH 005/335] Update doc_module.py --- vbaProjectCompiler/Models/Entities/doc_module.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/vbaProjectCompiler/Models/Entities/doc_module.py b/vbaProjectCompiler/Models/Entities/doc_module.py index 9538e5461..88fa9b6ba 100644 --- a/vbaProjectCompiler/Models/Entities/doc_module.py +++ b/vbaProjectCompiler/Models/Entities/doc_module.py @@ -19,15 +19,6 @@ def toProjectModuleString(self): return ("Document=" + self.modName.value + "/&H" + self.docTlibVer.to_bytes(4, "big").hex()) - def set_guid(self, guid): - if isinstance(guid, list): - self._guid = guid - else: - self._guid = [guid] - - def add_guid(self, guid): - self._guid += guid - def normalize_file(self): f = open(self._file_path, "r") new_f = open(self._file_path + ".new", "a+", newline='\r\n') From 6c96c3991b4f46475d78544206c9d7a6f37f525d Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 16 Mar 2023 10:57:32 -0400 Subject: [PATCH 006/335] Create project.uml --- tests/blank/project.uml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 tests/blank/project.uml diff --git a/tests/blank/project.uml b/tests/blank/project.uml new file mode 100644 index 000000000..8d84cafe4 --- /dev/null +++ b/tests/blank/project.uml @@ -0,0 +1,19 @@ +@startuml +digraph G { + "Root Entry" [fillcolor="red" style="filled" fontcolor="white"]; + VBA [fillcolor="red" style="filled" fontcolor="white"]; + PROJECTwm [fillcolor="red" style="filled" fontcolor="white"] + dir [fillcolor="red" style="filled" fontcolor="white"] + _VBA_PROJECT [fillcolor="red" style="filled" fontcolor="white"] + "Root Entry" -> PROJECT + PROJECT -> VBA + PROJECT -> PROJECTwm + VBA -> Module1 + Module1 -> Sheet1 + Module1 -> ThisWorkbook + Sheet1 -> dir + Sheet1 -> nil + ThisWorkbook -> _VBA_PROJECT + ThisWorkbook -> nil +} +@enduml From dd1fe9b8e084a416d9e64fb49c8eb54695fa203d Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 1 Apr 2023 11:06:09 -0400 Subject: [PATCH 007/335] Pep (#101) * Update requirements_dev.txt * Update test_dirObject.py * Update test_fullFile.py * Update dirStream.py * Update dirStream.py * Update vba_Project.py * Update test_dirObject.py * Update test_dirObject.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_libidReference.py * Update test_libidReference.py * Update test_project.py * Update test_projectWm.py * Update test_projectWm.py * Update test_projectWm.py * Update test_projectWm.py * Update test_vba_project.py * Update test_vba_project.py * Delete test_datetime.py * Update packedData.py * Update doc_module.py * Update and rename vba_Project.py to project_view.py * Update test_vba_project.py * Update vbaProject.py * Update referenceRecord.py * Update referenceRecord.py * Update vbaProject.py * Update project_view.py * Update test_fullFile.py * Update vbaProject.py * Update vbaProject.py * Update test_fullFile.py * Update dirStream.py * Update test_project.py * Update test_vba_project.py * Update vbaProject.py * Update project.py * Update vbaProject.py * Update test_dirObject.py * Update vbaProject.py * Update test_fullFile.py * Update test_dirObject.py * Update test_projectWm.py * Update test_project.py * Update vbaProject.py * Update module_base.py * Update test_project.py * Update project.py * Update test_fullFile.py * Update doc_module.py * Update module_base.py * Update module_base.py * Update referenceRecord.py * Update referenceRecord.py * Update referenceRecord.py * Update referenceRecord.py * Update referenceRecord.py * Update doubleEncodedString.py * Update referenceRecord.py * Update referenceRecord.py * Update idSizeField.py * Update libidReference.py * Update project.py * Update test_project.py * Update idSizeField.py * Update module_base.py * Update test_fullFile.py * Update test_dirObject.py * Update test_dirObject.py * Update vbaProject.py * Update project.py * Update dirStream.py * Update project.py * Update project_view.py * Update project.py --- requirements_dev.txt | 1 + tests/Functional/test_dirObject.py | 44 +++++----- tests/Functional/test_fullFile.py | 54 ++++++------- .../Unit/Models/Fields/test_libidReference.py | 10 +-- tests/Views/test_project.py | 24 +++--- tests/Views/test_projectWm.py | 16 ++-- tests/Views/test_vba_project.py | 16 ++-- tests/test_datetime.py | 16 ---- .../Models/Entities/doc_module.py | 12 +-- .../Models/Entities/module_base.py | 51 +++++++----- .../Models/Entities/referenceRecord.py | 23 +++--- .../Models/Fields/doubleEncodedString.py | 14 ++-- .../Models/Fields/idSizeField.py | 34 ++++---- .../Models/Fields/libidReference.py | 32 ++++---- .../Models/Fields/packedData.py | 8 +- vbaProjectCompiler/Views/dirStream.py | 60 +++++++------- vbaProjectCompiler/Views/project.py | 31 +++---- .../Views/{vba_Project.py => project_view.py} | 16 ++-- vbaProjectCompiler/vbaProject.py | 81 ++++++++++--------- 19 files changed, 272 insertions(+), 271 deletions(-) delete mode 100644 tests/test_datetime.py rename vbaProjectCompiler/Views/{vba_Project.py => project_view.py} (54%) diff --git a/requirements_dev.txt b/requirements_dev.txt index 30c969c3a..8fc00bff8 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -2,3 +2,4 @@ pytest pytest-cov pytest-mock coveralls +pep8-naming diff --git a/tests/Functional/test_dirObject.py b/tests/Functional/test_dirObject.py index 4078bb4d4..22a7aac92 100644 --- a/tests/Functional/test_dirObject.py +++ b/tests/Functional/test_dirObject.py @@ -10,7 +10,7 @@ from vbaProjectCompiler.Models.Entities.referenceRecord import ReferenceRecord -def test_dirStream(): +def test_dirstream() -> None: module_cache = ModuleCache(0xB5, 0x08F3) # Read the data from the demo file and decompress it. f = open('tests/blank/vbaProject.bin', 'rb') @@ -19,34 +19,34 @@ def test_dirStream(): f.seek(offset) container = f.read(length) ms_ovba = MsOvba() - decompressedStream = ms_ovba.decompress(container) + decompressed_stream = ms_ovba.decompress(container) # Create a project with the same attributes project = VbaProject() stream = DirStream(project) - codePage = 0x04E4 - codePageName = "cp" + str(codePage) + codepage = 0x04E4 + codepage_name = "cp" + str(codepage) guid = uuid.UUID('0002043000000000C000000000000046') - libidRef = LibidReference( + libid_ref = LibidReference( guid, "2.0", "0", "C:\\Windows\\System32\\stdole2.tlb", "OLE Automation" ) - oleReference = ReferenceRecord(codePageName, "stdole", libidRef) + ole_reference = ReferenceRecord(codepage_name, "stdole", libid_ref) guid = uuid.UUID('2DF8D04C5BFA101BBDE500AA0044DE52') - libidRef2 = LibidReference( + libid_ref2 = LibidReference( guid, "2.0", "0", "C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE16\\MSO.DLL", "Microsoft Office 16.0 Object Library" ) - officeReference = ReferenceRecord(codePageName, "Office", libidRef2) - project.addReference(oleReference) - project.addReference(officeReference) - project.setProjectCookie(0x08F3) + office_reference = ReferenceRecord(codepage_name, "Office", libid_ref2) + project.add_reference(ole_reference) + project.add_reference(office_reference) + project.set_project_cookie(0x08F3) indirect_table = ("02 80 FE FF FF FF FF FF 20 00 00 00 FF FF FF FF", "30 00 00 00 02 01 FF FF 00 00 00 00 00 00 00 00", @@ -61,36 +61,36 @@ def test_dirStream(): 0x18, "00000000", 1] this_workbook = DocModule("ThisWorkbook") - this_workbook.cookie.value = 0xB81C - module_cache.cookie = this_workbook.cookie.value + this_workbook.set_cookie(0xB81C) + module_cache.cookie = 0xB81C guid = uuid.UUID('0002081900000000C000000000000046') this_workbook.set_guid(guid) module_cache.guid = [guid] this_workbook.set_cache(module_cache.to_bytes()) sheet1 = DocModule("Sheet1") - sheet1.cookie.value = 0x9B9A - module_cache.cookie = sheet1.cookie.value + sheet1.set_cookie(0x9B9A) + module_cache.cookie = 0x9B9A guid = uuid.UUID('0002082000000000C000000000000046') module_cache.guid = [guid] sheet1.set_guid(guid) sheet1.set_cache(module_cache.to_bytes()) module1 = StdModule("Module1") - module1.cookie.value = 0xB241 + module1.set_cookie(0xB241) module_cache.clear_variables() - module_cache.cookie = module1.cookie.value + module_cache.cookie = 0xB241 module_cache.misc = [0x0316, 3, 0, 2, 0xFFFF, "FFFFFFFF", 0] module_cache.indirect_table = struct.pack(" None: rand = [0x41, 0xBC, 0x7B, 0x7B, 0x37, 0x7B, 0x7B, 0x7B] NotSoRandom.set_seed(rand) project = VbaProject() - codePage = 0x04E4 - codePageName = "cp" + str(codePage) - libidRef = LibidReference( + codepage = 0x04E4 + codepage_name = "cp" + str(codepage) + libid_ref = LibidReference( uuid.UUID("0002043000000000C000000000000046"), "2.0", "0", "C:\\Windows\\System32\\stdole2.tlb", "OLE Automation" ) - oleReference = ReferenceRecord(codePageName, "stdole", libidRef) - libidRef2 = LibidReference( + ole_reference = ReferenceRecord(codepage_name, "stdole", libid_ref) + libid_ref2 = LibidReference( uuid.UUID("2DF8D04C5BFA101BBDE500AA0044DE52"), "2.0", "0", "C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE16\\MSO.DLL", "Microsoft Office 16.0 Object Library" ) - officeReference = ReferenceRecord(codePageName, "Office", libidRef2) - project.addReference(oleReference) - project.addReference(officeReference) - project.setProjectCookie(0x08F3) - project.setProjectId('{9E394C0B-697E-4AEE-9FA6-446F51FB30DC}') - project.setPerformanceCache(createCache()) - project.setPerformanceCacheVersion(0x00B5) + office_reference = ReferenceRecord(codepage_name, "Office", libid_ref2) + project.add_reference(ole_reference) + project.add_reference(office_reference) + project.set_project_cookie(0x08F3) + project.set_project_id('{9E394C0B-697E-4AEE-9FA6-446F51FB30DC}') + project.set_performance_cache(create_cache()) + project.set_performance_cache_version(0x00B5) module_cache = ModuleCache(0xB5, 0x08F3) module_cache.misc = [0x0316, 0x0123, 0x88, 8, 0x18, "00000000", 1] @@ -106,7 +106,7 @@ def test_fullFile(): # Add Modules this_workbook = DocModule("ThisWorkbook") - this_workbook.cookie.value = 0xB81C + this_workbook.set_cookie(0xB81C) module_cache.module_cookie = 0xB81C guid = uuid.UUID("0002081900000000C000000000000046") module_cache.guid = [guid] @@ -117,7 +117,7 @@ def test_fullFile(): this_workbook.set_cache(module_cache.to_bytes()) sheet1 = DocModule("Sheet1") - sheet1.cookie.value = 0x9B9A + sheet1.set_cookie(0x9B9A) module_cache.module_cookie = 0x9B9A guid = uuid.UUID("0002082000000000C000000000000046") module_cache.guid = [guid] @@ -128,20 +128,20 @@ def test_fullFile(): sheet1.set_cache(module_cache.to_bytes()) module1 = StdModule("Module1") - module1.cookie.value = 0xB241 + module1.set_cookie(0xB241) module_cache.clear_variables() module_cache.misc = [0x0316, 3, 0, 2, 0xFFFF, "FFFFFFFF", 0] module_cache.indirect_table = struct.pack(" bytes: + vba_project = VbaProject() + vba_project.set_performance_cache_version(0x00B5) + this_workbook = DocModule("ThisWorkbook") + this_workbook.cookie.value = 0xB81C sheet1 = DocModule("Sheet1") sheet1.cookie.value = 0x9B9A module1 = StdModule("Module1") @@ -229,7 +229,7 @@ def createCache(): # index = 0x0046 i = 0 - for module in vbaProject.modules: + for module in vba_project.modules: name = module.modName.value.encode("utf_16_le") ca += struct.pack(" None: cls._rand = seeds @classmethod - def randint(cls, param1, param2): + def randint(cls, param1: int, param2: int) -> int: return cls._rand.pop(0) @@ -22,24 +22,24 @@ def randint(cls, param1, param2): def test_blank(): rand = [0x41, 0xBC, 0x7B, 0x7B, 0x37, 0x7B, 0x7B, 0x7B] NotSoRandom.set_seed(rand) - vbaProject = VbaProject() - vbaProject.setProjectId('{9E394C0B-697E-4AEE-9FA6-446F51FB30DC}') - project = Project(vbaProject) - project.addAttribute("HelpContextID", "0") - project.addAttribute("VersionCompatible32", "393222000") + vba_project = VbaProject() + vba_project.set_project_id('{9E394C0B-697E-4AEE-9FA6-446F51FB30DC}') + project = Project(vba_project) + project.add_attribute("HelpContextID", "0") + project.add_attribute("VersionCompatible32", "393222000") project.hostExtenderInfo = ("&H00000001=" + "{3832D640-CF90-11CF-8E43-00A0C911005A};VBE;" + "&H00000000") - thisWorkbook = DocModule("ThisWorkbook") + this_workbook = DocModule("ThisWorkbook") sheet1 = DocModule("Sheet1") module1 = StdModule("Module1") - module1.addWorkspace(26, 26, 1349, 522, 'Z') + module1.add_workspace(26, 26, 1349, 522, 'Z') - vbaProject.addModule(thisWorkbook) - vbaProject.addModule(sheet1) - vbaProject.addModule(module1) + vba_project.add_module(this_workbook) + vba_project.add_module(sheet1) + vba_project.add_module(module1) # expected = Path("tests/blank/vbaProject.bin").read_text() file = open("tests/blank/vbaProject.bin", "rb") diff --git a/tests/Views/test_projectWm.py b/tests/Views/test_projectWm.py index 1ac72f687..31e2c9f83 100644 --- a/tests/Views/test_projectWm.py +++ b/tests/Views/test_projectWm.py @@ -4,19 +4,19 @@ from vbaProjectCompiler.Views.projectWm import ProjectWm -def test_projectWm(): - vbaProject = VbaProject() - projectWm = ProjectWm(vbaProject) - thisWorkbook = DocModule("ThisWorkbook") +def test_project_wm() -> None: + vba_project = VbaProject() + project_wm = ProjectWm(vba_project) + this_workbook = DocModule("ThisWorkbook") sheet1 = DocModule("Sheet1") module1 = StdModule("Module1") - vbaProject.addModule(thisWorkbook) - vbaProject.addModule(sheet1) - vbaProject.addModule(module1) + vba_project.add_module(this_workbook) + vba_project.add_module(sheet1) + vba_project.add_module(module1) expected = (b'ThisWorkbook\x00T\x00h\x00i\x00s\x00W\x00o\x00r\x00k\x00b' + b'\x00o\x00o\x00k\x00\x00\x00Sheet1\x00S\x00h\x00e\x00e\x00' + b't\x001\x00\x00\x00Module1\x00M\x00o\x00d\x00u\x00l\x00e' + b'\x001\x00\x00\x00\x00\x00') - result = projectWm.to_bytes() + result = project_wm.to_bytes() assert len(result) == 86 assert result == expected diff --git a/tests/Views/test_vba_project.py b/tests/Views/test_vba_project.py index 78ca5c57d..e33750e30 100644 --- a/tests/Views/test_vba_project.py +++ b/tests/Views/test_vba_project.py @@ -1,13 +1,13 @@ from vbaProjectCompiler.vbaProject import VbaProject -from vbaProjectCompiler.Views.vba_Project import Vba_Project +from vbaProjectCompiler.Views.project_view import ProjectView -def test_vba_project(): - vbaProject = VbaProject() - vba_Project = Vba_Project(vbaProject) +def test_vba_project() -> None: + vba_project = VbaProject() + vba_project_view = ProjectView(vba_project) expected = b'\xCC\x61\xFF\xFF\x00\x03\x00' - assert vba_Project.to_bytes() == expected - vbaProject.setPerformanceCache(b'\x00\x01\x02\x03') - vbaProject.setPerformanceCacheVersion(0x00B5) + assert vba_project_view.to_bytes() == expected + vba_project.set_performance_cache(b'\x00\x01\x02\x03') + vba_project.set_performance_cache_version(0x00B5) expected = b'\xCC\x61\xB5\x00\x00\x03\x00\x00\x01\x02\x03' - assert vba_Project.to_bytes() == expected + assert vba_project_view.to_bytes() == expected diff --git a/tests/test_datetime.py b/tests/test_datetime.py deleted file mode 100644 index ac9b8c6b6..000000000 --- a/tests/test_datetime.py +++ /dev/null @@ -1,16 +0,0 @@ -import datetime - - -def test_datetime(): - # use a library - input = 0x01D92433C2B823C0 - date = filetime2datetime(input) - assert date.ctime() == "Mon Jan 9 14:07:51 2023" - - -def filetime2datetime(filetime): - """ - convert FILETIME (64 bits int) to Python datetime.datetime - """ - _FILETIME_null_date = datetime.datetime(1601, 1, 1, 0, 0, 0) - return _FILETIME_null_date + datetime.timedelta(microseconds=filetime//10) diff --git a/vbaProjectCompiler/Models/Entities/doc_module.py b/vbaProjectCompiler/Models/Entities/doc_module.py index 88fa9b6ba..9d2306a49 100644 --- a/vbaProjectCompiler/Models/Entities/doc_module.py +++ b/vbaProjectCompiler/Models/Entities/doc_module.py @@ -7,19 +7,19 @@ class DocModule(ModuleBase): A Document Module is a module record that is associated with a worksheet or workbook. """ - def __init__(self, name): - self.docTlibVer = 0 + def __init__(self, name) -> None: + self.doc_tlib_ver = 0 super(DocModule, self).__init__(name) self.type = "Document" # GUIDs self._guid = [] - def toProjectModuleString(self): + def to_project_module_string(self) -> str: return ("Document=" + self.modName.value + "/&H" - + self.docTlibVer.to_bytes(4, "big").hex()) + + self.doc_tlib_ver.to_bytes(4, "big").hex()) - def normalize_file(self): + def normalize_file(self) -> None: f = open(self._file_path, "r") new_f = open(self._file_path + ".new", "a+", newline='\r\n') for i in range(5): @@ -37,7 +37,7 @@ def normalize_file(self): new_f.writelines([self._attr("Customizable", "True")]) new_f.close() - def write_file(self): + def write_file(self) -> None: bin_f = open(self._file_path + ".bin", "wb") bin_f.write(self._cache) with open(self._file_path + ".new", mode="rb") as new_f: diff --git a/vbaProjectCompiler/Models/Entities/module_base.py b/vbaProjectCompiler/Models/Entities/module_base.py index a0cf1bf78..356e35f17 100644 --- a/vbaProjectCompiler/Models/Entities/module_base.py +++ b/vbaProjectCompiler/Models/Entities/module_base.py @@ -4,10 +4,14 @@ ) from vbaProjectCompiler.Models.Fields.packedData import PackedData from vbaProjectCompiler.Models.Fields.idSizeField import IdSizeField +from typing import TypeVar + + +T = TypeVar('T', bound='ModuleBase') class ModuleBase(): - def __init__(self, name): + def __init__(self: T, name: str) -> None: """ Initialize the module record """ @@ -30,52 +34,55 @@ def __init__(self, name): # GUIDs self._guid = [] - def set_guid(self, guid): + def set_guid(self: T, guid) -> None: if isinstance(guid, list): self._guid = guid else: self._guid = [guid] - def add_guid(self, guid): + def add_guid(self: T, guid) -> None: self._guid += guid - def set_cache(self, cache): + def set_cache(self: T, cache: bytes) -> None: self._cache = cache - def get_cache(self): + def get_cache(self: T): return self._cache - def get_name(self): + def set_cookie(self: T, value: int) -> None: + self.cookie = IdSizeField(0x002C, 2, value) + + def get_name(self: T): return self.modName.value - def addWorkspace(self, val1, val2, val3, val4, val5): + def add_workspace(self: T, val1, val2, val3, val4, val5) -> None: self.workspace = [val1, val2, val3, val4, val5] - def pack(self, codePageName, endien): + def pack(self: T, codepage_name, endien): """ Pack the metadata for use in the dir stream. """ - typeIdValue = 0x0022 if self.type == 'Document' else 0x0021 - typeId = PackedData("HI", typeIdValue, 0) + typeid_value = 0x0022 if self.type == 'Document' else 0x0021 + type_id = PackedData("HI", typeid_value, 0) self.offsetRec = IdSizeField(0x0031, 4, len(self._cache)) - output = (self.modName.pack(codePageName, endien) - + self.streamName.pack(codePageName, endien) - + self.docString.pack(codePageName, endien) - + self.offsetRec.pack(codePageName, endien) - + self.helpContext.pack(codePageName, endien) - + self.cookie.pack(codePageName, endien) - + typeId.pack(codePageName, endien)) + output = (self.modName.pack(codepage_name, endien) + + self.streamName.pack(codepage_name, endien) + + self.docString.pack(codepage_name, endien) + + self.offsetRec.pack(codepage_name, endien) + + self.helpContext.pack(codepage_name, endien) + + self.cookie.pack(codepage_name, endien) + + type_id.pack(codepage_name, endien)) footer = PackedData("HI", 0x002B, 0) - output += footer.pack(codePageName, endien) + output += footer.pack(codepage_name, endien) return output - def toProjectModuleString(self): + def to_project_module_string(self: T): return self.type + "=" + self.modName.value - def add_file(self, file_path): + def add_file(self: T, file_path: str) -> None: self._file_path = file_path - def write_file(self): + def write_file(self: T) -> None: bin_f = open(self._file_path + ".bin", "wb") bin_f.write(self._cache) with open(self._file_path + ".new", mode="rb") as new_f: @@ -85,5 +92,5 @@ def write_file(self): bin_f.write(compressed) bin_f.close() - def _attr(self, name, value): + def _attr(self: T, name: str, value: str) -> str: return 'Attribute VB_' + name + ' = ' + value + '\n' diff --git a/vbaProjectCompiler/Models/Entities/referenceRecord.py b/vbaProjectCompiler/Models/Entities/referenceRecord.py index 2d1ce917c..c3b55f76b 100644 --- a/vbaProjectCompiler/Models/Entities/referenceRecord.py +++ b/vbaProjectCompiler/Models/Entities/referenceRecord.py @@ -6,17 +6,18 @@ class ReferenceRecord(): - def __init__(self, codePageName, name, libidRef): - self.codePageName = codePageName - self.RefName = DoubleEncodedString([0x0016, 0x003E], name) - self.libidRef = libidRef + def __init__(self, codepage_name, name, libid_ref): + # is self._codepage_name even needed? + self._codepage_name = codepage_name + self._refname = DoubleEncodedString([0x0016, 0x003E], name) + self._libid_ref = libid_ref - def pack(self, codePageName, endien): - strlen = len(self.libidRef) + def pack(self, codepage_name, endien): + strlen = len(self._libid_ref) format = "HII" + str(strlen) + "sIH" - lib_str = str(self.libidRef).encode(self.codePageName) - refRegistered = PackedData(format, 0x000D, strlen + 10, - strlen, lib_str, 0, 0) + lib_str = str(self._libid_ref).encode(self._codepage_name) + ref_registered = PackedData(format, 0x000D, strlen + 10, + strlen, lib_str, 0, 0) - return (self.RefName.pack(codePageName, endien) - + refRegistered.pack(codePageName, endien)) + return (self._refname.pack(codepage_name, endien) + + ref_registered.pack(codepage_name, endien)) diff --git a/vbaProjectCompiler/Models/Fields/doubleEncodedString.py b/vbaProjectCompiler/Models/Fields/doubleEncodedString.py index 64f517d94..d9721dbcd 100644 --- a/vbaProjectCompiler/Models/Fields/doubleEncodedString.py +++ b/vbaProjectCompiler/Models/Fields/doubleEncodedString.py @@ -5,15 +5,15 @@ class DoubleEncodedString(): """ Encode text data twice with different ids and lengths """ - def __init__(self, ids, text): + def __init__(self, ids: list, text: str) -> None: self.ids = ids self.value = text - def pack(self, codePageName, endien): - encoded = self.value.encode(codePageName) - self.modName1 = IdSizeField(self.ids[0], len(encoded), encoded) + def pack(self, codepage_name, endien): + encoded = self.value.encode(codepage_name) + self.mod_name1 = IdSizeField(self.ids[0], len(encoded), encoded) format = "utf_16_le" if endien == 'little' else "utf_16_be" encoded = self.value.encode(format) - self.modName2 = IdSizeField(self.ids[1], len(encoded), encoded) - return (self.modName1.pack(codePageName, endien) - + self.modName2.pack(codePageName, endien)) + self.mod_name2 = IdSizeField(self.ids[1], len(encoded), encoded) + return (self.mod_name1.pack(codepage_name, endien) + + self.mod_name2.pack(codepage_name, endien)) diff --git a/vbaProjectCompiler/Models/Fields/idSizeField.py b/vbaProjectCompiler/Models/Fields/idSizeField.py index 363bc3092..b7f505b5f 100644 --- a/vbaProjectCompiler/Models/Fields/idSizeField.py +++ b/vbaProjectCompiler/Models/Fields/idSizeField.py @@ -7,25 +7,25 @@ class IdSizeField(): int value formatted to the defined size. """ - def __init__(self, id, size, value): - self.id = id - self.size = size - self.value = value + def __init__(self, id, size: int, value) -> None: + self._id = id + self._size = size + self._value = value - def pack(self, codePageName, endien): - endienSymbol = '<' if endien == 'little' else '>' - format = endienSymbol + "HI" - if isinstance(self.value, str): - self.stringValue = self.value - self.value = bytes(self.value, encoding="ascii") - format += str(self.size) + "s" - elif isinstance(self.value, bytes): - format += str(self.size) + "s" - elif self.size == 2: + def pack(self, codepage_name: str, endien: str) -> bytes: + endien_symbol = '<' if endien == 'little' else '>' + format = endien_symbol + "HI" + if isinstance(self._value, str): + self.stringValue = self._value + self._value = bytes(self._value, encoding="ascii") + format += str(self._size) + "s" + elif isinstance(self._value, bytes): + format += str(self._size) + "s" + elif self._size == 2: format += "H" - elif self.size == 4: + elif self._size == 4: format += "I" else: - msg = "Received data of type " + type(self.value).__name__ + msg = "Received data of type " + type(self._value).__name__ raise Exception(msg) - return struct.pack(format, self.id, self.size, self.value) + return struct.pack(format, self._id, self._size, self._value) diff --git a/vbaProjectCompiler/Models/Fields/libidReference.py b/vbaProjectCompiler/Models/Fields/libidReference.py index 7f49f9110..05cbd0cbd 100644 --- a/vbaProjectCompiler/Models/Fields/libidReference.py +++ b/vbaProjectCompiler/Models/Fields/libidReference.py @@ -1,24 +1,24 @@ class LibidReference(): - def __init__(self, libidGuid, version, - libidLcid, libidPath, libidRegName): - self.libidGuid = libidGuid - self.version = version - self.libidLcid = libidLcid - self.libidPath = libidPath - self.libidRegName = libidRegName - if self._is_windows_path(libidPath): - self.libidReferenceKind = "G" + def __init__(self, libid_guid, version, + libid_lcid, libid_path, libid_reg_name): + self._libid_guid = libid_guid + self._version = version + self._libid_lcid = libid_lcid + self._libid_path = libid_path + self._libid_reg_name = libid_reg_name + if self._is_windows_path(libid_path): + self._libid_reference_kind = "G" else: - self.libidReferenceKind = "H" + self._libid_reference_kind = "H" def __str__(self): return "*\\" + \ - self.libidReferenceKind + \ - "{" + str(self.libidGuid).upper() + "}#" + \ - self.version + "#" + \ - self.libidLcid + "#" + \ - str(self.libidPath) + "#" + \ - self.libidRegName + self._libid_reference_kind + \ + "{" + str(self._libid_guid).upper() + "}#" + \ + self._version + "#" + \ + self._libid_lcid + "#" + \ + str(self._libid_path) + "#" + \ + self._libid_reg_name def __len__(self): return len(str(self)) diff --git a/vbaProjectCompiler/Models/Fields/packedData.py b/vbaProjectCompiler/Models/Fields/packedData.py index c1e901c6e..474e7acb3 100644 --- a/vbaProjectCompiler/Models/Fields/packedData.py +++ b/vbaProjectCompiler/Models/Fields/packedData.py @@ -5,10 +5,10 @@ class PackedData(): """ Mutivalue field with a packing format """ - def __init__(self, format, *values): + def __init__(self, format, *values) -> None: self.values = values self.format = format - def pack(self, codePageName, endien): - endienSymbol = '<' if endien == 'little' else '>' - return struct.pack(endienSymbol + self.format, *self.values) + def pack(self, codepage_name, endien) -> bytes: + endien_symbol = '<' if endien == 'little' else '>' + return struct.pack(endien_symbol + self.format, *self.values) diff --git a/vbaProjectCompiler/Views/dirStream.py b/vbaProjectCompiler/Views/dirStream.py index e7ea8baee..8257668fe 100644 --- a/vbaProjectCompiler/Views/dirStream.py +++ b/vbaProjectCompiler/Views/dirStream.py @@ -12,63 +12,63 @@ class DirStream(): The dir stream is compressed on write """ - def __init__(self, project): + def __init__(self, project) -> None: self.project = project - self.codePage = 0x04E4 + self.codepage = 0x04E4 # 0=16bit, 1=32bit, 2=mac, 3=64bit syskind = IdSizeField(1, 4, 3) - compatVersion = IdSizeField(74, 4, 3) + compat_version = IdSizeField(74, 4, 3) lcid = IdSizeField(2, 4, 0x0409) - lcidInvoke = IdSizeField(20, 4, 0x0409) - codePageRecord = IdSizeField(3, 2, self.codePage) - projectName = IdSizeField(4, 10, "VBAProject") - docString = DoubleEncodedString([5, 0x0040], "") + lcid_invoke = IdSizeField(20, 4, 0x0409) + codepage_record = IdSizeField(3, 2, self.codepage) + project_name = IdSizeField(4, 10, "VBAProject") + docstring = DoubleEncodedString([5, 0x0040], "") helpfile = DoubleEncodedString([6, 0x003D], "") - helpContext = IdSizeField(7, 4, 0) - libFlags = IdSizeField(8, 4, 0) + help_context = IdSizeField(7, 4, 0) + lib_flags = IdSizeField(8, 4, 0) version = IdSizeField(9, 4, 0x65BE0257) - minorVersion = PackedData("H", 17) + minor_version = PackedData("H", 17) constants = DoubleEncodedString([12, 0x003C], "") self.information = [ syskind, - compatVersion, + compat_version, lcid, - lcidInvoke, - codePageRecord, - projectName, - docString, + lcid_invoke, + codepage_record, + project_name, + docstring, helpfile, - helpContext, - libFlags, + help_context, + lib_flags, version, - minorVersion, + minor_version, constants ] self.references = [] self.modules = [] - def to_bytes(self): + def to_bytes(self) -> bytes: endien = self.project.endien - codePageName = self.project.getCodePageName() - packSymbol = '<' if endien == 'little' else '>' + codepage_name = self.project.get_codepage_name() + pack_symbol = '<' if endien == 'little' else '>' # should be 0xFFFF - cookie_value = self.project.projectCookie - self.projectCookie = IdSizeField(19, 2, cookie_value) + cookie_value = self.project.get_project_cookie() + self.project_cookie = IdSizeField(19, 2, cookie_value) self.references = self.project.references self.modules = self.project.modules output = b'' for record in self.information: - output += record.pack(codePageName, endien) + output += record.pack(codepage_name, endien) for record in self.references: - output += record.pack(codePageName, endien) + output += record.pack(codepage_name, endien) - modulesHeader = IdSizeField(0x000F, 2, len(self.modules)) + modules_header = IdSizeField(0x000F, 2, len(self.modules)) - output += (modulesHeader.pack(codePageName, endien) - + self.projectCookie.pack(codePageName, endien)) + output += (modules_header.pack(codepage_name, endien) + + self.project_cookie.pack(codepage_name, endien)) for record in self.modules: - output += record.pack(codePageName, endien) - output += struct.pack(packSymbol + "HI", 16, 0) + output += record.pack(codepage_name, endien) + output += struct.pack(pack_symbol + "HI", 16, 0) return output def write_file(self): diff --git a/vbaProjectCompiler/Views/project.py b/vbaProjectCompiler/Views/project.py index 690299357..e47fe4c7e 100644 --- a/vbaProjectCompiler/Views/project.py +++ b/vbaProjectCompiler/Views/project.py @@ -6,7 +6,7 @@ class Project: """ The Project data view for the vbaProject """ - def __init__(self, project): + def __init__(self, project) -> None: self.project = project # Attributes @@ -16,20 +16,21 @@ def __init__(self, project): # The HostExtenderInfo string self.hostExtenderInfo = "" - def addAttribute(self, name, value): + def add_attribute(self, name, value) -> None: self.attributes[name] = value def to_bytes(self): project = self.project - codePageName = project.getCodePageName() + codepage_name = project.get_codepage_name() # Use \x0D0A line endings...however python encodes that. eol = b'\x0D\x0A' - project_id = project.getProjectId() - id = bytearray(project_id, codePageName) + project_id = project.get_project_id() + id = bytearray(project_id, codepage_name) result = b'ID="' + id + b'"' + eol modules = project.modules for module in modules: - result += bytes(module.toProjectModuleString(), codePageName) + eol + result += bytes(module.to_project_module_string(), codepage_name) + result += eol result += b'Name="VBAProject"' + eol for key in self.attributes: result += self._attr(key, self.attributes[key]) @@ -39,25 +40,25 @@ def to_bytes(self): ) dpb = ms_ovba_crypto.encrypt(project_id, project.get_password()) gc = ms_ovba_crypto.encrypt(project_id, project.get_visibility_state()) - result += (bytes('CMG="', codePageName) + result += (bytes('CMG="', codepage_name) + binascii.hexlify(cmg).upper() + b'\x22\x0D\x0A') - result += (bytes('DPB="', codePageName) + result += (bytes('DPB="', codepage_name) + binascii.hexlify(dpb).upper() + b'\x22\x0D\x0A') - result += (bytes('GC="', codePageName) + result += (bytes('GC="', codepage_name) + binascii.hexlify(gc).upper() + b'\x22\x0D\x0A') result += eol result += b'[Host Extender Info]' + eol - result += bytes(self.hostExtenderInfo, codePageName) + result += bytes(self.hostExtenderInfo, codepage_name) result += eol + eol result += b'[Workspace]' + eol for module in modules: separator = ", " - result += bytes(module.modName.value, codePageName) + b'=' + result += bytes(module.modName.value, codepage_name) + b'=' joined = separator.join(map(str, module.workspace)) - result += bytes(joined, codePageName) + result += bytes(joined, codepage_name) result += eol return result @@ -67,8 +68,8 @@ def write_file(self): bin_f.close() def _attr(self, name, value): - codePageName = self.project.getCodePageName() + codepage_name = self.project.get_codepage_name() eol = b'\x0D\x0A' - b_name = bytes(name, codePageName) - b_value = bytes(value, codePageName) + b_name = bytes(name, codepage_name) + b_value = bytes(value, codepage_name) return b_name + b'="' + b_value + b'"' + eol diff --git a/vbaProjectCompiler/Views/vba_Project.py b/vbaProjectCompiler/Views/project_view.py similarity index 54% rename from vbaProjectCompiler/Views/vba_Project.py rename to vbaProjectCompiler/Views/project_view.py index eeb2dad6d..939104fab 100644 --- a/vbaProjectCompiler/Views/vba_Project.py +++ b/vbaProjectCompiler/Views/project_view.py @@ -1,27 +1,27 @@ import struct -class Vba_Project: +class ProjectView: """ The _VBA_PROJECT data view for the vbaProject """ - def __init__(self, project): + def __init__(self, project) -> None: self.project = project - def to_bytes(self): - endienSymbol = '<' if self.project.endien == 'little' else '>' - format = endienSymbol + "HHBH" + def to_bytes(self) -> bytes: + endien_symbol = '<' if self.project.endien == 'little' else '>' + format = endien_symbol + "HHBH" output = b'' reserved1 = 0x61CC reserved2 = 0x00 reserved3 = 0x0003 - cache_version = self.project.getPerformanceCacheVersion() + cache_version = self.project.get_performance_cache_version() output += struct.pack(format, reserved1, cache_version, reserved2, reserved3) - return output + self.project.getPerformanceCache() + return output + self.project.get_performance_cache() - def write_file(self): + def write_file(self) -> None: bin_f = open("vba_project.bin", "wb") bin_f.write(self.to_bytes()) bin_f.close() diff --git a/vbaProjectCompiler/vbaProject.py b/vbaProjectCompiler/vbaProject.py index 8840fb6a9..9dd08d613 100644 --- a/vbaProjectCompiler/vbaProject.py +++ b/vbaProjectCompiler/vbaProject.py @@ -3,47 +3,51 @@ # from ms_cfb.Models.Directories.stream_directory import StreamDirectory from vbaProjectCompiler.Views.dirStream import DirStream -# from vbaProjectCompiler.Views.vba_Project import Vba_Project +# from vbaProjectCompiler.Views.project_view import ProjectView from vbaProjectCompiler.Views.project import Project from vbaProjectCompiler.Views.projectWm import ProjectWm +from typing import TypeVar + + +T = TypeVar('T', bound='VbaProject') class VbaProject: - def __init__(self): + def __init__(self: T) -> None: self.endien = 'little' # Protected Instance Attributes - self._codePageName = 'cp1252' - self._projectId = '{}' + self._codepage_name = 'cp1252' + self._project_id = '{}' self._protection_state = b'\x00\x00\x00\x00' self._password = b'\x00' self._visibility_state = b'\xFF' - self._performanceCache = b'' - self._performanceCacheVersion = 0xFFFF + self._performance_cache = b'' + self._performance_cache_version = 0xFFFF # A list of directories self.directories = [] self.references = [] self.modules = [] - self.projectCookie = 0xFFFF + self._project_cookie = 0xFFFF # Getters and Setters - def setProjectId(self, id): - self._projectId = id + def set_project_id(self: T, id: str) -> None: + self._project_id = id - def getProjectId(self): - return self._projectId + def get_project_id(self: T) -> str: + return self._project_id - def set_protection_state(self, state): + def set_protection_state(self: T, state: int) -> None: self._protection_state = state - def get_protection_state(self): + def get_protection_state(self: T) -> int: return self._protection_state - def set_visibility_state(self, state): + def set_visibility_state(self: T, state) -> None: """ 0 = not visible 255 = visible @@ -52,53 +56,56 @@ def set_visibility_state(self, state): raise Exception("Bad visibility value.") self._visibility_state = state - def get_visibility_state(self): + def get_visibility_state(self: T): return self._visibility_state - def set_password(self, value): + def set_password(self: T, value) -> None: self._password = value def get_password(self): return self._password - def setPerformanceCache(self, cache): - self._performanceCache = cache + def set_performance_cache(self: T, cache: bytes) -> None: + self._performance_cache = cache + + def get_performance_cache(self: T) -> None: + return self._performance_cache - def getPerformanceCache(self): - return self._performanceCache + def set_performance_cache_version(self: T, version: int) -> None: + self._performance_cache_version = version - def setPerformanceCacheVersion(self, version): - self._performanceCacheVersion = version + def get_performance_cache_version(self: T) -> int: + return self._performance_cache_version - def getPerformanceCacheVersion(self): - return self._performanceCacheVersion + def get_codepage_name(self: T) -> str: + return self._codepage_name - def getCodePageName(self): - return self._codePageName + def set_project_cookie(self: T, value: int) -> None: + self._project_cookie = value - def setProjectCookie(self, value): - self.projectCookie = value + def get_project_cookie(self: T) -> int: + return self._project_cookie # Appenders - def addModule(self, ref): + def add_module(self: T, ref) -> None: self.modules.append(ref) - def addReference(self, ref): + def add_reference(self: T, ref) -> None: self.references.append(ref) - def _create_binary_files(self): + def _create_binary_files(self: T) -> None: for module in self.modules: module.write_file() dir = DirStream(self) dir.write_file() project = Project(self) project.write_file() - projectWm = ProjectWm(self) - projectWm.write_file() - # views = ("_VBA_PROJECT", "dir", "projectWm", "Project") + project_wm = ProjectWm(self) + project_wm.write_file() + # views = ("_VBA_PROJECT", "dir", "project_wm", "Project") # Create views and write - def _build_ole_directory(self): + def _build_ole_directory(self: T) -> None: # directory = StorageDirectory() # directory.set_name("VBA") for module in self.modules: @@ -110,14 +117,14 @@ def _build_ole_directory(self): pass # return directory - def _write_ole_file(self, dir): + def _write_ole_file(self: T, dir) -> None: # ole_file = OleFile() # ole_file.add_directory(dir) # ole_file.build_file() # ole_file.write_file("vbaProject.bin") pass - def write_file(self): + def write_file(self: T) -> None: self._create_binary_files() directory = self._build_ole_directory() self._write_ole_file(directory) From a4a0b0b22d9ce8a89fc2286d8f7aa04c1aec2236 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Mon, 3 Apr 2023 12:52:35 -0400 Subject: [PATCH 008/335] Add Annotations, Seperate ole view from project (#102) --- requirements_dev.txt | 1 + tests/Functional/test_dirObject.py | 4 +- tests/Functional/test_fullFile.py | 30 ++++++---- tests/Unit/Models/Entities/test_doc_module.py | 2 +- tests/Unit/Models/Entities/test_std_module.py | 4 +- tests/Unit/Models/Fields/test_idSizeField.py | 2 +- .../Unit/Models/Fields/test_libidReference.py | 6 +- tests/Unit/Models/test_vbaProject.py | 8 +-- tests/Views/test_project.py | 10 +++- .../Models/Entities/doc_module.py | 12 ++-- .../Models/Entities/module_base.py | 17 +++--- ...referenceRecord.py => reference_record.py} | 12 +++- .../Models/Entities/std_module.py | 8 ++- .../Models/Fields/doubleEncodedString.py | 8 ++- .../Models/Fields/idSizeField.py | 8 ++- .../{libidReference.py => libid_reference.py} | 18 ++++-- .../Models/Fields/packedData.py | 14 ----- .../Models/Fields/packed_data.py | 18 ++++++ vbaProjectCompiler/Views/dirStream.py | 13 ++-- vbaProjectCompiler/Views/project.py | 15 +++-- vbaProjectCompiler/Views/projectWm.py | 13 +++- vbaProjectCompiler/Views/project_ole_file.py | 51 ++++++++++++++++ vbaProjectCompiler/Views/project_view.py | 11 +++- vbaProjectCompiler/main.py | 2 +- vbaProjectCompiler/vbaProject.py | 60 ++++--------------- 25 files changed, 215 insertions(+), 132 deletions(-) rename vbaProjectCompiler/Models/Entities/{referenceRecord.py => reference_record.py} (64%) rename vbaProjectCompiler/Models/Fields/{libidReference.py => libid_reference.py} (65%) delete mode 100644 vbaProjectCompiler/Models/Fields/packedData.py create mode 100644 vbaProjectCompiler/Models/Fields/packed_data.py create mode 100644 vbaProjectCompiler/Views/project_ole_file.py diff --git a/requirements_dev.txt b/requirements_dev.txt index 8fc00bff8..c3c5f1430 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -3,3 +3,4 @@ pytest-cov pytest-mock coveralls pep8-naming +flake8-annotations diff --git a/tests/Functional/test_dirObject.py b/tests/Functional/test_dirObject.py index 22a7aac92..72b6dd754 100644 --- a/tests/Functional/test_dirObject.py +++ b/tests/Functional/test_dirObject.py @@ -4,10 +4,10 @@ from ms_pcode_assembler.module_cache import ModuleCache from vbaProjectCompiler.vbaProject import VbaProject from vbaProjectCompiler.Views.dirStream import DirStream -from vbaProjectCompiler.Models.Fields.libidReference import LibidReference +from vbaProjectCompiler.Models.Fields.libid_reference import LibidReference from vbaProjectCompiler.Models.Entities.doc_module import DocModule from vbaProjectCompiler.Models.Entities.std_module import StdModule -from vbaProjectCompiler.Models.Entities.referenceRecord import ReferenceRecord +from vbaProjectCompiler.Models.Entities.reference_record import ReferenceRecord def test_dirstream() -> None: diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 0cc9bd1b0..03b8ce1cf 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -8,24 +8,29 @@ from vbaProjectCompiler.vbaProject import VbaProject from vbaProjectCompiler.Models.Entities.doc_module import DocModule from vbaProjectCompiler.Models.Entities.std_module import StdModule -from vbaProjectCompiler.Models.Entities.referenceRecord import ReferenceRecord -from vbaProjectCompiler.Models.Fields.libidReference import LibidReference +from vbaProjectCompiler.Models.Entities.reference_record import ReferenceRecord +from vbaProjectCompiler.Models.Fields.libid_reference import LibidReference +from vbaProjectCompiler.Views.project_ole_file import ProjectOleFile +from typing import Type, TypeVar + + +T = TypeVar('T', bound='NotSoRandom') class NotSoRandom(): _rand = [] @classmethod - def set_seed(cls, seeds: list): + def set_seed(cls: Type[T], seeds: list) -> None: cls._rand = seeds @classmethod - def randint(cls, param1, param2): + def randint(cls: Type[T], param1: int, param2: int) -> int: return cls._rand.pop(0) @pytest.fixture(autouse=True) -def run_around_tests(): +def run_around_tests() -> None: # Code that will run before your test, for example: # A test function will be run at this point @@ -40,17 +45,17 @@ def run_around_tests(): map(os.remove, names) -def remove_module(names): +def remove_module(names: str) -> None: for name in names: os.remove(name + ".new") os.remove(name + ".bin") -def module_matches_bin(module_path, - cache_size, - bin_path, - bin_offset, - bin_length): +def module_matches_bin(module_path: str, + cache_size: int, + bin_path: str, + bin_offset: int, + bin_length: int) -> bool: m = open(module_path, "rb") b = open(bin_path, "rb") b.seek(bin_offset) @@ -143,7 +148,8 @@ def test_full_file() -> None: project.add_module(sheet1) project.add_module(module1) - project.write_file() + ole_file = ProjectOleFile(project) + ole_file.write_file() path = "vbaProjectCompiler/blank_files/ThisWorkbook.cls.bin" assert module_matches_bin(path, 0x0333, "tests/blank/vbaProject.bin", 0x0800, 0xB5) diff --git a/tests/Unit/Models/Entities/test_doc_module.py b/tests/Unit/Models/Entities/test_doc_module.py index fe32951c9..fc59f3951 100644 --- a/tests/Unit/Models/Entities/test_doc_module.py +++ b/tests/Unit/Models/Entities/test_doc_module.py @@ -4,7 +4,7 @@ from vbaProjectCompiler.Models.Entities.doc_module import DocModule -def test_normalize(): +def test_normalize() -> None: cache = ModuleCache(0xB5, 0x08F3) cache.module_cookie = 0xB81C diff --git a/tests/Unit/Models/Entities/test_std_module.py b/tests/Unit/Models/Entities/test_std_module.py index f1ce91845..15eac0667 100644 --- a/tests/Unit/Models/Entities/test_std_module.py +++ b/tests/Unit/Models/Entities/test_std_module.py @@ -1,13 +1,13 @@ from vbaProjectCompiler.Models.Entities.std_module import StdModule -def test_set_get_cache(): +def test_set_get_cache() -> None: module = StdModule("Module1") cache = b'foo' module.set_cache(cache) assert module.get_cache() == cache -def test_get_name(): +def test_get_name() -> None: module = StdModule("Module1") assert module.get_name() == "Module1" diff --git a/tests/Unit/Models/Fields/test_idSizeField.py b/tests/Unit/Models/Fields/test_idSizeField.py index a63fea652..071ec3569 100644 --- a/tests/Unit/Models/Fields/test_idSizeField.py +++ b/tests/Unit/Models/Fields/test_idSizeField.py @@ -2,7 +2,7 @@ from vbaProjectCompiler.Models.Fields.idSizeField import IdSizeField -def test_bad_value(): +def test_bad_value() -> None: field = IdSizeField(2, 3, 6) with pytest.raises(Exception): field.pack(1234, "little") diff --git a/tests/Unit/Models/Fields/test_libidReference.py b/tests/Unit/Models/Fields/test_libidReference.py index ee7a54ba9..02590c9e6 100644 --- a/tests/Unit/Models/Fields/test_libidReference.py +++ b/tests/Unit/Models/Fields/test_libidReference.py @@ -1,8 +1,8 @@ import uuid -from vbaProjectCompiler.Models.Fields.libidReference import LibidReference +from vbaProjectCompiler.Models.Fields.libid_reference import LibidReference -def test_str(): +def test_str() -> None: guid = uuid.UUID('0002043000000000C000000000000046') libid_ref = LibidReference( guid, @@ -17,7 +17,7 @@ def test_str(): assert len(libid_ref) == 94 -def test_posix(): +def test_posix() -> None: guid = uuid.UUID('0002043000000000C000000000000046') libid_ref = LibidReference( guid, diff --git a/tests/Unit/Models/test_vbaProject.py b/tests/Unit/Models/test_vbaProject.py index 769ce9225..5066ed903 100644 --- a/tests/Unit/Models/test_vbaProject.py +++ b/tests/Unit/Models/test_vbaProject.py @@ -2,25 +2,25 @@ from vbaProjectCompiler.vbaProject import VbaProject -def test_set_get_visibility(): +def test_set_get_visibility() -> None: project = VbaProject() project.set_visibility_state(0) assert project.get_visibility_state() == 0 -def test_set_get_protection(): +def test_set_get_protection() -> None: project = VbaProject() project.set_protection_state(0) assert project.get_protection_state() == 0 -def test_set_get_password(): +def test_set_get_password() -> None: project = VbaProject() project.set_password(0) assert project.get_password() == 0 -def test_bad_visibility(): +def test_bad_visibility() -> None: """ Visibility must be zero or 0xFF """ diff --git a/tests/Views/test_project.py b/tests/Views/test_project.py index d496527d3..a0a7f7927 100644 --- a/tests/Views/test_project.py +++ b/tests/Views/test_project.py @@ -4,22 +4,26 @@ from vbaProjectCompiler.Models.Entities.doc_module import DocModule from vbaProjectCompiler.Models.Entities.std_module import StdModule from vbaProjectCompiler.Views.project import Project +from typing import Type, TypeVar + + +T = TypeVar('T', bound='NotSoRandom') class NotSoRandom(): _rand = [] @classmethod - def set_seed(cls, seeds) -> None: + def set_seed(cls: Type[T], seeds: list) -> None: cls._rand = seeds @classmethod - def randint(cls, param1: int, param2: int) -> int: + def randint(cls: Type[T], param1: int, param2: int) -> int: return cls._rand.pop(0) @unittest.mock.patch('random.randint', NotSoRandom.randint) -def test_blank(): +def test_blank() -> None: rand = [0x41, 0xBC, 0x7B, 0x7B, 0x37, 0x7B, 0x7B, 0x7B] NotSoRandom.set_seed(rand) vba_project = VbaProject() diff --git a/vbaProjectCompiler/Models/Entities/doc_module.py b/vbaProjectCompiler/Models/Entities/doc_module.py index 9d2306a49..21ce03e91 100644 --- a/vbaProjectCompiler/Models/Entities/doc_module.py +++ b/vbaProjectCompiler/Models/Entities/doc_module.py @@ -1,5 +1,9 @@ from ms_ovba_compression.ms_ovba import MsOvba from vbaProjectCompiler.Models.Entities.module_base import ModuleBase +from typing import TypeVar + + +T = TypeVar('T', bound='DocModule') class DocModule(ModuleBase): @@ -7,7 +11,7 @@ class DocModule(ModuleBase): A Document Module is a module record that is associated with a worksheet or workbook. """ - def __init__(self, name) -> None: + def __init__(self: T, name: str) -> None: self.doc_tlib_ver = 0 super(DocModule, self).__init__(name) self.type = "Document" @@ -15,11 +19,11 @@ def __init__(self, name) -> None: # GUIDs self._guid = [] - def to_project_module_string(self) -> str: + def to_project_module_string(self: T) -> str: return ("Document=" + self.modName.value + "/&H" + self.doc_tlib_ver.to_bytes(4, "big").hex()) - def normalize_file(self) -> None: + def normalize_file(self: T) -> None: f = open(self._file_path, "r") new_f = open(self._file_path + ".new", "a+", newline='\r\n') for i in range(5): @@ -37,7 +41,7 @@ def normalize_file(self) -> None: new_f.writelines([self._attr("Customizable", "True")]) new_f.close() - def write_file(self) -> None: + def write_file(self: T) -> None: bin_f = open(self._file_path + ".bin", "wb") bin_f.write(self._cache) with open(self._file_path + ".new", mode="rb") as new_f: diff --git a/vbaProjectCompiler/Models/Entities/module_base.py b/vbaProjectCompiler/Models/Entities/module_base.py index 356e35f17..5763adba9 100644 --- a/vbaProjectCompiler/Models/Entities/module_base.py +++ b/vbaProjectCompiler/Models/Entities/module_base.py @@ -2,7 +2,7 @@ from vbaProjectCompiler.Models.Fields.doubleEncodedString import ( DoubleEncodedString ) -from vbaProjectCompiler.Models.Fields.packedData import PackedData +from vbaProjectCompiler.Models.Fields.packed_data import PackedData from vbaProjectCompiler.Models.Fields.idSizeField import IdSizeField from typing import TypeVar @@ -34,31 +34,32 @@ def __init__(self: T, name: str) -> None: # GUIDs self._guid = [] - def set_guid(self: T, guid) -> None: + def set_guid(self: T, guid: str) -> None: if isinstance(guid, list): self._guid = guid else: self._guid = [guid] - def add_guid(self: T, guid) -> None: + def add_guid(self: T, guid: str) -> None: self._guid += guid def set_cache(self: T, cache: bytes) -> None: self._cache = cache - def get_cache(self: T): + def get_cache(self: T) -> bytes: return self._cache def set_cookie(self: T, value: int) -> None: self.cookie = IdSizeField(0x002C, 2, value) - def get_name(self: T): + def get_name(self: T) -> str: return self.modName.value - def add_workspace(self: T, val1, val2, val3, val4, val5) -> None: + def add_workspace(self: T, val1: int, val2: int, + val3: int, val4: int, val5: int) -> None: self.workspace = [val1, val2, val3, val4, val5] - def pack(self: T, codepage_name, endien): + def pack(self: T, codepage_name: str, endien: str) -> bytes: """ Pack the metadata for use in the dir stream. """ @@ -76,7 +77,7 @@ def pack(self: T, codepage_name, endien): output += footer.pack(codepage_name, endien) return output - def to_project_module_string(self: T): + def to_project_module_string(self: T) -> str: return self.type + "=" + self.modName.value def add_file(self: T, file_path: str) -> None: diff --git a/vbaProjectCompiler/Models/Entities/referenceRecord.py b/vbaProjectCompiler/Models/Entities/reference_record.py similarity index 64% rename from vbaProjectCompiler/Models/Entities/referenceRecord.py rename to vbaProjectCompiler/Models/Entities/reference_record.py index c3b55f76b..358b03ae9 100644 --- a/vbaProjectCompiler/Models/Entities/referenceRecord.py +++ b/vbaProjectCompiler/Models/Entities/reference_record.py @@ -1,18 +1,24 @@ from vbaProjectCompiler.Models.Fields.doubleEncodedString import ( DoubleEncodedString ) -from vbaProjectCompiler.Models.Fields.packedData import PackedData +from vbaProjectCompiler.Models.Fields.libid_reference import LibidReference +from vbaProjectCompiler.Models.Fields.packed_data import PackedData +from typing import TypeVar + + +T = TypeVar('T', bound='ReferenceRecord') class ReferenceRecord(): - def __init__(self, codepage_name, name, libid_ref): + def __init__(self: T, codepage_name: str, + name: str, libid_ref: LibidReference) -> None: # is self._codepage_name even needed? self._codepage_name = codepage_name self._refname = DoubleEncodedString([0x0016, 0x003E], name) self._libid_ref = libid_ref - def pack(self, codepage_name, endien): + def pack(self: T, codepage_name: str, endien: str) -> bytes: strlen = len(self._libid_ref) format = "HII" + str(strlen) + "sIH" lib_str = str(self._libid_ref).encode(self._codepage_name) diff --git a/vbaProjectCompiler/Models/Entities/std_module.py b/vbaProjectCompiler/Models/Entities/std_module.py index 2a5cc8fcc..c4859527f 100644 --- a/vbaProjectCompiler/Models/Entities/std_module.py +++ b/vbaProjectCompiler/Models/Entities/std_module.py @@ -1,13 +1,17 @@ from vbaProjectCompiler.Models.Entities.module_base import ModuleBase +from typing import TypeVar + + +T = TypeVar('T', bound='StdModule') class StdModule(ModuleBase): - def __init__(self, name): + def __init__(self: T, name: str) -> None: super(StdModule, self).__init__(name) self.type = "Module" - def normalize_file(self): + def normalize_file(self: T) -> None: f = open(self._file_path, "r") new_f = open(self._file_path + ".new", "a+", newline='\r\n') while line := f.readline(): diff --git a/vbaProjectCompiler/Models/Fields/doubleEncodedString.py b/vbaProjectCompiler/Models/Fields/doubleEncodedString.py index d9721dbcd..711b92e81 100644 --- a/vbaProjectCompiler/Models/Fields/doubleEncodedString.py +++ b/vbaProjectCompiler/Models/Fields/doubleEncodedString.py @@ -1,15 +1,19 @@ from vbaProjectCompiler.Models.Fields.idSizeField import IdSizeField +from typing import TypeVar + + +T = TypeVar('T', bound='DoubleEncodedString') class DoubleEncodedString(): """ Encode text data twice with different ids and lengths """ - def __init__(self, ids: list, text: str) -> None: + def __init__(self: T, ids: list, text: str) -> None: self.ids = ids self.value = text - def pack(self, codepage_name, endien): + def pack(self: T, codepage_name: str, endien: str) -> bytes: encoded = self.value.encode(codepage_name) self.mod_name1 = IdSizeField(self.ids[0], len(encoded), encoded) format = "utf_16_le" if endien == 'little' else "utf_16_be" diff --git a/vbaProjectCompiler/Models/Fields/idSizeField.py b/vbaProjectCompiler/Models/Fields/idSizeField.py index b7f505b5f..cc6b5f061 100644 --- a/vbaProjectCompiler/Models/Fields/idSizeField.py +++ b/vbaProjectCompiler/Models/Fields/idSizeField.py @@ -1,4 +1,8 @@ import struct +from typing import Any, TypeVar + + +T = TypeVar('T', bound='IdSizeField') class IdSizeField(): @@ -7,12 +11,12 @@ class IdSizeField(): int value formatted to the defined size. """ - def __init__(self, id, size: int, value) -> None: + def __init__(self: T, id: int, size: int, value: Any) -> None: self._id = id self._size = size self._value = value - def pack(self, codepage_name: str, endien: str) -> bytes: + def pack(self: T, codepage_name: str, endien: str) -> bytes: endien_symbol = '<' if endien == 'little' else '>' format = endien_symbol + "HI" if isinstance(self._value, str): diff --git a/vbaProjectCompiler/Models/Fields/libidReference.py b/vbaProjectCompiler/Models/Fields/libid_reference.py similarity index 65% rename from vbaProjectCompiler/Models/Fields/libidReference.py rename to vbaProjectCompiler/Models/Fields/libid_reference.py index 05cbd0cbd..12fbb2de0 100644 --- a/vbaProjectCompiler/Models/Fields/libidReference.py +++ b/vbaProjectCompiler/Models/Fields/libid_reference.py @@ -1,6 +1,14 @@ +import uuid +from typing import TypeVar + + +T = TypeVar('T', bound='LibidReference') + + class LibidReference(): - def __init__(self, libid_guid, version, - libid_lcid, libid_path, libid_reg_name): + def __init__(self: T, libid_guid: uuid.UUID, version: str, + libid_lcid: str, libid_path: str, + libid_reg_name: str) -> None: self._libid_guid = libid_guid self._version = version self._libid_lcid = libid_lcid @@ -11,7 +19,7 @@ def __init__(self, libid_guid, version, else: self._libid_reference_kind = "H" - def __str__(self): + def __str__(self: T) -> str: return "*\\" + \ self._libid_reference_kind + \ "{" + str(self._libid_guid).upper() + "}#" + \ @@ -20,8 +28,8 @@ def __str__(self): str(self._libid_path) + "#" + \ self._libid_reg_name - def __len__(self): + def __len__(self: T) -> int: return len(str(self)) - def _is_windows_path(self, path): + def _is_windows_path(self: T, path: str) -> bool: return path[0] != '/' diff --git a/vbaProjectCompiler/Models/Fields/packedData.py b/vbaProjectCompiler/Models/Fields/packedData.py deleted file mode 100644 index 474e7acb3..000000000 --- a/vbaProjectCompiler/Models/Fields/packedData.py +++ /dev/null @@ -1,14 +0,0 @@ -import struct - - -class PackedData(): - """ - Mutivalue field with a packing format - """ - def __init__(self, format, *values) -> None: - self.values = values - self.format = format - - def pack(self, codepage_name, endien) -> bytes: - endien_symbol = '<' if endien == 'little' else '>' - return struct.pack(endien_symbol + self.format, *self.values) diff --git a/vbaProjectCompiler/Models/Fields/packed_data.py b/vbaProjectCompiler/Models/Fields/packed_data.py new file mode 100644 index 000000000..7ee87ae38 --- /dev/null +++ b/vbaProjectCompiler/Models/Fields/packed_data.py @@ -0,0 +1,18 @@ +import struct +from typing import Any, TypeVar + + +T = TypeVar('T', bound='PackedData') + + +class PackedData(): + """ + Multivalue field with a packing format + """ + def __init__(self: T, format: str, *values: Any) -> None: + self.values = values + self.format = format + + def pack(self: T, codepage_name: str, endien: str) -> bytes: + endien_symbol = '<' if endien == 'little' else '>' + return struct.pack(endien_symbol + self.format, *self.values) diff --git a/vbaProjectCompiler/Views/dirStream.py b/vbaProjectCompiler/Views/dirStream.py index 8257668fe..c2db98dcb 100644 --- a/vbaProjectCompiler/Views/dirStream.py +++ b/vbaProjectCompiler/Views/dirStream.py @@ -1,10 +1,15 @@ import struct from ms_ovba_compression.ms_ovba import MsOvba +from vbaProjectCompiler.vbaProject import VbaProject from vbaProjectCompiler.Models.Fields.idSizeField import IdSizeField from vbaProjectCompiler.Models.Fields.doubleEncodedString import ( DoubleEncodedString ) -from vbaProjectCompiler.Models.Fields.packedData import PackedData +from vbaProjectCompiler.Models.Fields.packed_data import PackedData +from typing import TypeVar + + +T = TypeVar('T', bound='DirStream') class DirStream(): @@ -12,7 +17,7 @@ class DirStream(): The dir stream is compressed on write """ - def __init__(self, project) -> None: + def __init__(self: T, project: VbaProject) -> None: self.project = project self.codepage = 0x04E4 # 0=16bit, 1=32bit, 2=mac, 3=64bit @@ -47,7 +52,7 @@ def __init__(self, project) -> None: self.references = [] self.modules = [] - def to_bytes(self) -> bytes: + def to_bytes(self: T) -> bytes: endien = self.project.endien codepage_name = self.project.get_codepage_name() pack_symbol = '<' if endien == 'little' else '>' @@ -71,7 +76,7 @@ def to_bytes(self) -> bytes: output += struct.pack(pack_symbol + "HI", 16, 0) return output - def write_file(self): + def write_file(self: T) -> None: bin_f = open("dir.bin", "wb") ms_ovba = MsOvba() compressed = ms_ovba.compress(self.to_bytes()) diff --git a/vbaProjectCompiler/Views/project.py b/vbaProjectCompiler/Views/project.py index e47fe4c7e..1b43e123e 100644 --- a/vbaProjectCompiler/Views/project.py +++ b/vbaProjectCompiler/Views/project.py @@ -1,12 +1,17 @@ import binascii import ms_ovba_crypto +from vbaProjectCompiler.vbaProject import VbaProject +from typing import TypeVar + + +T = TypeVar('T', bound='Project') class Project: """ The Project data view for the vbaProject """ - def __init__(self, project) -> None: + def __init__(self: T, project: VbaProject) -> None: self.project = project # Attributes @@ -16,10 +21,10 @@ def __init__(self, project) -> None: # The HostExtenderInfo string self.hostExtenderInfo = "" - def add_attribute(self, name, value) -> None: + def add_attribute(self: T, name: str, value: str) -> None: self.attributes[name] = value - def to_bytes(self): + def to_bytes(self: T) -> bytes: project = self.project codepage_name = project.get_codepage_name() # Use \x0D0A line endings...however python encodes that. @@ -62,12 +67,12 @@ def to_bytes(self): result += eol return result - def write_file(self): + def write_file(self: T) -> None: bin_f = open("project.bin", "wb") bin_f.write(self.to_bytes()) bin_f.close() - def _attr(self, name, value): + def _attr(self: T, name: str, value: str) -> str: codepage_name = self.project.get_codepage_name() eol = b'\x0D\x0A' b_name = bytes(name, codepage_name) diff --git a/vbaProjectCompiler/Views/projectWm.py b/vbaProjectCompiler/Views/projectWm.py index 3922ca66b..266972ec4 100644 --- a/vbaProjectCompiler/Views/projectWm.py +++ b/vbaProjectCompiler/Views/projectWm.py @@ -1,11 +1,18 @@ +from vbaProjectCompiler.vbaProject import VbaProject +from typing import TypeVar + + +T = TypeVar('T', bound='ProjectWm') + + class ProjectWm: """ The ProjectWM data view for the vbaProject """ - def __init__(self, project): + def __init__(self: T, project: VbaProject) -> None: self.project = project - def to_bytes(self): + def to_bytes(self: T) -> bytes: output = b'' for module in self.project.modules: output += (bytes(module.modName.value, 'ascii') @@ -15,7 +22,7 @@ def to_bytes(self): output += b'\x00\x00' return output - def write_file(self): + def write_file(self: T) -> None: bin_f = open("project.bin", "wb") bin_f.write(self.to_bytes()) bin_f.close() diff --git a/vbaProjectCompiler/Views/project_ole_file.py b/vbaProjectCompiler/Views/project_ole_file.py new file mode 100644 index 000000000..b8d53b3ba --- /dev/null +++ b/vbaProjectCompiler/Views/project_ole_file.py @@ -0,0 +1,51 @@ +from vbaProjectCompiler.vbaProject import VbaProject +from vbaProjectCompiler.Views.dirStream import DirStream +# from vbaProjectCompiler.Views.project_view import ProjectView +from vbaProjectCompiler.Views.project import Project +from vbaProjectCompiler.Views.projectWm import ProjectWm +from typing import TypeVar + + +T = TypeVar('T', bound='ProjectOleFile') + + +class ProjectOleFile: + + def __init__(self: T, project: VbaProject) -> None: + self._project = project + + def _create_binary_files(self: T) -> None: + for module in self._project.get_modules(): + module.write_file() + dir = DirStream(self._project) + dir.write_file() + project = Project(self._project) + project.write_file() + project_wm = ProjectWm(self._project) + project_wm.write_file() + # views = ("_VBA_PROJECT", "dir", "project_wm", "Project") + # Create views and write + + def _build_ole_directory(self: T) -> None: + # directory = StorageDirectory() + # directory.set_name("VBA") + for module in self._project.get_modules(): + # path = module.get_name() + '.bin' + # dir = StreamDirectory() + # dir.set_name(module.get_name()) + # dir.add_stream(path) + # directory.add_directory(dir) + pass + # return directory + + def _write_ole_file(self: T, dir: str) -> None: + # ole_file = OleFile() + # ole_file.add_directory(dir) + # ole_file.build_file() + # ole_file.write_file("vbaProject.bin") + pass + + def write_file(self: T) -> None: + self._create_binary_files() + directory = self._build_ole_directory() + self._write_ole_file(directory) diff --git a/vbaProjectCompiler/Views/project_view.py b/vbaProjectCompiler/Views/project_view.py index 939104fab..9a82e33c0 100644 --- a/vbaProjectCompiler/Views/project_view.py +++ b/vbaProjectCompiler/Views/project_view.py @@ -1,14 +1,19 @@ import struct +from vbaProjectCompiler.vbaProject import VbaProject +from typing import TypeVar + + +T = TypeVar('T', bound='ProjectView') class ProjectView: """ The _VBA_PROJECT data view for the vbaProject """ - def __init__(self, project) -> None: + def __init__(self: T, project: VbaProject) -> None: self.project = project - def to_bytes(self) -> bytes: + def to_bytes(self: T) -> bytes: endien_symbol = '<' if self.project.endien == 'little' else '>' format = endien_symbol + "HHBH" output = b'' @@ -21,7 +26,7 @@ def to_bytes(self) -> bytes: reserved2, reserved3) return output + self.project.get_performance_cache() - def write_file(self) -> None: + def write_file(self: T) -> None: bin_f = open("vba_project.bin", "wb") bin_f.write(self.to_bytes()) bin_f.close() diff --git a/vbaProjectCompiler/main.py b/vbaProjectCompiler/main.py index 6df828706..05b1038b6 100644 --- a/vbaProjectCompiler/main.py +++ b/vbaProjectCompiler/main.py @@ -1,2 +1,2 @@ -def main(args): +def main(args: list) -> None: pass diff --git a/vbaProjectCompiler/vbaProject.py b/vbaProjectCompiler/vbaProject.py index 9dd08d613..ed1976fc0 100644 --- a/vbaProjectCompiler/vbaProject.py +++ b/vbaProjectCompiler/vbaProject.py @@ -1,11 +1,8 @@ # from ms_cfb import OleFile # from ms_cfb.Models.Directories.storage_directory import StorageDirectory # from ms_cfb.Models.Directories.stream_directory import StreamDirectory - -from vbaProjectCompiler.Views.dirStream import DirStream -# from vbaProjectCompiler.Views.project_view import ProjectView -from vbaProjectCompiler.Views.project import Project -from vbaProjectCompiler.Views.projectWm import ProjectWm +from vbaProjectCompiler.Models.Entities.module_base import ModuleBase +from vbaProjectCompiler.Models.Entities.reference_record import ReferenceRecord from typing import TypeVar @@ -47,7 +44,7 @@ def set_protection_state(self: T, state: int) -> None: def get_protection_state(self: T) -> int: return self._protection_state - def set_visibility_state(self: T, state) -> None: + def set_visibility_state(self: T, state: int) -> None: """ 0 = not visible 255 = visible @@ -56,13 +53,13 @@ def set_visibility_state(self: T, state) -> None: raise Exception("Bad visibility value.") self._visibility_state = state - def get_visibility_state(self: T): + def get_visibility_state(self: T) -> bytes: return self._visibility_state - def set_password(self: T, value) -> None: + def set_password(self: T, value: bytes) -> None: self._password = value - def get_password(self): + def get_password(self: T) -> bytes: return self._password def set_performance_cache(self: T, cache: bytes) -> None: @@ -86,45 +83,12 @@ def set_project_cookie(self: T, value: int) -> None: def get_project_cookie(self: T) -> int: return self._project_cookie + def get_modules(self: T) -> list: + return self.modules + # Appenders - def add_module(self: T, ref) -> None: - self.modules.append(ref) + def add_module(self: T, mod: ModuleBase) -> None: + self.modules.append(mod) - def add_reference(self: T, ref) -> None: + def add_reference(self: T, ref: ReferenceRecord) -> None: self.references.append(ref) - - def _create_binary_files(self: T) -> None: - for module in self.modules: - module.write_file() - dir = DirStream(self) - dir.write_file() - project = Project(self) - project.write_file() - project_wm = ProjectWm(self) - project_wm.write_file() - # views = ("_VBA_PROJECT", "dir", "project_wm", "Project") - # Create views and write - - def _build_ole_directory(self: T) -> None: - # directory = StorageDirectory() - # directory.set_name("VBA") - for module in self.modules: - # path = module.get_name() + '.bin' - # dir = StreamDirectory() - # dir.set_name(module.get_name()) - # dir.add_stream(path) - # directory.add_directory(dir) - pass - # return directory - - def _write_ole_file(self: T, dir) -> None: - # ole_file = OleFile() - # ole_file.add_directory(dir) - # ole_file.build_file() - # ole_file.write_file("vbaProject.bin") - pass - - def write_file(self: T) -> None: - self._create_binary_files() - directory = self._build_ole_directory() - self._write_ole_file(directory) From c4cc4fe9bc010490cb5b526773127c4eec6f56f5 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Mon, 3 Apr 2023 12:53:08 -0400 Subject: [PATCH 009/335] Update README.md --- README.md | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/README.md b/README.md index 9d6080ed1..259ff2fe3 100644 --- a/README.md +++ b/README.md @@ -37,20 +37,3 @@ libidRef = LibidReference( oleReference = ReferenceRecord(codePageName, "stdole", libidRef) project.addReference(oleReference) ``` - -## oleFile Class - -Users should not have to interact with the oleFile class. It's job is to extract the data from the vbaProject and turn it into a valid file. This includes deciding which data stream appears where, and applying different views to the models to save the data in the correct formats. - -The oleFIle has two parts, a header and a FAT Sector Chain. This FAT chain stores multiple streams of data: -* Fat Chain Stream -* Directory Stream -* Minifat Chain Stream -* Minifat Data Stream -* Fat Data Stream - -These are all different views of data from the following Models - -* fatChain -* minifatChain -* directoryStream From b231bdb6a075394780347e12ac391ee6a2162b61 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Tue, 4 Apr 2023 08:40:20 -0400 Subject: [PATCH 010/335] Reorganize (#103) --- .github/workflows/python-package.yml | 2 +- pyproject.toml | 2 +- setup.py | 7 ------ .../Models/Entities/doc_module.py | 2 +- .../Models/Entities/module_base.py | 6 ++--- .../Models/Entities/reference_record.py | 6 ++--- .../Models/Entities/std_module.py | 2 +- .../Models/Fields/doubleEncodedString.py | 2 +- .../Models/Fields/idSizeField.py | 0 .../Models/Fields/libid_reference.py | 0 .../Models/Fields/packed_data.py | 0 .../vbaproject_compiler}/Views/dirStream.py | 8 +++---- .../vbaproject_compiler}/Views/project.py | 2 +- .../vbaproject_compiler}/Views/projectWm.py | 2 +- .../Views/project_ole_file.py | 10 ++++---- .../Views/project_view.py | 2 +- src/vbaproject_compiler/__init__.py | 1 + .../blank_files/Sheet1.cls | 0 .../blank_files/ThisWorkbook.cls | 0 .../vbaproject_compiler}/main.py | 0 .../vbaproject_compiler}/vbaProject.py | 9 ++++--- tests/Functional/test_dirObject.py | 14 ++++++----- tests/Functional/test_fullFile.py | 24 ++++++++++--------- tests/Unit/Models/Entities/test_doc_module.py | 4 ++-- tests/Unit/Models/Entities/test_std_module.py | 2 +- tests/Unit/Models/Fields/test_idSizeField.py | 2 +- .../Unit/Models/Fields/test_libidReference.py | 2 +- tests/Unit/Models/test_vbaProject.py | 2 +- tests/Views/test_project.py | 8 +++---- tests/Views/test_projectWm.py | 8 +++---- tests/Views/test_vba_project.py | 4 ++-- .../Models/Entities/__init__.py | 1 - vbaProjectCompiler/Models/Fields/__init__.py | 1 - vbaProjectCompiler/__init__.py | 1 - 34 files changed, 65 insertions(+), 71 deletions(-) delete mode 100644 setup.py rename {vbaProjectCompiler => src/vbaproject_compiler}/Models/Entities/doc_module.py (95%) rename {vbaProjectCompiler => src/vbaproject_compiler}/Models/Entities/module_base.py (93%) rename {vbaProjectCompiler => src/vbaproject_compiler}/Models/Entities/reference_record.py (80%) rename {vbaProjectCompiler => src/vbaproject_compiler}/Models/Entities/std_module.py (86%) rename {vbaProjectCompiler => src/vbaproject_compiler}/Models/Fields/doubleEncodedString.py (91%) rename {vbaProjectCompiler => src/vbaproject_compiler}/Models/Fields/idSizeField.py (100%) rename {vbaProjectCompiler => src/vbaproject_compiler}/Models/Fields/libid_reference.py (100%) rename {vbaProjectCompiler => src/vbaproject_compiler}/Models/Fields/packed_data.py (100%) rename {vbaProjectCompiler => src/vbaproject_compiler}/Views/dirStream.py (91%) rename {vbaProjectCompiler => src/vbaproject_compiler}/Views/project.py (98%) rename {vbaProjectCompiler => src/vbaproject_compiler}/Views/projectWm.py (93%) rename {vbaProjectCompiler => src/vbaproject_compiler}/Views/project_ole_file.py (83%) rename {vbaProjectCompiler => src/vbaproject_compiler}/Views/project_view.py (94%) create mode 100644 src/vbaproject_compiler/__init__.py rename {vbaProjectCompiler => src/vbaproject_compiler}/blank_files/Sheet1.cls (100%) rename {vbaProjectCompiler => src/vbaproject_compiler}/blank_files/ThisWorkbook.cls (100%) rename {vbaProjectCompiler => src/vbaproject_compiler}/main.py (100%) rename {vbaProjectCompiler => src/vbaproject_compiler}/vbaProject.py (88%) delete mode 100644 vbaProjectCompiler/Models/Entities/__init__.py delete mode 100644 vbaProjectCompiler/Models/Fields/__init__.py delete mode 100644 vbaProjectCompiler/__init__.py diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index f68e4d390..c4031c37a 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -42,7 +42,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - pytest --cov=vbaProjectCompiler + pytest --cov=src coveralls --service=github flake8: diff --git a/pyproject.toml b/pyproject.toml index 8dd59b357..034507569 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta" [project] -name = "vba_project_compiler" +name = "vbaproject_compiler" version = "0.0.1" authors = [ { name="Kevin Nowaczyk", email="beakerboy99@yahoo.com" }, diff --git a/setup.py b/setup.py deleted file mode 100644 index dd30318df..000000000 --- a/setup.py +++ /dev/null @@ -1,7 +0,0 @@ -from setuptools import setup - -setup( - name="vbaProjectCompiler", - packages=['vbaProjectCompiler'], - tests_require=['pytest'], -) diff --git a/vbaProjectCompiler/Models/Entities/doc_module.py b/src/vbaproject_compiler/Models/Entities/doc_module.py similarity index 95% rename from vbaProjectCompiler/Models/Entities/doc_module.py rename to src/vbaproject_compiler/Models/Entities/doc_module.py index 21ce03e91..cbb3e3111 100644 --- a/vbaProjectCompiler/Models/Entities/doc_module.py +++ b/src/vbaproject_compiler/Models/Entities/doc_module.py @@ -1,5 +1,5 @@ from ms_ovba_compression.ms_ovba import MsOvba -from vbaProjectCompiler.Models.Entities.module_base import ModuleBase +from vbaproject_compiler.Models.Entities.module_base import ModuleBase from typing import TypeVar diff --git a/vbaProjectCompiler/Models/Entities/module_base.py b/src/vbaproject_compiler/Models/Entities/module_base.py similarity index 93% rename from vbaProjectCompiler/Models/Entities/module_base.py rename to src/vbaproject_compiler/Models/Entities/module_base.py index 5763adba9..f6dbeafa7 100644 --- a/vbaProjectCompiler/Models/Entities/module_base.py +++ b/src/vbaproject_compiler/Models/Entities/module_base.py @@ -1,9 +1,9 @@ from ms_ovba_compression.ms_ovba import MsOvba -from vbaProjectCompiler.Models.Fields.doubleEncodedString import ( +from vbaproject_compiler.Models.Fields.doubleEncodedString import ( DoubleEncodedString ) -from vbaProjectCompiler.Models.Fields.packed_data import PackedData -from vbaProjectCompiler.Models.Fields.idSizeField import IdSizeField +from vbaproject_compiler.Models.Fields.packed_data import PackedData +from vbaproject_compiler.Models.Fields.idSizeField import IdSizeField from typing import TypeVar diff --git a/vbaProjectCompiler/Models/Entities/reference_record.py b/src/vbaproject_compiler/Models/Entities/reference_record.py similarity index 80% rename from vbaProjectCompiler/Models/Entities/reference_record.py rename to src/vbaproject_compiler/Models/Entities/reference_record.py index 358b03ae9..76fba03b4 100644 --- a/vbaProjectCompiler/Models/Entities/reference_record.py +++ b/src/vbaproject_compiler/Models/Entities/reference_record.py @@ -1,8 +1,8 @@ -from vbaProjectCompiler.Models.Fields.doubleEncodedString import ( +from vbaproject_compiler.Models.Fields.doubleEncodedString import ( DoubleEncodedString ) -from vbaProjectCompiler.Models.Fields.libid_reference import LibidReference -from vbaProjectCompiler.Models.Fields.packed_data import PackedData +from vbaproject_compiler.Models.Fields.libid_reference import LibidReference +from vbaproject_compiler.Models.Fields.packed_data import PackedData from typing import TypeVar diff --git a/vbaProjectCompiler/Models/Entities/std_module.py b/src/vbaproject_compiler/Models/Entities/std_module.py similarity index 86% rename from vbaProjectCompiler/Models/Entities/std_module.py rename to src/vbaproject_compiler/Models/Entities/std_module.py index c4859527f..b517e8fdf 100644 --- a/vbaProjectCompiler/Models/Entities/std_module.py +++ b/src/vbaproject_compiler/Models/Entities/std_module.py @@ -1,4 +1,4 @@ -from vbaProjectCompiler.Models.Entities.module_base import ModuleBase +from vbaproject_compiler.Models.Entities.module_base import ModuleBase from typing import TypeVar diff --git a/vbaProjectCompiler/Models/Fields/doubleEncodedString.py b/src/vbaproject_compiler/Models/Fields/doubleEncodedString.py similarity index 91% rename from vbaProjectCompiler/Models/Fields/doubleEncodedString.py rename to src/vbaproject_compiler/Models/Fields/doubleEncodedString.py index 711b92e81..04da1e9fe 100644 --- a/vbaProjectCompiler/Models/Fields/doubleEncodedString.py +++ b/src/vbaproject_compiler/Models/Fields/doubleEncodedString.py @@ -1,4 +1,4 @@ -from vbaProjectCompiler.Models.Fields.idSizeField import IdSizeField +from vbaproject_compiler.Models.Fields.idSizeField import IdSizeField from typing import TypeVar diff --git a/vbaProjectCompiler/Models/Fields/idSizeField.py b/src/vbaproject_compiler/Models/Fields/idSizeField.py similarity index 100% rename from vbaProjectCompiler/Models/Fields/idSizeField.py rename to src/vbaproject_compiler/Models/Fields/idSizeField.py diff --git a/vbaProjectCompiler/Models/Fields/libid_reference.py b/src/vbaproject_compiler/Models/Fields/libid_reference.py similarity index 100% rename from vbaProjectCompiler/Models/Fields/libid_reference.py rename to src/vbaproject_compiler/Models/Fields/libid_reference.py diff --git a/vbaProjectCompiler/Models/Fields/packed_data.py b/src/vbaproject_compiler/Models/Fields/packed_data.py similarity index 100% rename from vbaProjectCompiler/Models/Fields/packed_data.py rename to src/vbaproject_compiler/Models/Fields/packed_data.py diff --git a/vbaProjectCompiler/Views/dirStream.py b/src/vbaproject_compiler/Views/dirStream.py similarity index 91% rename from vbaProjectCompiler/Views/dirStream.py rename to src/vbaproject_compiler/Views/dirStream.py index c2db98dcb..046708e05 100644 --- a/vbaProjectCompiler/Views/dirStream.py +++ b/src/vbaproject_compiler/Views/dirStream.py @@ -1,11 +1,11 @@ import struct from ms_ovba_compression.ms_ovba import MsOvba -from vbaProjectCompiler.vbaProject import VbaProject -from vbaProjectCompiler.Models.Fields.idSizeField import IdSizeField -from vbaProjectCompiler.Models.Fields.doubleEncodedString import ( +from vbaproject_compiler.vbaProject import VbaProject +from vbaproject_compiler.Models.Fields.idSizeField import IdSizeField +from vbaproject_compiler.Models.Fields.doubleEncodedString import ( DoubleEncodedString ) -from vbaProjectCompiler.Models.Fields.packed_data import PackedData +from vbaproject_compiler.Models.Fields.packed_data import PackedData from typing import TypeVar diff --git a/vbaProjectCompiler/Views/project.py b/src/vbaproject_compiler/Views/project.py similarity index 98% rename from vbaProjectCompiler/Views/project.py rename to src/vbaproject_compiler/Views/project.py index 1b43e123e..9d88ec7fc 100644 --- a/vbaProjectCompiler/Views/project.py +++ b/src/vbaproject_compiler/Views/project.py @@ -1,6 +1,6 @@ import binascii import ms_ovba_crypto -from vbaProjectCompiler.vbaProject import VbaProject +from vbaproject_compiler.vbaProject import VbaProject from typing import TypeVar diff --git a/vbaProjectCompiler/Views/projectWm.py b/src/vbaproject_compiler/Views/projectWm.py similarity index 93% rename from vbaProjectCompiler/Views/projectWm.py rename to src/vbaproject_compiler/Views/projectWm.py index 266972ec4..a47054676 100644 --- a/vbaProjectCompiler/Views/projectWm.py +++ b/src/vbaproject_compiler/Views/projectWm.py @@ -1,4 +1,4 @@ -from vbaProjectCompiler.vbaProject import VbaProject +from vbaproject_compiler.vbaProject import VbaProject from typing import TypeVar diff --git a/vbaProjectCompiler/Views/project_ole_file.py b/src/vbaproject_compiler/Views/project_ole_file.py similarity index 83% rename from vbaProjectCompiler/Views/project_ole_file.py rename to src/vbaproject_compiler/Views/project_ole_file.py index b8d53b3ba..50f8fa320 100644 --- a/vbaProjectCompiler/Views/project_ole_file.py +++ b/src/vbaproject_compiler/Views/project_ole_file.py @@ -1,8 +1,8 @@ -from vbaProjectCompiler.vbaProject import VbaProject -from vbaProjectCompiler.Views.dirStream import DirStream -# from vbaProjectCompiler.Views.project_view import ProjectView -from vbaProjectCompiler.Views.project import Project -from vbaProjectCompiler.Views.projectWm import ProjectWm +from vbaproject_compiler.vbaProject import VbaProject +from vbaproject_compiler.Views.dirStream import DirStream +# from vbaproject_compiler.Views.project_view import ProjectView +from vbaproject_compiler.Views.project import Project +from vbaproject_compiler.Views.projectWm import ProjectWm from typing import TypeVar diff --git a/vbaProjectCompiler/Views/project_view.py b/src/vbaproject_compiler/Views/project_view.py similarity index 94% rename from vbaProjectCompiler/Views/project_view.py rename to src/vbaproject_compiler/Views/project_view.py index 9a82e33c0..e15cf81d3 100644 --- a/vbaProjectCompiler/Views/project_view.py +++ b/src/vbaproject_compiler/Views/project_view.py @@ -1,5 +1,5 @@ import struct -from vbaProjectCompiler.vbaProject import VbaProject +from vbaproject_compiler.vbaProject import VbaProject from typing import TypeVar diff --git a/src/vbaproject_compiler/__init__.py b/src/vbaproject_compiler/__init__.py new file mode 100644 index 000000000..308ec1db4 --- /dev/null +++ b/src/vbaproject_compiler/__init__.py @@ -0,0 +1 @@ +# comment diff --git a/vbaProjectCompiler/blank_files/Sheet1.cls b/src/vbaproject_compiler/blank_files/Sheet1.cls similarity index 100% rename from vbaProjectCompiler/blank_files/Sheet1.cls rename to src/vbaproject_compiler/blank_files/Sheet1.cls diff --git a/vbaProjectCompiler/blank_files/ThisWorkbook.cls b/src/vbaproject_compiler/blank_files/ThisWorkbook.cls similarity index 100% rename from vbaProjectCompiler/blank_files/ThisWorkbook.cls rename to src/vbaproject_compiler/blank_files/ThisWorkbook.cls diff --git a/vbaProjectCompiler/main.py b/src/vbaproject_compiler/main.py similarity index 100% rename from vbaProjectCompiler/main.py rename to src/vbaproject_compiler/main.py diff --git a/vbaProjectCompiler/vbaProject.py b/src/vbaproject_compiler/vbaProject.py similarity index 88% rename from vbaProjectCompiler/vbaProject.py rename to src/vbaproject_compiler/vbaProject.py index ed1976fc0..acff144e9 100644 --- a/vbaProjectCompiler/vbaProject.py +++ b/src/vbaproject_compiler/vbaProject.py @@ -1,8 +1,7 @@ -# from ms_cfb import OleFile -# from ms_cfb.Models.Directories.storage_directory import StorageDirectory -# from ms_cfb.Models.Directories.stream_directory import StreamDirectory -from vbaProjectCompiler.Models.Entities.module_base import ModuleBase -from vbaProjectCompiler.Models.Entities.reference_record import ReferenceRecord +from vbaproject_compiler.Models.Entities.module_base import ModuleBase +from vbaproject_compiler.Models.Entities.reference_record import ( + ReferenceRecord +) from typing import TypeVar diff --git a/tests/Functional/test_dirObject.py b/tests/Functional/test_dirObject.py index 72b6dd754..c0340d8bd 100644 --- a/tests/Functional/test_dirObject.py +++ b/tests/Functional/test_dirObject.py @@ -2,12 +2,14 @@ import uuid from ms_ovba_compression.ms_ovba import MsOvba from ms_pcode_assembler.module_cache import ModuleCache -from vbaProjectCompiler.vbaProject import VbaProject -from vbaProjectCompiler.Views.dirStream import DirStream -from vbaProjectCompiler.Models.Fields.libid_reference import LibidReference -from vbaProjectCompiler.Models.Entities.doc_module import DocModule -from vbaProjectCompiler.Models.Entities.std_module import StdModule -from vbaProjectCompiler.Models.Entities.reference_record import ReferenceRecord +from vbaproject_compiler.vbaProject import VbaProject +from vbaproject_compiler.Views.dirStream import DirStream +from vbaproject_compiler.Models.Fields.libid_reference import LibidReference +from vbaproject_compiler.Models.Entities.doc_module import DocModule +from vbaproject_compiler.Models.Entities.std_module import StdModule +from vbaproject_compiler.Models.Entities.reference_record import ( + ReferenceRecord +) def test_dirstream() -> None: diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 03b8ce1cf..d979fda81 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -5,12 +5,14 @@ import uuid from ms_ovba_compression.ms_ovba import MsOvba from ms_pcode_assembler.module_cache import ModuleCache -from vbaProjectCompiler.vbaProject import VbaProject -from vbaProjectCompiler.Models.Entities.doc_module import DocModule -from vbaProjectCompiler.Models.Entities.std_module import StdModule -from vbaProjectCompiler.Models.Entities.reference_record import ReferenceRecord -from vbaProjectCompiler.Models.Fields.libid_reference import LibidReference -from vbaProjectCompiler.Views.project_ole_file import ProjectOleFile +from vbaproject_compiler.vbaProject import VbaProject +from vbaproject_compiler.Models.Entities.doc_module import DocModule +from vbaproject_compiler.Models.Entities.std_module import StdModule +from vbaproject_compiler.Models.Entities.reference_record import ( + ReferenceRecord +) +from vbaproject_compiler.Models.Fields.libid_reference import LibidReference +from vbaproject_compiler.Views.project_ole_file import ProjectOleFile from typing import Type, TypeVar @@ -36,7 +38,7 @@ def run_around_tests() -> None: # A test function will be run at this point yield # Code that will run after your test - root = "vbaProjectCompiler/blank_files/" + root = "src/vbaproject_compiler/blank_files/" root2 = "tests/blank/" names = [root + "ThisWorkbook.cls", root + "Sheet1.cls", root2 + "Module1.bas"] @@ -116,7 +118,7 @@ def test_full_file() -> None: guid = uuid.UUID("0002081900000000C000000000000046") module_cache.guid = [guid] this_workbook.set_guid(guid) - module_path = "vbaProjectCompiler/blank_files/ThisWorkbook.cls" + module_path = "src/vbaproject_compiler/blank_files/ThisWorkbook.cls" this_workbook.add_file(module_path) this_workbook.normalize_file() this_workbook.set_cache(module_cache.to_bytes()) @@ -127,7 +129,7 @@ def test_full_file() -> None: guid = uuid.UUID("0002082000000000C000000000000046") module_cache.guid = [guid] sheet1.set_guid(guid) - module_path = "vbaProjectCompiler/blank_files/Sheet1.cls" + module_path = "src/vbaproject_compiler/blank_files/Sheet1.cls" sheet1.add_file(module_path) sheet1.normalize_file() sheet1.set_cache(module_cache.to_bytes()) @@ -150,10 +152,10 @@ def test_full_file() -> None: ole_file = ProjectOleFile(project) ole_file.write_file() - path = "vbaProjectCompiler/blank_files/ThisWorkbook.cls.bin" + path = "src/vbaproject_compiler/blank_files/ThisWorkbook.cls.bin" assert module_matches_bin(path, 0x0333, "tests/blank/vbaProject.bin", 0x0800, 0xB5) - path = "vbaProjectCompiler/blank_files/Sheet1.cls.bin" + path = "src/vbaproject_compiler/blank_files/Sheet1.cls.bin" assert module_matches_bin(path, 0x0333, "tests/blank/vbaProject.bin", 0x0C00, 0xAC) diff --git a/tests/Unit/Models/Entities/test_doc_module.py b/tests/Unit/Models/Entities/test_doc_module.py index fc59f3951..cb76be0d1 100644 --- a/tests/Unit/Models/Entities/test_doc_module.py +++ b/tests/Unit/Models/Entities/test_doc_module.py @@ -1,7 +1,7 @@ import uuid from ms_ovba_compression.ms_ovba import MsOvba from ms_pcode_assembler.module_cache import ModuleCache -from vbaProjectCompiler.Models.Entities.doc_module import DocModule +from vbaproject_compiler.Models.Entities.doc_module import DocModule def test_normalize() -> None: @@ -23,7 +23,7 @@ def test_normalize() -> None: cache.object_table = bytes.fromhex(" ".join(object_table)) module = DocModule("foo") - path1 = "vbaProjectCompiler/blank_files/ThisWorkbook.cls" + path1 = "src/vbaproject_compiler/blank_files/ThisWorkbook.cls" module.add_file(path1) module.cookie.value = 0xB81C guid = uuid.UUID('0002081900000000C000000000000046') diff --git a/tests/Unit/Models/Entities/test_std_module.py b/tests/Unit/Models/Entities/test_std_module.py index 15eac0667..2b7730ef3 100644 --- a/tests/Unit/Models/Entities/test_std_module.py +++ b/tests/Unit/Models/Entities/test_std_module.py @@ -1,4 +1,4 @@ -from vbaProjectCompiler.Models.Entities.std_module import StdModule +from vbaproject_compiler.Models.Entities.std_module import StdModule def test_set_get_cache() -> None: diff --git a/tests/Unit/Models/Fields/test_idSizeField.py b/tests/Unit/Models/Fields/test_idSizeField.py index 071ec3569..fe8573c19 100644 --- a/tests/Unit/Models/Fields/test_idSizeField.py +++ b/tests/Unit/Models/Fields/test_idSizeField.py @@ -1,5 +1,5 @@ import pytest -from vbaProjectCompiler.Models.Fields.idSizeField import IdSizeField +from vbaproject_compiler.Models.Fields.idSizeField import IdSizeField def test_bad_value() -> None: diff --git a/tests/Unit/Models/Fields/test_libidReference.py b/tests/Unit/Models/Fields/test_libidReference.py index 02590c9e6..d6261a350 100644 --- a/tests/Unit/Models/Fields/test_libidReference.py +++ b/tests/Unit/Models/Fields/test_libidReference.py @@ -1,5 +1,5 @@ import uuid -from vbaProjectCompiler.Models.Fields.libid_reference import LibidReference +from vbaproject_compiler.Models.Fields.libid_reference import LibidReference def test_str() -> None: diff --git a/tests/Unit/Models/test_vbaProject.py b/tests/Unit/Models/test_vbaProject.py index 5066ed903..77de05547 100644 --- a/tests/Unit/Models/test_vbaProject.py +++ b/tests/Unit/Models/test_vbaProject.py @@ -1,5 +1,5 @@ import pytest -from vbaProjectCompiler.vbaProject import VbaProject +from vbaproject_compiler.vbaProject import VbaProject def test_set_get_visibility() -> None: diff --git a/tests/Views/test_project.py b/tests/Views/test_project.py index a0a7f7927..38bf2e18f 100644 --- a/tests/Views/test_project.py +++ b/tests/Views/test_project.py @@ -1,9 +1,9 @@ import unittest.mock -from vbaProjectCompiler.vbaProject import VbaProject -from vbaProjectCompiler.Models.Entities.doc_module import DocModule -from vbaProjectCompiler.Models.Entities.std_module import StdModule -from vbaProjectCompiler.Views.project import Project +from vbaproject_compiler.vbaProject import VbaProject +from vbaproject_compiler.Models.Entities.doc_module import DocModule +from vbaproject_compiler.Models.Entities.std_module import StdModule +from vbaproject_compiler.Views.project import Project from typing import Type, TypeVar diff --git a/tests/Views/test_projectWm.py b/tests/Views/test_projectWm.py index 31e2c9f83..d14390a5c 100644 --- a/tests/Views/test_projectWm.py +++ b/tests/Views/test_projectWm.py @@ -1,7 +1,7 @@ -from vbaProjectCompiler.vbaProject import VbaProject -from vbaProjectCompiler.Models.Entities.doc_module import DocModule -from vbaProjectCompiler.Models.Entities.std_module import StdModule -from vbaProjectCompiler.Views.projectWm import ProjectWm +from vbaproject_compiler.vbaProject import VbaProject +from vbaproject_compiler.Models.Entities.doc_module import DocModule +from vbaproject_compiler.Models.Entities.std_module import StdModule +from vbaproject_compiler.Views.projectWm import ProjectWm def test_project_wm() -> None: diff --git a/tests/Views/test_vba_project.py b/tests/Views/test_vba_project.py index e33750e30..80506973a 100644 --- a/tests/Views/test_vba_project.py +++ b/tests/Views/test_vba_project.py @@ -1,5 +1,5 @@ -from vbaProjectCompiler.vbaProject import VbaProject -from vbaProjectCompiler.Views.project_view import ProjectView +from vbaproject_compiler.vbaProject import VbaProject +from vbaproject_compiler.Views.project_view import ProjectView def test_vba_project() -> None: diff --git a/vbaProjectCompiler/Models/Entities/__init__.py b/vbaProjectCompiler/Models/Entities/__init__.py deleted file mode 100644 index 33123adf7..000000000 --- a/vbaProjectCompiler/Models/Entities/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# Does a comment help this pass? diff --git a/vbaProjectCompiler/Models/Fields/__init__.py b/vbaProjectCompiler/Models/Fields/__init__.py deleted file mode 100644 index 33123adf7..000000000 --- a/vbaProjectCompiler/Models/Fields/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# Does a comment help this pass? diff --git a/vbaProjectCompiler/__init__.py b/vbaProjectCompiler/__init__.py deleted file mode 100644 index 33123adf7..000000000 --- a/vbaProjectCompiler/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# Does a comment help this pass? From 11f2e03d4152c9b58da7737c7e5d8f8e5c4a514b Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Tue, 4 Apr 2023 09:46:06 -0400 Subject: [PATCH 011/335] Update projectWm.py --- src/vbaproject_compiler/Views/projectWm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vbaproject_compiler/Views/projectWm.py b/src/vbaproject_compiler/Views/projectWm.py index a47054676..fc651cf4e 100644 --- a/src/vbaproject_compiler/Views/projectWm.py +++ b/src/vbaproject_compiler/Views/projectWm.py @@ -23,6 +23,6 @@ def to_bytes(self: T) -> bytes: return output def write_file(self: T) -> None: - bin_f = open("project.bin", "wb") + bin_f = open("projectwm.bin", "wb") bin_f.write(self.to_bytes()) bin_f.close() From a9c3d677e486abead0c1187048cdad31b5293fdd Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Tue, 2 May 2023 13:41:07 -0400 Subject: [PATCH 012/335] Olefile (#104) --- README.md | 7 +- .../Models/Entities/module_base.py | 3 + .../Views/project_ole_file.py | 77 +++++++++------- tests/Functional/test_fullFile.py | 87 ++++++++++--------- 4 files changed, 98 insertions(+), 76 deletions(-) diff --git a/README.md b/README.md index 259ff2fe3..5e32fa898 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ The vbaProject class contains all the data and metadata that will be used to cre ```python from vbaProjectCompiler.vbaProject import VbaProject -from vbaProjectCompiler.ole_file import OleFile +from ms_cfb.ole_file import OleFile project = VbaProject() @@ -18,16 +18,15 @@ thisWorkbook.addFile(path) project.addModule(thisWorkbook) ole_file = OleFile(project) -ole_file.writeFile(".") +ole_file.create_file(".") ``` -The VbaProject class has many layers of customization available. Forexample a librry referenece can be added to the project. +The VbaProject class has many layers of customization available. For example a library referenece can be added to the project. ```python codePage = 0x04E4 codePageName = "cp" + str(codePage) libidRef = LibidReference( - "windows", "{00020430-0000-0000-C000-000000000046}", "2.0", "0", diff --git a/src/vbaproject_compiler/Models/Entities/module_base.py b/src/vbaproject_compiler/Models/Entities/module_base.py index f6dbeafa7..9a08e3dd6 100644 --- a/src/vbaproject_compiler/Models/Entities/module_base.py +++ b/src/vbaproject_compiler/Models/Entities/module_base.py @@ -55,6 +55,9 @@ def set_cookie(self: T, value: int) -> None: def get_name(self: T) -> str: return self.modName.value + def get_bin_path(self: T) -> str: + return self._file_path + ".bin" + def add_workspace(self: T, val1: int, val2: int, val3: int, val4: int, val5: int) -> None: self.workspace = [val1, val2, val3, val4, val5] diff --git a/src/vbaproject_compiler/Views/project_ole_file.py b/src/vbaproject_compiler/Views/project_ole_file.py index 50f8fa320..62e7ddb1b 100644 --- a/src/vbaproject_compiler/Views/project_ole_file.py +++ b/src/vbaproject_compiler/Views/project_ole_file.py @@ -1,6 +1,10 @@ +from ms_cfb.ole_file import OleFile +from ms_cfb.Models.Directories.root_directory import RootDirectory +from ms_cfb.Models.Directories.storage_directory import StorageDirectory +from ms_cfb.Models.Directories.stream_directory import StreamDirectory from vbaproject_compiler.vbaProject import VbaProject from vbaproject_compiler.Views.dirStream import DirStream -# from vbaproject_compiler.Views.project_view import ProjectView +from vbaproject_compiler.Views.project_view import ProjectView from vbaproject_compiler.Views.project import Project from vbaproject_compiler.Views.projectWm import ProjectWm from typing import TypeVar @@ -14,38 +18,51 @@ class ProjectOleFile: def __init__(self: T, project: VbaProject) -> None: self._project = project - def _create_binary_files(self: T) -> None: + def _build_ole_directory(self: T) -> RootDirectory: + """ + Create all the custom views for the OLE file: + dir + project + projectWm + vbs_project + + Organize the modules and views into the correct storage directories + """ + directory = RootDirectory() + storage = StorageDirectory("VBA") for module in self._project.get_modules(): module.write_file() - dir = DirStream(self._project) - dir.write_file() - project = Project(self._project) - project.write_file() - project_wm = ProjectWm(self._project) - project_wm.write_file() - # views = ("_VBA_PROJECT", "dir", "project_wm", "Project") - # Create views and write - - def _build_ole_directory(self: T) -> None: - # directory = StorageDirectory() - # directory.set_name("VBA") - for module in self._project.get_modules(): - # path = module.get_name() + '.bin' - # dir = StreamDirectory() - # dir.set_name(module.get_name()) - # dir.add_stream(path) - # directory.add_directory(dir) - pass - # return directory - - def _write_ole_file(self: T, dir: str) -> None: - # ole_file = OleFile() - # ole_file.add_directory(dir) - # ole_file.build_file() - # ole_file.write_file("vbaProject.bin") - pass + dir = StreamDirectory(module.get_name(), module.get_bin_path()) + storage.add_directory(dir) + + module = DirStream(self._project) + module.write_file() + dir = StreamDirectory("dir", "dir.bin") + storage.add_directory(dir) + + module = ProjectView(self._project) + module.write_file() + dir = StreamDirectory("_VBA_PROJECT", "vba_project.bin") + storage.add_directory(dir) + + directory.add_directory(storage) + + module = ProjectWm(self._project) + module.write_file() + stream = StreamDirectory("PROJECTwm", "projectwm.bin") + directory.add_directory(stream) + + module = Project(self._project) + module.write_file() + stream = StreamDirectory("PROJECT", "project.bin") + directory.add_directory(stream) + return directory + + def _write_ole_file(self: T, root: str) -> None: + ole_file = OleFile() + ole_file.set_root_directory(root) + ole_file.create_file("vbaProject.bin") def write_file(self: T) -> None: - self._create_binary_files() directory = self._build_ole_directory() self._write_ole_file(directory) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index d979fda81..be252bc91 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -99,43 +99,28 @@ def test_full_file() -> None: project.set_performance_cache(create_cache()) project.set_performance_cache_version(0x00B5) - module_cache = ModuleCache(0xB5, 0x08F3) - module_cache.misc = [0x0316, 0x0123, 0x88, 8, 0x18, "00000000", 1] - indirect_table = ("02 80 FE FF FF FF FF FF 20 00 00 00 FF FF FF FF", - "30 00 00 00 02 01 FF FF 00 00 00 00 00 00 00 00", - "FF FF FF FF FF FF FF FF 00 00 00 00 2E 00 43 00", - "1D 00 00 00 25 00 00 00 FF FF FF FF 40 00 00 00") - module_cache.indirect_table = bytes.fromhex(" ".join(indirect_table)) - object_table = ("02 00 53 4C FF FF FF FF 00 00 01 00 53 10 FF FF", - "FF FF 00 00 01 00 53 94 FF FF FF FF 00 00 00 00", - "02 3C FF FF FF FF 00 00") - module_cache.object_table = bytes.fromhex(" ".join(object_table)) - # Add Modules this_workbook = DocModule("ThisWorkbook") this_workbook.set_cookie(0xB81C) - module_cache.module_cookie = 0xB81C guid = uuid.UUID("0002081900000000C000000000000046") - module_cache.guid = [guid] this_workbook.set_guid(guid) module_path = "src/vbaproject_compiler/blank_files/ThisWorkbook.cls" this_workbook.add_file(module_path) this_workbook.normalize_file() - this_workbook.set_cache(module_cache.to_bytes()) + this_workbook.set_cache(create_module_cache(0xB81C, guid).to_bytes()) sheet1 = DocModule("Sheet1") sheet1.set_cookie(0x9B9A) - module_cache.module_cookie = 0x9B9A guid = uuid.UUID("0002082000000000C000000000000046") - module_cache.guid = [guid] sheet1.set_guid(guid) module_path = "src/vbaproject_compiler/blank_files/Sheet1.cls" sheet1.add_file(module_path) sheet1.normalize_file() - sheet1.set_cache(module_cache.to_bytes()) + sheet1.set_cache(create_module_cache(0x9B9A, guid).to_bytes()) module1 = StdModule("Module1") module1.set_cookie(0xB241) + module_cache = ModuleCache(0xB5, 0x08F3) module_cache.clear_variables() module_cache.misc = [0x0316, 3, 0, 2, 0xFFFF, "FFFFFFFF", 0] module_cache.indirect_table = struct.pack(" None: module1.normalize_file() module1.set_cache(module_cache.to_bytes()) - project.add_module(this_workbook) - project.add_module(sheet1) project.add_module(module1) + project.add_module(sheet1) + project.add_module(this_workbook) ole_file = ProjectOleFile(project) ole_file.write_file() - path = "src/vbaproject_compiler/blank_files/ThisWorkbook.cls.bin" - assert module_matches_bin(path, 0x0333, - "tests/blank/vbaProject.bin", 0x0800, 0xB5) - path = "src/vbaproject_compiler/blank_files/Sheet1.cls.bin" - assert module_matches_bin(path, 0x0333, "tests/blank/vbaProject.bin", - 0x0C00, 0xAC) - - # fileIO = OleFile(project) - # fileIO.build_file() - - # Alter red-black tree - # fileIO.streams[2].color = 1 - # fileIO.streams[3].color = 1 - # fileIO.streams[4].color = 1 - # fileIO.streams[8].color = 1 - - # fileIO.write_file(".") - # assert size of ./vbaProject.bin == size of tests/blank.vbaProject.bin + + # time = Filetime.from_msfiletime(0x01D92433C2B823C0) + # root.set_modified(time) + # storage.set_modified(time) + # storage.set_created(time) + + file_size = os.stat("vbaProject.bin").st_size + expected_size = os.stat("tests/blank/vbaProject.bin").st_size + assert file_size == expected_size # compare new file to blank file in 512 block chunks - # new = open("./vbaProject.bin", "rb") - # expected = open("tests/blank/vbaProject.bin", "rb") - # for chunk in iter(partial(new.read, 512), ''): - # assert chunk == expected.read(512) + new = open("./vbaProject.bin", "rb") + expected = open("tests/blank/vbaProject.bin", "rb") + + # Header + assert new.read(512) == expected.read(512) + + # FAT + assert new.read(512) == expected.read(512) + # new.read(512) + # expected.read(512) + + # Dir + # Stream sizes will not match due to compression differences + # assert new.read(512) == expected.read(512) def create_cache() -> bytes: @@ -246,3 +232,20 @@ def create_cache() -> bytes: ca += name + struct.pack(" ModuleCache: + module_cache = ModuleCache(0xB5, 0x08F3) + module_cache.misc = [0x0316, 0x0123, 0x88, 8, 0x18, "00000000", 1] + indirect_table = ("02 80 FE FF FF FF FF FF 20 00 00 00 FF FF FF FF", + "30 00 00 00 02 01 FF FF 00 00 00 00 00 00 00 00", + "FF FF FF FF FF FF FF FF 00 00 00 00 2E 00 43 00", + "1D 00 00 00 25 00 00 00 FF FF FF FF 40 00 00 00") + module_cache.indirect_table = bytes.fromhex(" ".join(indirect_table)) + object_table = ("02 00 53 4C FF FF FF FF 00 00 01 00 53 10 FF FF", + "FF FF 00 00 01 00 53 94 FF FF FF FF 00 00 00 00", + "02 3C FF FF FF FF 00 00") + module_cache.object_table = bytes.fromhex(" ".join(object_table)) + module_cache.guid = [guid] + module_cache.module_cookie = cookie + return module_cache From cb14a5f71691dec10044a82047095861176de771 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 09:19:48 -0400 Subject: [PATCH 013/335] Update pyproject.toml --- pyproject.toml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 034507569..dd9ac0c58 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,7 +16,10 @@ classifiers = [ "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", ] - +dependencies = [ + 'ms_ovba_compression', + 'ms_ovba_crypto' +] [project.urls] "Homepage" = "https://github.com/Beakerboy/vbaProject-Compiler" "Bug Tracker" = "https://github.com/Beakerboy/vbaProject-Compiler/issues" From a107b028df7f41555040e738dfa6ae26b13c8779 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 09:22:48 -0400 Subject: [PATCH 014/335] Update python-package.yml --- .github/workflows/python-package.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index c4031c37a..37a642208 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -27,7 +27,6 @@ jobs: run: | python -m pip install --upgrade pip python -m pip install flake8 pytest - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi if [ -f requirements_dev.txt ]; then pip install -r requirements_dev.txt; fi pip install git+https://github.com/Beakerboy/MS-CFB@dev pip install git+https://github.com/Beakerboy/MS-Pcode-Assembler@dev From bd2d58c08271da8e516d92e55c5a0fe22ac8e8ca Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 09:26:58 -0400 Subject: [PATCH 015/335] Update pyproject.toml --- pyproject.toml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index dd9ac0c58..0485b94f8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,6 +20,15 @@ dependencies = [ 'ms_ovba_compression', 'ms_ovba_crypto' ] +[project.optional-dependencies] +tests = [ + 'pytest', + 'pytest-cov' + 'pytest-mock', + 'coveralls', + 'pep8-naming', + 'flake8-annotations' +] [project.urls] "Homepage" = "https://github.com/Beakerboy/vbaProject-Compiler" "Bug Tracker" = "https://github.com/Beakerboy/vbaProject-Compiler/issues" From e9c18cae9a2d7a76288c1a5a7b02f1923ed9370e Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 09:27:12 -0400 Subject: [PATCH 016/335] Update pyproject.toml --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 0485b94f8..f59071624 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,7 @@ dependencies = [ [project.optional-dependencies] tests = [ 'pytest', - 'pytest-cov' + 'pytest-cov', 'pytest-mock', 'coveralls', 'pep8-naming', From f63773b3bd57652fa915e00b4ef3e416e282850a Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 09:30:42 -0400 Subject: [PATCH 017/335] Delete requirements_dev.txt --- requirements_dev.txt | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 requirements_dev.txt diff --git a/requirements_dev.txt b/requirements_dev.txt deleted file mode 100644 index c3c5f1430..000000000 --- a/requirements_dev.txt +++ /dev/null @@ -1,6 +0,0 @@ -pytest -pytest-cov -pytest-mock -coveralls -pep8-naming -flake8-annotations From e4e0117b281cd184254e6b232d9dc4b390c254b3 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 09:30:52 -0400 Subject: [PATCH 018/335] Delete requirements.txt --- requirements.txt | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 3d80e0cd7..000000000 --- a/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -ms_ovba_compression -ms_ovba_crypto From f0138b212d1776f7d1fe9c9896aa9caf4d6379ab Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 09:52:28 -0400 Subject: [PATCH 019/335] Update python-package.yml --- .github/workflows/python-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 37a642208..d405f4cf4 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -30,7 +30,7 @@ jobs: if [ -f requirements_dev.txt ]; then pip install -r requirements_dev.txt; fi pip install git+https://github.com/Beakerboy/MS-CFB@dev pip install git+https://github.com/Beakerboy/MS-Pcode-Assembler@dev - pip install -e . + pip install -e .[tests] - name: Lint with flake8 run: | # stop the build if there are Python syntax errors or undefined names From bb8dfa15cf016ea11abd6bcd103e9a9616701c22 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 11:20:07 -0400 Subject: [PATCH 020/335] Rename main.py to __main__.py --- src/vbaproject_compiler/{main.py => __main__.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/vbaproject_compiler/{main.py => __main__.py} (100%) diff --git a/src/vbaproject_compiler/main.py b/src/vbaproject_compiler/__main__.py similarity index 100% rename from src/vbaproject_compiler/main.py rename to src/vbaproject_compiler/__main__.py From b5eeec355c3dee86fc86d9a98afbc736181454a1 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 11:47:53 -0400 Subject: [PATCH 021/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index 05b1038b6..c426d9b5c 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -1,2 +1,15 @@ +import argparse + def main(args: list) -> None: - pass + parser = argparse.ArgumentParser() + parser.add_argument("directory", + help="The directory that contains your files.") + parser.add_argument("-o", "--output", + help="The output file name.") + args = parser.parse_args() + # cd args.output + # build a list of all bas, cls, frm, and frx files + # create a new project object + # add the files + # create the output directory + # save the deliverables. From 827f0f3bc0e333e8a2ef2bf957bcccdb0b509234 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 13:06:17 -0400 Subject: [PATCH 022/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index c426d9b5c..71b52ce6b 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -1,4 +1,7 @@ import argparse +import glob +from vbaproject_compiler.vbaProject import VbaProject +from vbaproject_compiler.Views.project_ole_file import ProjectOleFile def main(args: list) -> None: parser = argparse.ArgumentParser() @@ -9,7 +12,29 @@ def main(args: list) -> None: args = parser.parse_args() # cd args.output # build a list of all bas, cls, frm, and frx files + bas_files = glob.glob('*.bas') + cls_files = glob.glob('*.cls') + frm_files = glob.glob('*.frm') + frx_files = glob.glob('*.frx') + # create a new project object + project = VbaProject() + + # add default modules + module = DocModule('Sheet1') + module.addFile('src/vbaproject_compiler/blank_files/Sheet1.cls') + project.addModule(module) + module = DocModule('ThisWorkbook') + module.addFile('src/vbaproject_compiler/blank_files/ThisWorkbook.cls') + project.addModule(module) + # add the files - # create the output directory - # save the deliverables. + foreach bas_files as file: + #name = get name from file + code = StdModule(name) + code.addFile(file) + project.addModule(code) + + ole_file = ProjectOleFile(project) + ole_file.write_file() + From 963ae2f0861090def32076607eab6050f2c4c946 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 13:09:03 -0400 Subject: [PATCH 023/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index 71b52ce6b..f5c0b6bfb 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -29,7 +29,7 @@ def main(args: list) -> None: project.addModule(module) # add the files - foreach bas_files as file: + for file in bas_files: #name = get name from file code = StdModule(name) code.addFile(file) From 1589c310aced606c0dbc351a0bd4f88b0eb4264a Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 13:12:38 -0400 Subject: [PATCH 024/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index f5c0b6bfb..bba60ae6a 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -1,5 +1,6 @@ import argparse import glob +import os from vbaproject_compiler.vbaProject import VbaProject from vbaproject_compiler.Views.project_ole_file import ProjectOleFile @@ -29,10 +30,11 @@ def main(args: list) -> None: project.addModule(module) # add the files - for file in bas_files: - #name = get name from file - code = StdModule(name) - code.addFile(file) + for file_path in bas_files: + file_name = os.path.basename(file_path) + file = os.path.splitext(file_name) + code = StdModule(file[0]) + code.addFile(file_path) project.addModule(code) ole_file = ProjectOleFile(project) From f153e2a48514aea722f2571ed0c7acddfe8b46bb Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 13:18:10 -0400 Subject: [PATCH 025/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index bba60ae6a..213bbbab2 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -2,6 +2,8 @@ import glob import os from vbaproject_compiler.vbaProject import VbaProject +from vbaproject_compiler.Models.Entities.doc_module import DocModule +from vbaproject_compiler.Models.Entities.std_module import StdModule from vbaproject_compiler.Views.project_ole_file import ProjectOleFile def main(args: list) -> None: From 62fef5716b57495ce49361251984593e60dc9c80 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 13:21:07 -0400 Subject: [PATCH 026/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index 213bbbab2..e7d52c071 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -10,15 +10,13 @@ def main(args: list) -> None: parser = argparse.ArgumentParser() parser.add_argument("directory", help="The directory that contains your files.") - parser.add_argument("-o", "--output", - help="The output file name.") args = parser.parse_args() # cd args.output # build a list of all bas, cls, frm, and frx files bas_files = glob.glob('*.bas') - cls_files = glob.glob('*.cls') - frm_files = glob.glob('*.frm') - frx_files = glob.glob('*.frx') + #cls_files = glob.glob('*.cls') + #frm_files = glob.glob('*.frm') + #frx_files = glob.glob('*.frx') # create a new project object project = VbaProject() From b597fcdba0714e84974ca8c633ba4daea285849e Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 13:21:16 -0400 Subject: [PATCH 027/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index e7d52c071..fda58bd18 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -6,6 +6,7 @@ from vbaproject_compiler.Models.Entities.std_module import StdModule from vbaproject_compiler.Views.project_ole_file import ProjectOleFile + def main(args: list) -> None: parser = argparse.ArgumentParser() parser.add_argument("directory", From 3418c399443f3a76782fa7624ad996b48b4defd5 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 13:24:11 -0400 Subject: [PATCH 028/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index fda58bd18..69d9722c6 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -14,7 +14,7 @@ def main(args: list) -> None: args = parser.parse_args() # cd args.output # build a list of all bas, cls, frm, and frx files - bas_files = glob.glob('*.bas') + bas_files = glob.glob(args.directory + '/*.bas') #cls_files = glob.glob('*.cls') #frm_files = glob.glob('*.frm') #frx_files = glob.glob('*.frx') From 8cc72a720368e2ad6ba1c93e417ee5f432d45213 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 13:25:25 -0400 Subject: [PATCH 029/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index 69d9722c6..55479bfd5 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -15,9 +15,9 @@ def main(args: list) -> None: # cd args.output # build a list of all bas, cls, frm, and frx files bas_files = glob.glob(args.directory + '/*.bas') - #cls_files = glob.glob('*.cls') - #frm_files = glob.glob('*.frm') - #frx_files = glob.glob('*.frx') + # cls_files = glob.glob('*.cls') + # frm_files = glob.glob('*.frm') + # frx_files = glob.glob('*.frx') # create a new project object project = VbaProject() @@ -29,7 +29,7 @@ def main(args: list) -> None: module = DocModule('ThisWorkbook') module.addFile('src/vbaproject_compiler/blank_files/ThisWorkbook.cls') project.addModule(module) - + # add the files for file_path in bas_files: file_name = os.path.basename(file_path) @@ -37,7 +37,6 @@ def main(args: list) -> None: code = StdModule(file[0]) code.addFile(file_path) project.addModule(code) - + ole_file = ProjectOleFile(project) ole_file.write_file() - From 6d71a024e90d509f2ba57d8868b6571dab50eb16 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 13:37:39 -0400 Subject: [PATCH 030/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index 55479bfd5..24b82c5e5 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -40,3 +40,5 @@ def main(args: list) -> None: ole_file = ProjectOleFile(project) ole_file.write_file() + file = glob.glob('vbaProject.bin') + print(file[0]) From 6b41da421f7bb652e526b19a7adb6b0d367f0d59 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 13:41:06 -0400 Subject: [PATCH 031/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index 24b82c5e5..743f7b100 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -37,7 +37,7 @@ def main(args: list) -> None: code = StdModule(file[0]) code.addFile(file_path) project.addModule(code) - + os.mkdir('project') ole_file = ProjectOleFile(project) ole_file.write_file() file = glob.glob('vbaProject.bin') From 18f1d1e56befc1739a321556b237046e75a54ab6 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 13:48:37 -0400 Subject: [PATCH 032/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index 743f7b100..1fdeffc48 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -41,4 +41,4 @@ def main(args: list) -> None: ole_file = ProjectOleFile(project) ole_file.write_file() file = glob.glob('vbaProject.bin') - print(file[0]) + print('HELLO') From 64446ec04bbd5d51715ab760a94de1b2c1ab3a52 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 13:56:31 -0400 Subject: [PATCH 033/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index 1fdeffc48..3c3d6253d 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -8,9 +8,12 @@ def main(args: list) -> None: + print("in Main") parser = argparse.ArgumentParser() parser.add_argument("directory", help="The directory that contains your files.") + parser.add_argument("dest", + help="out.") args = parser.parse_args() # cd args.output # build a list of all bas, cls, frm, and frx files From a67ccc880a7105b0f4ebced093466a4025309bb5 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 14:00:54 -0400 Subject: [PATCH 034/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index 3c3d6253d..9b4ecd229 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -8,7 +8,7 @@ def main(args: list) -> None: - print("in Main") + print("in Main", flush=True) parser = argparse.ArgumentParser() parser.add_argument("directory", help="The directory that contains your files.") From f9b63776d15c98be04b344f8efc080ffef9dce25 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 14:08:04 -0400 Subject: [PATCH 035/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index 9b4ecd229..d6f9d6b33 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -17,7 +17,7 @@ def main(args: list) -> None: args = parser.parse_args() # cd args.output # build a list of all bas, cls, frm, and frx files - bas_files = glob.glob(args.directory + '/*.bas') + bas_files = glob.glob('/*.bas', root_dir=args.directory) # cls_files = glob.glob('*.cls') # frm_files = glob.glob('*.frm') # frx_files = glob.glob('*.frx') From ad62866466d286581ae78e55ad90019039ac7d74 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 14:13:31 -0400 Subject: [PATCH 036/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index d6f9d6b33..0e9bd043c 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -8,6 +8,7 @@ def main(args: list) -> None: + raise Exception("IN MAIN!") print("in Main", flush=True) parser = argparse.ArgumentParser() parser.add_argument("directory", From 5cacb79e99bc30764c1376d9c077f5b457f39a86 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 14:24:46 -0400 Subject: [PATCH 037/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index 0e9bd043c..8250ba219 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -46,3 +46,5 @@ def main(args: list) -> None: ole_file.write_file() file = glob.glob('vbaProject.bin') print('HELLO') + +main() From 4a7769b796bbbb17f92bac12f57dccd6655a09e3 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 14:28:56 -0400 Subject: [PATCH 038/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index 8250ba219..3f53e53e6 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -7,7 +7,7 @@ from vbaproject_compiler.Views.project_ole_file import ProjectOleFile -def main(args: list) -> None: +def main() -> None: raise Exception("IN MAIN!") print("in Main", flush=True) parser = argparse.ArgumentParser() From 6c8e6065f63ccf3fe4a7dfc5a6962a78a17e1e26 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 15:10:07 -0400 Subject: [PATCH 039/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index 3f53e53e6..dccbc6ecb 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -8,8 +8,6 @@ def main() -> None: - raise Exception("IN MAIN!") - print("in Main", flush=True) parser = argparse.ArgumentParser() parser.add_argument("directory", help="The directory that contains your files.") From 7d784286d65f2da6bec626627958a1190a66fc3e Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 15:13:13 -0400 Subject: [PATCH 040/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index dccbc6ecb..b0c1ba038 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -11,8 +11,6 @@ def main() -> None: parser = argparse.ArgumentParser() parser.add_argument("directory", help="The directory that contains your files.") - parser.add_argument("dest", - help="out.") args = parser.parse_args() # cd args.output # build a list of all bas, cls, frm, and frx files @@ -43,6 +41,5 @@ def main() -> None: ole_file = ProjectOleFile(project) ole_file.write_file() file = glob.glob('vbaProject.bin') - print('HELLO') main() From 5bbe4cdc8d5bda37c45d348866ae29e8440ed3e9 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 15:15:04 -0400 Subject: [PATCH 041/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index b0c1ba038..234b04bd5 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -24,10 +24,10 @@ def main() -> None: # add default modules module = DocModule('Sheet1') - module.addFile('src/vbaproject_compiler/blank_files/Sheet1.cls') + module.add_file('src/vbaproject_compiler/blank_files/Sheet1.cls') project.addModule(module) module = DocModule('ThisWorkbook') - module.addFile('src/vbaproject_compiler/blank_files/ThisWorkbook.cls') + module.add_file('src/vbaproject_compiler/blank_files/ThisWorkbook.cls') project.addModule(module) # add the files From ab23c502d2bf282bd07ecb7efff7887ced97d0f1 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 15:16:01 -0400 Subject: [PATCH 042/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index 234b04bd5..053e7376e 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -8,6 +8,8 @@ def main() -> None: + + parser = argparse.ArgumentParser() parser.add_argument("directory", help="The directory that contains your files.") From 629194d6d5a2d903e09940676d500c85217ecddb Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 15:18:35 -0400 Subject: [PATCH 043/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index 053e7376e..7cdf4ad43 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -27,18 +27,18 @@ def main() -> None: # add default modules module = DocModule('Sheet1') module.add_file('src/vbaproject_compiler/blank_files/Sheet1.cls') - project.addModule(module) + project.add_module(module) module = DocModule('ThisWorkbook') module.add_file('src/vbaproject_compiler/blank_files/ThisWorkbook.cls') - project.addModule(module) + project.add_module(module) # add the files for file_path in bas_files: file_name = os.path.basename(file_path) file = os.path.splitext(file_name) code = StdModule(file[0]) - code.addFile(file_path) - project.addModule(code) + code.add_file(file_path) + project.add_module(code) os.mkdir('project') ole_file = ProjectOleFile(project) ole_file.write_file() From 258e83018beaccc2d0490728f233fa5eac99c1a1 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 15:19:58 -0400 Subject: [PATCH 044/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index 7cdf4ad43..b5241dcf2 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -9,7 +9,6 @@ def main() -> None: - parser = argparse.ArgumentParser() parser.add_argument("directory", help="The directory that contains your files.") From 7c3ed49ac6faebaf292fa86198b4ac84a61d5f57 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 15:20:48 -0400 Subject: [PATCH 045/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index b5241dcf2..5ffc46d5a 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -43,4 +43,5 @@ def main() -> None: ole_file.write_file() file = glob.glob('vbaProject.bin') + main() From a5a4753fcd8a03d9c0f6d5e100bfbf5d97fdfaf6 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 21:43:57 -0400 Subject: [PATCH 046/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index 5ffc46d5a..6f26468f0 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -25,10 +25,11 @@ def main() -> None: # add default modules module = DocModule('Sheet1') - module.add_file('src/vbaproject_compiler/blank_files/Sheet1.cls') + base_path = os.path.basename(__file__) + module.add_file(base_path + '/blank_files/Sheet1.cls') project.add_module(module) module = DocModule('ThisWorkbook') - module.add_file('src/vbaproject_compiler/blank_files/ThisWorkbook.cls') + module.add_file(base_path + '/blank_files/ThisWorkbook.cls') project.add_module(module) # add the files From ac9aab48f843eded7121c8311c7bd8063071a76c Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 21:46:06 -0400 Subject: [PATCH 047/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index 6f26468f0..31d48b211 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -25,7 +25,7 @@ def main() -> None: # add default modules module = DocModule('Sheet1') - base_path = os.path.basename(__file__) + base_path = os.path.dirname(__file__) module.add_file(base_path + '/blank_files/Sheet1.cls') project.add_module(module) module = DocModule('ThisWorkbook') From 7c8e96009d05b44ac87f5394d84298c1beb3e199 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 22:49:13 -0400 Subject: [PATCH 048/335] Update pyproject.toml --- pyproject.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index f59071624..ebefd1570 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,3 +38,5 @@ pythonpath = "src" testpaths = [ "tests", ] +[tool.setuptools.package-data] +"*" = ["*.cls"] From f254fc505201f9ed962206dedb9baecb738db300 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 22:59:35 -0400 Subject: [PATCH 049/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index 31d48b211..154e8e68c 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -27,9 +27,11 @@ def main() -> None: module = DocModule('Sheet1') base_path = os.path.dirname(__file__) module.add_file(base_path + '/blank_files/Sheet1.cls') + module.normalize_file() project.add_module(module) module = DocModule('ThisWorkbook') module.add_file(base_path + '/blank_files/ThisWorkbook.cls') + module.normalize_file() project.add_module(module) # add the files From 113a1f97a2733f51f7e3678194ef4fbfbaeb865d Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 2 Nov 2023 23:06:50 -0400 Subject: [PATCH 050/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index 154e8e68c..2b100100f 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -33,7 +33,7 @@ def main() -> None: module.add_file(base_path + '/blank_files/ThisWorkbook.cls') module.normalize_file() project.add_module(module) - + project.set_project_id('{9E394C0B-697E-4AEE-9FA6-446F51FB30DC}') # add the files for file_path in bas_files: file_name = os.path.basename(file_path) From 5737e12dbe69f333253be550500ca215866461d7 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 4 Nov 2023 15:58:04 -0400 Subject: [PATCH 051/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index 2b100100f..a1ab32e14 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -15,7 +15,7 @@ def main() -> None: args = parser.parse_args() # cd args.output # build a list of all bas, cls, frm, and frx files - bas_files = glob.glob('/*.bas', root_dir=args.directory) + bas_files = glob.glob(args.directory + '/**/*.bas', recursive=True) # cls_files = glob.glob('*.cls') # frm_files = glob.glob('*.frm') # frx_files = glob.glob('*.frx') From c850256ecbc56bea63d00053711f6d0fcbdb96fd Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 8 Nov 2023 08:09:35 -0500 Subject: [PATCH 052/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index be252bc91..1398b3111 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -3,6 +3,7 @@ import struct import unittest.mock import uuid +from ms_cfb.ole_file import OleFile from ms_ovba_compression.ms_ovba import MsOvba from ms_pcode_assembler.module_cache import ModuleCache from vbaproject_compiler.vbaProject import VbaProject @@ -159,6 +160,9 @@ def test_full_file() -> None: # expected.read(512) # Dir + ole_standard = OleFile.create_from_file("tests/blank/vbaProject.bin") + ole_new = OleFile.create_from_file("./vbaProject.bin") + assert len(ole_standard.dirlist) == len(ole_new.dirlist) # Stream sizes will not match due to compression differences # assert new.read(512) == expected.read(512) From d226130351d6ddc352b1d618228a6eac95ca902f Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 8 Nov 2023 08:17:17 -0500 Subject: [PATCH 053/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index a1ab32e14..5a2192768 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -41,6 +41,7 @@ def main() -> None: code = StdModule(file[0]) code.add_file(file_path) project.add_module(code) + print('Added ' + file_path) os.mkdir('project') ole_file = ProjectOleFile(project) ole_file.write_file() From 4469797410ab201a0d70fa2cf376665155209129 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 8 Nov 2023 08:38:56 -0500 Subject: [PATCH 054/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index 5a2192768..0c8d62ba9 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -40,6 +40,7 @@ def main() -> None: file = os.path.splitext(file_name) code = StdModule(file[0]) code.add_file(file_path) + code.normalize_file() project.add_module(code) print('Added ' + file_path) os.mkdir('project') From ed1c279df590803a6be917f69b81cb6a26917a2d Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 8 Nov 2023 09:18:11 -0500 Subject: [PATCH 055/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index 0c8d62ba9..4bb55886d 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -42,8 +42,26 @@ def main() -> None: code.add_file(file_path) code.normalize_file() project.add_module(code) - print('Added ' + file_path) - os.mkdir('project') + codepage = 0x04E4 + codepage_name = "cp" + str(codepage) + libid_ref = LibidReference( + uuid.UUID("0002043000000000C000000000000046"), + "2.0", + "0", + "C:\\Windows\\System32\\stdole2.tlb", + "OLE Automation" + ) + ole_reference = ReferenceRecord(codepage_name, "stdole", libid_ref) + libid_ref2 = LibidReference( + uuid.UUID("2DF8D04C5BFA101BBDE500AA0044DE52"), + "2.0", + "0", + "C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE16\\MSO.DLL", + "Microsoft Office 16.0 Object Library" + ) + office_reference = ReferenceRecord(codepage_name, "Office", libid_ref2) + project.add_reference(ole_reference) + project.add_reference(office_reference) ole_file = ProjectOleFile(project) ole_file.write_file() file = glob.glob('vbaProject.bin') From 47234caf9d8f07156adda48bbfadb2036f88c1ae Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 8 Nov 2023 09:23:22 -0500 Subject: [PATCH 056/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index 4bb55886d..2eda6c5ae 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -5,6 +5,10 @@ from vbaproject_compiler.Models.Entities.doc_module import DocModule from vbaproject_compiler.Models.Entities.std_module import StdModule from vbaproject_compiler.Views.project_ole_file import ProjectOleFile +from vbaproject_compiler.Models.Entities.reference_record import ( + ReferenceRecord +) +from vbaproject_compiler.Models.Fields.libid_reference import LibidReference def main() -> None: From 8eb6c8953737bd6314b43cf38f6ebe8bb8af1e90 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 8 Nov 2023 09:24:37 -0500 Subject: [PATCH 057/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index 2eda6c5ae..5801c0b5c 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -1,6 +1,7 @@ import argparse import glob import os +import uuid from vbaproject_compiler.vbaProject import VbaProject from vbaproject_compiler.Models.Entities.doc_module import DocModule from vbaproject_compiler.Models.Entities.std_module import StdModule From 6ffabd59ac902a5d5b8f00b5b72dbd0de61029b4 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 8 Nov 2023 09:36:15 -0500 Subject: [PATCH 058/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index 5801c0b5c..0b844bb91 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -33,10 +33,14 @@ def main() -> None: base_path = os.path.dirname(__file__) module.add_file(base_path + '/blank_files/Sheet1.cls') module.normalize_file() + guid = uuid.UUID("0002082000000000C000000000000046") + sheet1.set_guid(guid) project.add_module(module) module = DocModule('ThisWorkbook') module.add_file(base_path + '/blank_files/ThisWorkbook.cls') module.normalize_file() + guid = uuid.UUID("0002081900000000C000000000000046") + module.set_guid(guid) project.add_module(module) project.set_project_id('{9E394C0B-697E-4AEE-9FA6-446F51FB30DC}') # add the files From da234f17ccc3c42275443ef305c6e1599fb5fa23 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 8 Nov 2023 13:46:26 -0500 Subject: [PATCH 059/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index 0b844bb91..9cac91d2e 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -34,7 +34,7 @@ def main() -> None: module.add_file(base_path + '/blank_files/Sheet1.cls') module.normalize_file() guid = uuid.UUID("0002082000000000C000000000000046") - sheet1.set_guid(guid) + smodule.set_guid(guid) project.add_module(module) module = DocModule('ThisWorkbook') module.add_file(base_path + '/blank_files/ThisWorkbook.cls') From 7d164555436d63e5c52871d618f4fbf4fbea3fb5 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 9 Nov 2023 07:23:27 -0500 Subject: [PATCH 060/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index 9cac91d2e..cd531eb52 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -34,7 +34,7 @@ def main() -> None: module.add_file(base_path + '/blank_files/Sheet1.cls') module.normalize_file() guid = uuid.UUID("0002082000000000C000000000000046") - smodule.set_guid(guid) + module.set_guid(guid) project.add_module(module) module = DocModule('ThisWorkbook') module.add_file(base_path + '/blank_files/ThisWorkbook.cls') From 77eab445d0c5aed265bd6eee0acf95fbdf28b10c Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 9 Nov 2023 10:48:13 -0500 Subject: [PATCH 061/335] Update python-package.yml --- .github/workflows/python-package.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index d405f4cf4..644a902d2 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -26,8 +26,6 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - python -m pip install flake8 pytest - if [ -f requirements_dev.txt ]; then pip install -r requirements_dev.txt; fi pip install git+https://github.com/Beakerboy/MS-CFB@dev pip install git+https://github.com/Beakerboy/MS-Pcode-Assembler@dev pip install -e .[tests] From 0e7908fc895fa02d2c216df0648f8ba219fb3544 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 9 Nov 2023 11:07:40 -0500 Subject: [PATCH 062/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 1398b3111..c611b5855 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -155,16 +155,21 @@ def test_full_file() -> None: assert new.read(512) == expected.read(512) # FAT - assert new.read(512) == expected.read(512) - # new.read(512) - # expected.read(512) + # assert new.read(512) == expected.read(512) + new.read(512) + expected.read(512) - # Dir + # Dir1 ole_standard = OleFile.create_from_file("tests/blank/vbaProject.bin") ole_new = OleFile.create_from_file("./vbaProject.bin") assert len(ole_standard.dirlist) == len(ole_new.dirlist) - # Stream sizes will not match due to compression differences - # assert new.read(512) == expected.read(512) + + #assert new.read(512) == expected.read(512) + new.read(512) + expected.read(512) + + # minifat + assert new.read(512) == expected.read(512) def create_cache() -> bytes: From 49b10c5cad5264d02998a44286e17eab24546892 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Tue, 14 Nov 2023 09:35:09 -0500 Subject: [PATCH 063/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index c611b5855..a43346660 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -164,7 +164,7 @@ def test_full_file() -> None: ole_new = OleFile.create_from_file("./vbaProject.bin") assert len(ole_standard.dirlist) == len(ole_new.dirlist) - #assert new.read(512) == expected.read(512) + # assert new.read(512) == expected.read(512) new.read(512) expected.read(512) From 9cd3a8877e08ea07489b3cc5de05ab169bef0539 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Tue, 14 Nov 2023 10:26:35 -0500 Subject: [PATCH 064/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index a43346660..3fc7bcaf1 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -163,7 +163,7 @@ def test_full_file() -> None: ole_standard = OleFile.create_from_file("tests/blank/vbaProject.bin") ole_new = OleFile.create_from_file("./vbaProject.bin") assert len(ole_standard.dirlist) == len(ole_new.dirlist) - + # assert new.read(512) == expected.read(512) new.read(512) expected.read(512) From f1fc0a3d0a41a0f842d04f1bd40f4f1cfa515276 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Tue, 14 Nov 2023 10:56:13 -0500 Subject: [PATCH 065/335] Made compat version optional in dirstream --- src/vbaproject_compiler/Views/dirStream.py | 70 ++++++++++++---------- tests/Functional/test_dirObject.py | 1 + 2 files changed, 41 insertions(+), 30 deletions(-) diff --git a/src/vbaproject_compiler/Views/dirStream.py b/src/vbaproject_compiler/Views/dirStream.py index 046708e05..9ceec0eca 100644 --- a/src/vbaproject_compiler/Views/dirStream.py +++ b/src/vbaproject_compiler/Views/dirStream.py @@ -19,40 +19,13 @@ class DirStream(): def __init__(self: T, project: VbaProject) -> None: self.project = project - self.codepage = 0x04E4 - # 0=16bit, 1=32bit, 2=mac, 3=64bit - syskind = IdSizeField(1, 4, 3) - compat_version = IdSizeField(74, 4, 3) - lcid = IdSizeField(2, 4, 0x0409) - lcid_invoke = IdSizeField(20, 4, 0x0409) - codepage_record = IdSizeField(3, 2, self.codepage) - project_name = IdSizeField(4, 10, "VBAProject") - docstring = DoubleEncodedString([5, 0x0040], "") - helpfile = DoubleEncodedString([6, 0x003D], "") - help_context = IdSizeField(7, 4, 0) - lib_flags = IdSizeField(8, 4, 0) - version = IdSizeField(9, 4, 0x65BE0257) - minor_version = PackedData("H", 17) - constants = DoubleEncodedString([12, 0x003C], "") - self.information = [ - syskind, - compat_version, - lcid, - lcid_invoke, - codepage_record, - project_name, - docstring, - helpfile, - help_context, - lib_flags, - version, - minor_version, - constants - ] + self.information = [] self.references = [] self.modules = [] + self._include_compat = False def to_bytes(self: T) -> bytes: + self._load_information() endien = self.project.endien codepage_name = self.project.get_codepage_name() pack_symbol = '<' if endien == 'little' else '>' @@ -76,9 +49,46 @@ def to_bytes(self: T) -> bytes: output += struct.pack(pack_symbol + "HI", 16, 0) return output + def include_compat(self: T) -> None: + self._include_compat = True + def write_file(self: T) -> None: bin_f = open("dir.bin", "wb") ms_ovba = MsOvba() compressed = ms_ovba.compress(self.to_bytes()) bin_f.write(compressed) bin_f.close() + + def _load_information(self: T) -> None: + self.codepage = 0x04E4 + # 0=16bit, 1=32bit, 2=mac, 3=64bit + syskind = IdSizeField(1, 4, 3) + compat_version = IdSizeField(74, 4, 3) + lcid = IdSizeField(2, 4, 0x0409) + lcid_invoke = IdSizeField(20, 4, 0x0409) + codepage_record = IdSizeField(3, 2, self.codepage) + project_name = IdSizeField(4, 10, "VBAProject") + docstring = DoubleEncodedString([5, 0x0040], "") + helpfile = DoubleEncodedString([6, 0x003D], "") + help_context = IdSizeField(7, 4, 0) + lib_flags = IdSizeField(8, 4, 0) + version = IdSizeField(9, 4, 0x65BE0257) + minor_version = PackedData("H", 17) + constants = DoubleEncodedString([12, 0x003C], "") + + self.information = [syskind] + if self._include_compat: + self.information.append(compat_version) + self.information.extend([ + lcid, + lcid_invoke, + codepage_record, + project_name, + docstring, + helpfile, + help_context, + lib_flags, + version, + minor_version, + constants + ]) diff --git a/tests/Functional/test_dirObject.py b/tests/Functional/test_dirObject.py index c0340d8bd..d7e4976cd 100644 --- a/tests/Functional/test_dirObject.py +++ b/tests/Functional/test_dirObject.py @@ -26,6 +26,7 @@ def test_dirstream() -> None: # Create a project with the same attributes project = VbaProject() stream = DirStream(project) + stream.include_compat() codepage = 0x04E4 codepage_name = "cp" + str(codepage) guid = uuid.UUID('0002043000000000C000000000000046') From 4fd649044c0253913f016b8dedd3401080a15cc9 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 15 Nov 2023 11:56:08 -0500 Subject: [PATCH 066/335] Update test_fullFile.py (#111) Added more details to performance cache --- tests/Functional/test_fullFile.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 3fc7bcaf1..21e502e4c 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -173,14 +173,16 @@ def test_full_file() -> None: def create_cache() -> bytes: - vba_project = VbaProject() - vba_project.set_performance_cache_version(0x00B5) + modules = [] this_workbook = DocModule("ThisWorkbook") this_workbook.cookie.value = 0xB81C + modules.append(this_workbook) sheet1 = DocModule("Sheet1") sheet1.cookie.value = 0x9B9A + modules.append(sheet1) module1 = StdModule("Module1") module1.cookie.value = 0xB241 + modules.append(module1) libraries = [] delim = [] @@ -232,10 +234,10 @@ def create_cache() -> bytes: # index = 0x0046 i = 0 - for module in vba_project.modules: + for module in modules: name = module.modName.value.encode("utf_16_le") ca += struct.pack(" Date: Wed, 15 Nov 2023 12:14:57 -0500 Subject: [PATCH 067/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 34 ++++++++++++++++--------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 21e502e4c..ea947b0fd 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -101,23 +101,13 @@ def test_full_file() -> None: project.set_performance_cache_version(0x00B5) # Add Modules - this_workbook = DocModule("ThisWorkbook") - this_workbook.set_cookie(0xB81C) - guid = uuid.UUID("0002081900000000C000000000000046") - this_workbook.set_guid(guid) - module_path = "src/vbaproject_compiler/blank_files/ThisWorkbook.cls" - this_workbook.add_file(module_path) - this_workbook.normalize_file() - this_workbook.set_cache(create_module_cache(0xB81C, guid).to_bytes()) + this_workbook = create_doc_module("ThisWorkbook", 0xB81C, + "0002081900000000C000000000000046", + "src/vbaproject_compiler/blank_files/ThisWorkbook.cls") - sheet1 = DocModule("Sheet1") - sheet1.set_cookie(0x9B9A) - guid = uuid.UUID("0002082000000000C000000000000046") - sheet1.set_guid(guid) - module_path = "src/vbaproject_compiler/blank_files/Sheet1.cls" - sheet1.add_file(module_path) - sheet1.normalize_file() - sheet1.set_cache(create_module_cache(0x9B9A, guid).to_bytes()) + sheet1 = create_doc_module("Sheet1", 0x9B9A, + "0002082000000000C000000000000046", + "src/vbaproject_compiler/blank_files/Sheet1.cls") module1 = StdModule("Module1") module1.set_cookie(0xB241) @@ -260,3 +250,15 @@ def create_module_cache(cookie: int, guid: uuid.UUID) -> ModuleCache: module_cache.guid = [guid] module_cache.module_cookie = cookie return module_cache + + +def create_doc_module(name: str, cookie: int, guid_s: str, path: str) -> DocModule: + mod = DocModule(name) + mod.set_cookie(cookie) + guid = uuid.UUID(guid_s) + mod.set_guid(guid) + module_path = path + mod.add_file(module_path) + mod.normalize_file() + mod.set_cache(create_module_cache(cookie, guid).to_bytes()) + return mod From 24d987395f9e99a66b02744fc711c3f0d7735eb0 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 15 Nov 2023 12:20:06 -0500 Subject: [PATCH 068/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index ea947b0fd..a9d571fd7 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -95,7 +95,8 @@ def test_full_file() -> None: office_reference = ReferenceRecord(codepage_name, "Office", libid_ref2) project.add_reference(ole_reference) project.add_reference(office_reference) - project.set_project_cookie(0x08F3) + proj_cookie = 0x08F3 + project.set_project_cookie(proj_cookie) project.set_project_id('{9E394C0B-697E-4AEE-9FA6-446F51FB30DC}') project.set_performance_cache(create_cache()) project.set_performance_cache_version(0x00B5) @@ -110,12 +111,13 @@ def test_full_file() -> None: "src/vbaproject_compiler/blank_files/Sheet1.cls") module1 = StdModule("Module1") - module1.set_cookie(0xB241) - module_cache = ModuleCache(0xB5, 0x08F3) + cookie = 0xB241 + module1.set_cookie(cookie) + module_cache = ModuleCache(0xB5, proj_cookie) module_cache.clear_variables() module_cache.misc = [0x0316, 3, 0, 2, 0xFFFF, "FFFFFFFF", 0] module_cache.indirect_table = struct.pack(" Date: Wed, 15 Nov 2023 12:30:29 -0500 Subject: [PATCH 069/335] Update module_base.py --- src/vbaproject_compiler/Models/Entities/module_base.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vbaproject_compiler/Models/Entities/module_base.py b/src/vbaproject_compiler/Models/Entities/module_base.py index 9a08e3dd6..880efc6c9 100644 --- a/src/vbaproject_compiler/Models/Entities/module_base.py +++ b/src/vbaproject_compiler/Models/Entities/module_base.py @@ -50,8 +50,12 @@ def get_cache(self: T) -> bytes: return self._cache def set_cookie(self: T, value: int) -> None: + self_cookie = value self.cookie = IdSizeField(0x002C, 2, value) + def get_cookie(seff: T) -> int: + return self._cookie + def get_name(self: T) -> str: return self.modName.value From 74ca49680e3b4771d5a71e994f0f619153af7f38 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 15 Nov 2023 12:35:29 -0500 Subject: [PATCH 070/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index a9d571fd7..6ce0a2e6a 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -102,11 +102,11 @@ def test_full_file() -> None: project.set_performance_cache_version(0x00B5) # Add Modules - this_workbook = create_doc_module("ThisWorkbook", 0xB81C, + this_workbook = create_doc_module(project, "ThisWorkbook", 0xB81C, "0002081900000000C000000000000046", "src/vbaproject_compiler/blank_files/ThisWorkbook.cls") - sheet1 = create_doc_module("Sheet1", 0x9B9A, + sheet1 = create_doc_module(project, "Sheet1", 0x9B9A, "0002082000000000C000000000000046", "src/vbaproject_compiler/blank_files/Sheet1.cls") @@ -237,8 +237,18 @@ def create_cache() -> bytes: return ca -def create_module_cache(cookie: int, guid: uuid.UUID) -> ModuleCache: - module_cache = ModuleCache(0xB5, 0x08F3) +def create_doc_module(project: VbaProject, name: str, cookie: int, guid_s: str, path: str) -> DocModule: + mod = DocModule(name) + mod.set_cookie(cookie) + guid = uuid.UUID(guid_s) + mod.set_guid(guid) + module_path = path + mod.add_file(module_path) + mod.normalize_file() + + cache_ver = project.get_performance_cache_version() + proj_cookie = project.get_project_cookie() + module_cache = ModuleCache(cache_ver, proj_cookie) module_cache.misc = [0x0316, 0x0123, 0x88, 8, 0x18, "00000000", 1] indirect_table = ("02 80 FE FF FF FF FF FF 20 00 00 00 FF FF FF FF", "30 00 00 00 02 01 FF FF 00 00 00 00 00 00 00 00", @@ -251,16 +261,6 @@ def create_module_cache(cookie: int, guid: uuid.UUID) -> ModuleCache: module_cache.object_table = bytes.fromhex(" ".join(object_table)) module_cache.guid = [guid] module_cache.module_cookie = cookie - return module_cache - -def create_doc_module(name: str, cookie: int, guid_s: str, path: str) -> DocModule: - mod = DocModule(name) - mod.set_cookie(cookie) - guid = uuid.UUID(guid_s) - mod.set_guid(guid) - module_path = path - mod.add_file(module_path) - mod.normalize_file() - mod.set_cache(create_module_cache(cookie, guid).to_bytes()) + mod.set_cache(module_cache.to_bytes()) return mod From 1ef7cca91da21b5d939f585e3fbc873d4522e279 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 15 Nov 2023 12:40:49 -0500 Subject: [PATCH 071/335] Update module_base.py --- src/vbaproject_compiler/Models/Entities/module_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vbaproject_compiler/Models/Entities/module_base.py b/src/vbaproject_compiler/Models/Entities/module_base.py index 880efc6c9..0a43166fb 100644 --- a/src/vbaproject_compiler/Models/Entities/module_base.py +++ b/src/vbaproject_compiler/Models/Entities/module_base.py @@ -53,7 +53,7 @@ def set_cookie(self: T, value: int) -> None: self_cookie = value self.cookie = IdSizeField(0x002C, 2, value) - def get_cookie(seff: T) -> int: + def get_cookie(self: T) -> int: return self._cookie def get_name(self: T) -> str: From e3db8c016b58e2015884ea8dfb88469333d5f579 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 15 Nov 2023 12:42:34 -0500 Subject: [PATCH 072/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 6ce0a2e6a..0e31b6027 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -101,14 +101,15 @@ def test_full_file() -> None: project.set_performance_cache(create_cache()) project.set_performance_cache_version(0x00B5) + base_path = ""src/vbaproject_compiler/blank_files/" # Add Modules this_workbook = create_doc_module(project, "ThisWorkbook", 0xB81C, "0002081900000000C000000000000046", - "src/vbaproject_compiler/blank_files/ThisWorkbook.cls") + base_path + "ThisWorkbook.cls") sheet1 = create_doc_module(project, "Sheet1", 0x9B9A, - "0002082000000000C000000000000046", - "src/vbaproject_compiler/blank_files/Sheet1.cls") + "0002082000000000C000000000000046", + base_path + "Sheet1.cls") module1 = StdModule("Module1") cookie = 0xB241 From f095084d27dca815be78b31d1824831a3c2b99b9 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 15 Nov 2023 12:43:32 -0500 Subject: [PATCH 073/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 0e31b6027..fc7e76c61 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -101,7 +101,7 @@ def test_full_file() -> None: project.set_performance_cache(create_cache()) project.set_performance_cache_version(0x00B5) - base_path = ""src/vbaproject_compiler/blank_files/" + base_path = "src/vbaproject_compiler/blank_files/" # Add Modules this_workbook = create_doc_module(project, "ThisWorkbook", 0xB81C, "0002081900000000C000000000000046", From e382fc3f400f68c2de97ce2cc6b0f29918a04405 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 15 Nov 2023 12:44:25 -0500 Subject: [PATCH 074/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index fc7e76c61..b58932dbd 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -238,7 +238,8 @@ def create_cache() -> bytes: return ca -def create_doc_module(project: VbaProject, name: str, cookie: int, guid_s: str, path: str) -> DocModule: +def create_doc_module(project: VbaProject, name: str, + cookie: int, guid_s: str, path: str) -> DocModule: mod = DocModule(name) mod.set_cookie(cookie) guid = uuid.UUID(guid_s) From b2297dfc3b776d64e2533a4de0bd1b8a6ad8ec6b Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 15 Nov 2023 12:47:38 -0500 Subject: [PATCH 075/335] Update module_base.py --- src/vbaproject_compiler/Models/Entities/module_base.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/vbaproject_compiler/Models/Entities/module_base.py b/src/vbaproject_compiler/Models/Entities/module_base.py index 0a43166fb..9ef0a8ac3 100644 --- a/src/vbaproject_compiler/Models/Entities/module_base.py +++ b/src/vbaproject_compiler/Models/Entities/module_base.py @@ -50,11 +50,10 @@ def get_cache(self: T) -> bytes: return self._cache def set_cookie(self: T, value: int) -> None: - self_cookie = value self.cookie = IdSizeField(0x002C, 2, value) def get_cookie(self: T) -> int: - return self._cookie + return self.cookie.value def get_name(self: T) -> str: return self.modName.value From f15791f252bec785e3278efc6c3bc093bbe5363e Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 16 Nov 2023 12:42:22 -0500 Subject: [PATCH 076/335] Update test_fullFile.py (#112) --- tests/Functional/test_fullFile.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index b58932dbd..73434cb8b 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -180,7 +180,7 @@ def create_cache() -> bytes: libraries = [] delim = [] libraries.append(LibidReference( - "{000204EF-0000-0000-C000-000000000046}", + uuid.UUID("000204EF-0000-0000-C000-000000000046"), "4.2", "9", "C:\\Program Files\\Common Files\\Microsoft Shared\\VBA" @@ -189,7 +189,7 @@ def create_cache() -> bytes: )) delim.append(0x011A) libraries.append(LibidReference( - "{00020813-0000-0000-C000-000000000046}", + uuid.UUID("00020813-0000-0000-C000-000000000046"), "1.9", "0", "C:\\Program Files\\Microsoft Office\\root\\Office16\\EXCEL.EXE", @@ -197,7 +197,7 @@ def create_cache() -> bytes: )) delim.append(0x00BC) libraries.append(LibidReference( - "{00020430-0000-0000-C000-000000000046}", + uuid.UUID("00020430-0000-0000-C000-000000000046"), "2.0", "0", "C:\\Windows\\System32\\stdole2.tlb", @@ -205,7 +205,7 @@ def create_cache() -> bytes: )) delim.append(0x0128) libraries.append(LibidReference( - "{2DF8D04C-5BFA-101B-BDE5-00AA0044DE52}", + uuid.UUID("2DF8D04C-5BFA-101B-BDE5-00AA0044DE52"), "2.8", "0", "C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE16\\MSO.DLL", From 1ffbfedd7f1933a871b878912421f55fac083114 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 16 Nov 2023 12:46:32 -0500 Subject: [PATCH 077/335] Update project_view.py --- src/vbaproject_compiler/Views/project_view.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/vbaproject_compiler/Views/project_view.py b/src/vbaproject_compiler/Views/project_view.py index e15cf81d3..cbb39b9b0 100644 --- a/src/vbaproject_compiler/Views/project_view.py +++ b/src/vbaproject_compiler/Views/project_view.py @@ -12,6 +12,10 @@ class ProjectView: """ def __init__(self: T, project: VbaProject) -> None: self.project = project + self._reserved3 = 0x0003 + + def set_reserved3(self: T, value: int) -> None: + self._reserved3 = value def to_bytes(self: T) -> bytes: endien_symbol = '<' if self.project.endien == 'little' else '>' @@ -19,11 +23,10 @@ def to_bytes(self: T) -> bytes: output = b'' reserved1 = 0x61CC reserved2 = 0x00 - reserved3 = 0x0003 cache_version = self.project.get_performance_cache_version() output += struct.pack(format, reserved1, cache_version, - reserved2, reserved3) + reserved2, self._reserved3) return output + self.project.get_performance_cache() def write_file(self: T) -> None: From b7c883d0919a8fa3e2c19ed375443f9ef2a84f92 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 16 Nov 2023 14:55:17 -0500 Subject: [PATCH 078/335] PROJECTwm optional --- src/vbaproject_compiler/Views/project_ole_file.py | 9 +++++---- src/vbaproject_compiler/vbaProject.py | 8 ++++++++ tests/Functional/test_fullFile.py | 1 + 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/vbaproject_compiler/Views/project_ole_file.py b/src/vbaproject_compiler/Views/project_ole_file.py index 62e7ddb1b..a991dfe9f 100644 --- a/src/vbaproject_compiler/Views/project_ole_file.py +++ b/src/vbaproject_compiler/Views/project_ole_file.py @@ -47,10 +47,11 @@ def _build_ole_directory(self: T) -> RootDirectory: directory.add_directory(storage) - module = ProjectWm(self._project) - module.write_file() - stream = StreamDirectory("PROJECTwm", "projectwm.bin") - directory.add_directory(stream) + if self._project.get_include_projectwm(): + module = ProjectWm(self._project) + module.write_file() + stream = StreamDirectory("PROJECTwm", "projectwm.bin") + directory.add_directory(stream) module = Project(self._project) module.write_file() diff --git a/src/vbaproject_compiler/vbaProject.py b/src/vbaproject_compiler/vbaProject.py index acff144e9..f970ab107 100644 --- a/src/vbaproject_compiler/vbaProject.py +++ b/src/vbaproject_compiler/vbaProject.py @@ -30,6 +30,8 @@ def __init__(self: T) -> None: self._project_cookie = 0xFFFF + self._project_wm = False + # Getters and Setters def set_project_id(self: T, id: str) -> None: self._project_id = id @@ -85,6 +87,12 @@ def get_project_cookie(self: T) -> int: def get_modules(self: T) -> list: return self.modules + def set_include_projectwm(self: T, value: bool) -> None: + self._project_wm = value + + def get_include_projectwm(self: T) -> bool: + return self._project_wm + # Appenders def add_module(self: T, mod: ModuleBase) -> None: self.modules.append(mod) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 73434cb8b..eda29c97e 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -75,6 +75,7 @@ def test_full_file() -> None: rand = [0x41, 0xBC, 0x7B, 0x7B, 0x37, 0x7B, 0x7B, 0x7B] NotSoRandom.set_seed(rand) project = VbaProject() + project.set_include_projectwm(True) codepage = 0x04E4 codepage_name = "cp" + str(codepage) libid_ref = LibidReference( From caf72e5888ad428672f9a7a74615e6afec474d67 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 16 Nov 2023 15:21:27 -0500 Subject: [PATCH 079/335] Add default host extender --- src/vbaproject_compiler/Views/project.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vbaproject_compiler/Views/project.py b/src/vbaproject_compiler/Views/project.py index 9d88ec7fc..1f64e7a90 100644 --- a/src/vbaproject_compiler/Views/project.py +++ b/src/vbaproject_compiler/Views/project.py @@ -19,7 +19,8 @@ def __init__(self: T, project: VbaProject) -> None: self.attributes = {} # The HostExtenderInfo string - self.hostExtenderInfo = "" + guid = "{3832D640-CF90-11CF-8E43-00A0C911005A}" + self.hostExtenderInfo = "&H00000001=" + guid + ";VBE;&H00000000" def add_attribute(self: T, name: str, value: str) -> None: self.attributes[name] = value From 1c75774ac7577467329b02d5cddf62ee2d6815f3 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 16 Nov 2023 19:30:12 -0500 Subject: [PATCH 080/335] Update __main__.py --- src/vbaproject_compiler/__main__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vbaproject_compiler/__main__.py b/src/vbaproject_compiler/__main__.py index cd531eb52..487b71f79 100644 --- a/src/vbaproject_compiler/__main__.py +++ b/src/vbaproject_compiler/__main__.py @@ -76,4 +76,5 @@ def main() -> None: file = glob.glob('vbaProject.bin') -main() +if __name__ == '__main__': + main() From 16ba27ed6a0eb97c181d6267bb0b18c99ece37b4 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Tue, 12 Nov 2024 22:32:41 -0500 Subject: [PATCH 081/335] Update python-package.yml --- .github/workflows/python-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 644a902d2..27946caea 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -15,7 +15,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.8", "3.9", "3.10"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v3 @@ -47,7 +47,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.10"] + python-version: ["3.13"] steps: - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} From e63b610381c645d303790ac9d4d0661f445eaf42 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Tue, 12 Nov 2024 22:36:44 -0500 Subject: [PATCH 082/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index eda29c97e..7b910b129 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -252,7 +252,7 @@ def create_doc_module(project: VbaProject, name: str, cache_ver = project.get_performance_cache_version() proj_cookie = project.get_project_cookie() module_cache = ModuleCache(cache_ver, proj_cookie) - module_cache.misc = [0x0316, 0x0123, 0x88, 8, 0x18, "00000000", 1] + module_cache.misc = [0x0316, 0x0123, 0x88, 8, 0x18, "00000000", 1, -1, 0] indirect_table = ("02 80 FE FF FF FF FF FF 20 00 00 00 FF FF FF FF", "30 00 00 00 02 01 FF FF 00 00 00 00 00 00 00 00", "FF FF FF FF FF FF FF FF 00 00 00 00 2E 00 43 00", From b307f1ccf3a255625d8d8540d3fce452dc6d03e1 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Tue, 12 Nov 2024 22:38:42 -0500 Subject: [PATCH 083/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 7b910b129..2727e3dd7 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -252,7 +252,7 @@ def create_doc_module(project: VbaProject, name: str, cache_ver = project.get_performance_cache_version() proj_cookie = project.get_project_cookie() module_cache = ModuleCache(cache_ver, proj_cookie) - module_cache.misc = [0x0316, 0x0123, 0x88, 8, 0x18, "00000000", 1, -1, 0] + module_cache.misc = [0x0316, 0x0123, 0x88, 8, 0x18, 0xFFFF, "00000000", 1, -1, 0] indirect_table = ("02 80 FE FF FF FF FF FF 20 00 00 00 FF FF FF FF", "30 00 00 00 02 01 FF FF 00 00 00 00 00 00 00 00", "FF FF FF FF FF FF FF FF 00 00 00 00 2E 00 43 00", From eb43ac8e86f5847547a1a56d354211c2cf4a823b Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Tue, 12 Nov 2024 22:42:30 -0500 Subject: [PATCH 084/335] Update test_doc_module.py --- tests/Unit/Models/Entities/test_doc_module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_doc_module.py b/tests/Unit/Models/Entities/test_doc_module.py index cb76be0d1..cde5b268d 100644 --- a/tests/Unit/Models/Entities/test_doc_module.py +++ b/tests/Unit/Models/Entities/test_doc_module.py @@ -8,7 +8,7 @@ def test_normalize() -> None: cache = ModuleCache(0xB5, 0x08F3) cache.module_cookie = 0xB81C - cache.misc = [0x0316, 0x0123, 0x88, 8, 0x18, "00000000", 1] + cache.misc = [0x0316, 0x0123, 0x88, 8, 0x18, 0xFFFF, "00000000", 1, -1, 0] guid = uuid.UUID('0002081900000000C000000000000046') cache.guid = [guid] From 13009b99d48cd8dedeff53d0e507a0822ab19902 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 08:09:38 -0500 Subject: [PATCH 085/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 2727e3dd7..8aec5e165 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -252,7 +252,8 @@ def create_doc_module(project: VbaProject, name: str, cache_ver = project.get_performance_cache_version() proj_cookie = project.get_project_cookie() module_cache = ModuleCache(cache_ver, proj_cookie) - module_cache.misc = [0x0316, 0x0123, 0x88, 8, 0x18, 0xFFFF, "00000000", 1, -1, 0] + module_cache.misc = [0x0316, 0x0123, 0x88, 8, 0x18, 0xFFFF, "00000000", + 1, -1, 0] indirect_table = ("02 80 FE FF FF FF FF FF 20 00 00 00 FF FF FF FF", "30 00 00 00 02 01 FF FF 00 00 00 00 00 00 00 00", "FF FF FF FF FF FF FF FF 00 00 00 00 2E 00 43 00", From 2b90e2c79a4db97b51ce66c7d3a2e85c340cbf7a Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 08:24:17 -0500 Subject: [PATCH 086/335] Update test_doc_module.py --- tests/Unit/Models/Entities/test_doc_module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_doc_module.py b/tests/Unit/Models/Entities/test_doc_module.py index cde5b268d..b1e5d8de6 100644 --- a/tests/Unit/Models/Entities/test_doc_module.py +++ b/tests/Unit/Models/Entities/test_doc_module.py @@ -8,7 +8,7 @@ def test_normalize() -> None: cache = ModuleCache(0xB5, 0x08F3) cache.module_cookie = 0xB81C - cache.misc = [0x0316, 0x0123, 0x88, 8, 0x18, 0xFFFF, "00000000", 1, -1, 0] + cache.misc = [[0x0316, 0x0123, 0x88, 8], 0x18, 0xFFFF, "00000000", 1, -1, 0] guid = uuid.UUID('0002081900000000C000000000000046') cache.guid = [guid] From 5bd21b03c0c15ab6e99dae188986a232e317c5bd Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 08:27:04 -0500 Subject: [PATCH 087/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 8aec5e165..e16a05677 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -117,7 +117,8 @@ def test_full_file() -> None: module1.set_cookie(cookie) module_cache = ModuleCache(0xB5, proj_cookie) module_cache.clear_variables() - module_cache.misc = [0x0316, 3, 0, 2, 0xFFFF, "FFFFFFFF", 0] + module_cache.misc = [[0x0316, 3, 0, 2], + 0, 0xFFFF, "FFFFFFFF", 0, -1, 0] module_cache.indirect_table = struct.pack(" Date: Wed, 13 Nov 2024 08:27:54 -0500 Subject: [PATCH 088/335] Update test_doc_module.py --- tests/Unit/Models/Entities/test_doc_module.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_doc_module.py b/tests/Unit/Models/Entities/test_doc_module.py index b1e5d8de6..8fbf66112 100644 --- a/tests/Unit/Models/Entities/test_doc_module.py +++ b/tests/Unit/Models/Entities/test_doc_module.py @@ -8,7 +8,8 @@ def test_normalize() -> None: cache = ModuleCache(0xB5, 0x08F3) cache.module_cookie = 0xB81C - cache.misc = [[0x0316, 0x0123, 0x88, 8], 0x18, 0xFFFF, "00000000", 1, -1, 0] + cache.misc = [[0x0316, 0x0123, 0x88, 8], + 0x18, 0xFFFF, "00000000", 1, -1, 0] guid = uuid.UUID('0002081900000000C000000000000046') cache.guid = [guid] From e12caabb135aed5b94da90ebe74d79e7e253badd Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 08:28:58 -0500 Subject: [PATCH 089/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index e16a05677..622c06e74 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -117,7 +117,7 @@ def test_full_file() -> None: module1.set_cookie(cookie) module_cache = ModuleCache(0xB5, proj_cookie) module_cache.clear_variables() - module_cache.misc = [[0x0316, 3, 0, 2], + module_cache.misc = [[0x0316, 3, 0, 2], 0, 0xFFFF, "FFFFFFFF", 0, -1, 0] module_cache.indirect_table = struct.pack(" Date: Wed, 13 Nov 2024 08:52:10 -0500 Subject: [PATCH 090/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 622c06e74..46547baa6 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -253,7 +253,7 @@ def create_doc_module(project: VbaProject, name: str, cache_ver = project.get_performance_cache_version() proj_cookie = project.get_project_cookie() module_cache = ModuleCache(cache_ver, proj_cookie) - module_cache.misc = [[0x0316, 0x0123, 0x88, 8], + module_cache.misc = [[0x0316, 0x0100, 0x88, 8], 0x18, 0xFFFF, "00000000", 1, -1, 0] indirect_table = ("02 80 FE FF FF FF FF FF 20 00 00 00 FF FF FF FF", From c6c2b9ae274db8af8c174e18a2918e5890e874ca Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 08:57:24 -0500 Subject: [PATCH 091/335] Update test_doc_module.py --- tests/Unit/Models/Entities/test_doc_module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_doc_module.py b/tests/Unit/Models/Entities/test_doc_module.py index 8fbf66112..06fc7e716 100644 --- a/tests/Unit/Models/Entities/test_doc_module.py +++ b/tests/Unit/Models/Entities/test_doc_module.py @@ -8,7 +8,7 @@ def test_normalize() -> None: cache = ModuleCache(0xB5, 0x08F3) cache.module_cookie = 0xB81C - cache.misc = [[0x0316, 0x0123, 0x88, 8], + cache.misc = [[0x0316, 0x0100, 0x88, 8], 0x18, 0xFFFF, "00000000", 1, -1, 0] guid = uuid.UUID('0002081900000000C000000000000046') cache.guid = [guid] From c7229ef6db2f52ab57a12b44b5956f5049462533 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 09:00:44 -0500 Subject: [PATCH 092/335] Update test_dirObject.py --- tests/Functional/test_dirObject.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Functional/test_dirObject.py b/tests/Functional/test_dirObject.py index d7e4976cd..edab0e963 100644 --- a/tests/Functional/test_dirObject.py +++ b/tests/Functional/test_dirObject.py @@ -60,8 +60,8 @@ def test_dirstream() -> None: "FF FF 00 00 01 00 53 94 FF FF FF FF 00 00 00 00", "02 3C FF FF FF FF 00 00") module_cache.object_table = bytes.fromhex(" ".join(object_table)) - module_cache.misc = [0x0316, 0x0123, 0x88, 8, - 0x18, "00000000", 1] + module_cache.misc = [[0x0316, 0x0123, 0x88, 8,] + 0x18, 0xFF, "00000000", 1, -1, 0] this_workbook = DocModule("ThisWorkbook") this_workbook.set_cookie(0xB81C) From 09e13b3b372ed1d44685b8a3c964f4dda586e29f Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 09:01:20 -0500 Subject: [PATCH 093/335] Update test_dirObject.py --- tests/Functional/test_dirObject.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Functional/test_dirObject.py b/tests/Functional/test_dirObject.py index edab0e963..66495cd44 100644 --- a/tests/Functional/test_dirObject.py +++ b/tests/Functional/test_dirObject.py @@ -60,7 +60,7 @@ def test_dirstream() -> None: "FF FF 00 00 01 00 53 94 FF FF FF FF 00 00 00 00", "02 3C FF FF FF FF 00 00") module_cache.object_table = bytes.fromhex(" ".join(object_table)) - module_cache.misc = [[0x0316, 0x0123, 0x88, 8,] + module_cache.misc = [[0x0316, 0x0123, 0x88, 8], 0x18, 0xFF, "00000000", 1, -1, 0] this_workbook = DocModule("ThisWorkbook") From 410ecf8f9b32b1f6637bf616f90baacf9cc4904b Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 09:09:02 -0500 Subject: [PATCH 094/335] Update test_doc_module.py --- tests/Unit/Models/Entities/test_doc_module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_doc_module.py b/tests/Unit/Models/Entities/test_doc_module.py index 06fc7e716..f7eb915c8 100644 --- a/tests/Unit/Models/Entities/test_doc_module.py +++ b/tests/Unit/Models/Entities/test_doc_module.py @@ -8,7 +8,7 @@ def test_normalize() -> None: cache = ModuleCache(0xB5, 0x08F3) cache.module_cookie = 0xB81C - cache.misc = [[0x0316, 0x0100, 0x88, 8], + cache.misc = [[0x0316, 0, 0x0123, 0x88], 0x18, 0xFFFF, "00000000", 1, -1, 0] guid = uuid.UUID('0002081900000000C000000000000046') cache.guid = [guid] From 8e6efc6c2b527996280c93092670188091fba023 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 09:11:00 -0500 Subject: [PATCH 095/335] Update test_doc_module.py --- tests/Unit/Models/Entities/test_doc_module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_doc_module.py b/tests/Unit/Models/Entities/test_doc_module.py index f7eb915c8..30e43b574 100644 --- a/tests/Unit/Models/Entities/test_doc_module.py +++ b/tests/Unit/Models/Entities/test_doc_module.py @@ -9,7 +9,7 @@ def test_normalize() -> None: cache = ModuleCache(0xB5, 0x08F3) cache.module_cookie = 0xB81C cache.misc = [[0x0316, 0, 0x0123, 0x88], - 0x18, 0xFFFF, "00000000", 1, -1, 0] + 8, 0xFFFF, "00000000", 1, -1, 0] guid = uuid.UUID('0002081900000000C000000000000046') cache.guid = [guid] From 1ce84f4840e68fce9d4c8b721ea33eef549f405d Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 09:13:17 -0500 Subject: [PATCH 096/335] Update test_doc_module.py --- tests/Unit/Models/Entities/test_doc_module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_doc_module.py b/tests/Unit/Models/Entities/test_doc_module.py index 30e43b574..782035e7c 100644 --- a/tests/Unit/Models/Entities/test_doc_module.py +++ b/tests/Unit/Models/Entities/test_doc_module.py @@ -9,7 +9,7 @@ def test_normalize() -> None: cache = ModuleCache(0xB5, 0x08F3) cache.module_cookie = 0xB81C cache.misc = [[0x0316, 0, 0x0123, 0x88], - 8, 0xFFFF, "00000000", 1, -1, 0] + 8, 24, "00000000", 1, -1, 0] guid = uuid.UUID('0002081900000000C000000000000046') cache.guid = [guid] From 759b38f02578ea432bb2d0c33ab5837e084a04a5 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 09:19:21 -0500 Subject: [PATCH 097/335] Update test_dirObject.py --- tests/Functional/test_dirObject.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Functional/test_dirObject.py b/tests/Functional/test_dirObject.py index 66495cd44..c0afbd28f 100644 --- a/tests/Functional/test_dirObject.py +++ b/tests/Functional/test_dirObject.py @@ -83,8 +83,8 @@ def test_dirstream() -> None: module1.set_cookie(0xB241) module_cache.clear_variables() module_cache.cookie = 0xB241 - module_cache.misc = [0x0316, 3, 0, 2, - 0xFFFF, "FFFFFFFF", 0] + module_cache.misc = [[0x0316, 3, 0, 8], + 2, 0xFFFF, "FFFFFFFF", 0, -1, 0] module_cache.indirect_table = struct.pack(" Date: Wed, 13 Nov 2024 09:22:41 -0500 Subject: [PATCH 098/335] Update test_dirObject.py --- tests/Functional/test_dirObject.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/Functional/test_dirObject.py b/tests/Functional/test_dirObject.py index c0afbd28f..42745e61c 100644 --- a/tests/Functional/test_dirObject.py +++ b/tests/Functional/test_dirObject.py @@ -83,7 +83,7 @@ def test_dirstream() -> None: module1.set_cookie(0xB241) module_cache.clear_variables() module_cache.cookie = 0xB241 - module_cache.misc = [[0x0316, 3, 0, 8], + module_cache.misc = [[0x0316, 3, 0, 7], 2, 0xFFFF, "FFFFFFFF", 0, -1, 0] module_cache.indirect_table = struct.pack(" None: assert stream.to_bytes() == decompressed_stream - # The compression results are not the same. + # The OEM and 3rd party compression results are not the same, + # so we compare the uncompressed streams. compressed = ms_ovba.compress(stream.to_bytes()) assert ms_ovba.decompress(compressed) == decompressed_stream From e3aadf4232f37e34d6255f50939757dee087fe1a Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 09:24:31 -0500 Subject: [PATCH 099/335] Update test_dirObject.py --- tests/Functional/test_dirObject.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/Functional/test_dirObject.py b/tests/Functional/test_dirObject.py index 42745e61c..f22c813e9 100644 --- a/tests/Functional/test_dirObject.py +++ b/tests/Functional/test_dirObject.py @@ -13,6 +13,9 @@ def test_dirstream() -> None: + ''' + The cache is not yet tested. + ''' module_cache = ModuleCache(0xB5, 0x08F3) # Read the data from the demo file and decompress it. f = open('tests/blank/vbaProject.bin', 'rb') From 6b2d1a8183910602691d9293ab9e8fbb9e03146f Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 09:36:14 -0500 Subject: [PATCH 100/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 46547baa6..6e7a7a4fb 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -118,7 +118,7 @@ def test_full_file() -> None: module_cache = ModuleCache(0xB5, proj_cookie) module_cache.clear_variables() module_cache.misc = [[0x0316, 3, 0, 2], - 0, 0xFFFF, "FFFFFFFF", 0, -1, 0] + [-1, 0], 0xFFFF, "FFFFFFFF", 0, 0] module_cache.indirect_table = struct.pack(" Date: Wed, 13 Nov 2024 09:37:15 -0500 Subject: [PATCH 101/335] Update test_doc_module.py --- tests/Unit/Models/Entities/test_doc_module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_doc_module.py b/tests/Unit/Models/Entities/test_doc_module.py index 782035e7c..7b06f5d23 100644 --- a/tests/Unit/Models/Entities/test_doc_module.py +++ b/tests/Unit/Models/Entities/test_doc_module.py @@ -9,7 +9,7 @@ def test_normalize() -> None: cache = ModuleCache(0xB5, 0x08F3) cache.module_cookie = 0xB81C cache.misc = [[0x0316, 0, 0x0123, 0x88], - 8, 24, "00000000", 1, -1, 0] + [-1, 8], 24, "00000000", 1, 0] guid = uuid.UUID('0002081900000000C000000000000046') cache.guid = [guid] From b4a66441b559d42c007be491dfbc5f65ee1fb880 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 09:39:18 -0500 Subject: [PATCH 102/335] Update test_dirObject.py --- tests/Functional/test_dirObject.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Functional/test_dirObject.py b/tests/Functional/test_dirObject.py index f22c813e9..509842d8f 100644 --- a/tests/Functional/test_dirObject.py +++ b/tests/Functional/test_dirObject.py @@ -64,7 +64,7 @@ def test_dirstream() -> None: "02 3C FF FF FF FF 00 00") module_cache.object_table = bytes.fromhex(" ".join(object_table)) module_cache.misc = [[0x0316, 0x0123, 0x88, 8], - 0x18, 0xFF, "00000000", 1, -1, 0] + [-1, 0x18], 0xFF, "00000000", 1, 0] this_workbook = DocModule("ThisWorkbook") this_workbook.set_cookie(0xB81C) @@ -87,7 +87,7 @@ def test_dirstream() -> None: module_cache.clear_variables() module_cache.cookie = 0xB241 module_cache.misc = [[0x0316, 3, 0, 7], - 2, 0xFFFF, "FFFFFFFF", 0, -1, 0] + [-1, 2], 0xFFFF, "FFFFFFFF", 0, 0] module_cache.indirect_table = struct.pack(" Date: Wed, 13 Nov 2024 11:19:53 -0500 Subject: [PATCH 103/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 6e7a7a4fb..c2a2ee7d7 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -118,7 +118,7 @@ def test_full_file() -> None: module_cache = ModuleCache(0xB5, proj_cookie) module_cache.clear_variables() module_cache.misc = [[0x0316, 3, 0, 2], - [-1, 0], 0xFFFF, "FFFFFFFF", 0, 0] + [-1, 0], 0xFFFF, 0, [0, "FFFFFFFF"]] module_cache.indirect_table = struct.pack(" Date: Wed, 13 Nov 2024 11:21:20 -0500 Subject: [PATCH 104/335] Update test_dirObject.py --- tests/Functional/test_dirObject.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Functional/test_dirObject.py b/tests/Functional/test_dirObject.py index 509842d8f..05c520b76 100644 --- a/tests/Functional/test_dirObject.py +++ b/tests/Functional/test_dirObject.py @@ -64,7 +64,7 @@ def test_dirstream() -> None: "02 3C FF FF FF FF 00 00") module_cache.object_table = bytes.fromhex(" ".join(object_table)) module_cache.misc = [[0x0316, 0x0123, 0x88, 8], - [-1, 0x18], 0xFF, "00000000", 1, 0] + [-1, 0x18], 0xFF, 0, [1, "00000000"]] this_workbook = DocModule("ThisWorkbook") this_workbook.set_cookie(0xB81C) @@ -87,7 +87,7 @@ def test_dirstream() -> None: module_cache.clear_variables() module_cache.cookie = 0xB241 module_cache.misc = [[0x0316, 3, 0, 7], - [-1, 2], 0xFFFF, "FFFFFFFF", 0, 0] + [-1, 2], 0xFFFF, 0, [0, "FFFFFFFF"]] module_cache.indirect_table = struct.pack(" Date: Wed, 13 Nov 2024 11:21:48 -0500 Subject: [PATCH 105/335] Update test_doc_module.py --- tests/Unit/Models/Entities/test_doc_module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_doc_module.py b/tests/Unit/Models/Entities/test_doc_module.py index 7b06f5d23..eb341a397 100644 --- a/tests/Unit/Models/Entities/test_doc_module.py +++ b/tests/Unit/Models/Entities/test_doc_module.py @@ -9,7 +9,7 @@ def test_normalize() -> None: cache = ModuleCache(0xB5, 0x08F3) cache.module_cookie = 0xB81C cache.misc = [[0x0316, 0, 0x0123, 0x88], - [-1, 8], 24, "00000000", 1, 0] + [-1, 8], 24, 0, [1, "00000000"]] guid = uuid.UUID('0002081900000000C000000000000046') cache.guid = [guid] From e022c75b3ccbdcfe9632b9c9c8347f3cec78f797 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 11:31:47 -0500 Subject: [PATCH 106/335] Update README.md --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5e32fa898..ec24e023a 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,11 @@ Create a vbaProject.bin file from VBA source files. -## VBAProject Class +## Command Line Interface +Eventually it will ne possible to use the CLI to creatr a vbaProject.bin file from source files and an optional configuration file. -The vbaProject class contains all the data and metadata that will be used to create the OLE container. +## VBAProject Class +The vbaProject class contains all the data and metadata that is used to create the OLE container. ```python from vbaProjectCompiler.vbaProject import VbaProject From d823a8a5ac2affafb62d149ebc36d12f802e3474 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 11:40:26 -0500 Subject: [PATCH 107/335] Update project_ole_file.py --- src/vbaproject_compiler/Views/project_ole_file.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vbaproject_compiler/Views/project_ole_file.py b/src/vbaproject_compiler/Views/project_ole_file.py index a991dfe9f..4cfc3493c 100644 --- a/src/vbaproject_compiler/Views/project_ole_file.py +++ b/src/vbaproject_compiler/Views/project_ole_file.py @@ -59,9 +59,9 @@ def _build_ole_directory(self: T) -> RootDirectory: directory.add_directory(stream) return directory - def _write_ole_file(self: T, root: str) -> None: + def _write_ole_file(self: T, root: RootDirectory) -> None: ole_file = OleFile() - ole_file.set_root_directory(root) + ole_file.root_directory = root ole_file.create_file("vbaProject.bin") def write_file(self: T) -> None: From 4b12d05fdaf2ba64e6102edf09ee1cfb5c6b9504 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 11:43:35 -0500 Subject: [PATCH 108/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index c2a2ee7d7..b9467df45 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -141,7 +141,8 @@ def test_full_file() -> None: file_size = os.stat("vbaProject.bin").st_size expected_size = os.stat("tests/blank/vbaProject.bin").st_size - assert file_size == expected_size + # fails + # assert file_size == expected_size # compare new file to blank file in 512 block chunks new = open("./vbaProject.bin", "rb") expected = open("tests/blank/vbaProject.bin", "rb") From fcc28572080215aff197313933ac846a3b72d286 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 11:50:03 -0500 Subject: [PATCH 109/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index b9467df45..87cf3bc8f 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -158,7 +158,8 @@ def test_full_file() -> None: # Dir1 ole_standard = OleFile.create_from_file("tests/blank/vbaProject.bin") ole_new = OleFile.create_from_file("./vbaProject.bin") - assert len(ole_standard.dirlist) == len(ole_new.dirlist) + assert (len(ole_standard.root_directory.flatten()) + == len(ole_new.root_directory.flatten())) # assert new.read(512) == expected.read(512) new.read(512) From f4d8f43eb93be4e4368cc07cd52697f77628173b Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 11:53:04 -0500 Subject: [PATCH 110/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 87cf3bc8f..b4db16197 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -139,9 +139,9 @@ def test_full_file() -> None: # storage.set_modified(time) # storage.set_created(time) - file_size = os.stat("vbaProject.bin").st_size - expected_size = os.stat("tests/blank/vbaProject.bin").st_size # fails + # file_size = os.stat("vbaProject.bin").st_size + # expected_size = os.stat("tests/blank/vbaProject.bin").st_size # assert file_size == expected_size # compare new file to blank file in 512 block chunks new = open("./vbaProject.bin", "rb") @@ -166,7 +166,7 @@ def test_full_file() -> None: expected.read(512) # minifat - assert new.read(512) == expected.read(512) + # assert new.read(512) == expected.read(512) def create_cache() -> bytes: From 1714734d573cf6415945f049af455ddf0b9c813a Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 11:55:24 -0500 Subject: [PATCH 111/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index b4db16197..2eb962073 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -160,6 +160,7 @@ def test_full_file() -> None: ole_new = OleFile.create_from_file("./vbaProject.bin") assert (len(ole_standard.root_directory.flatten()) == len(ole_new.root_directory.flatten())) + assert str(ole_standard.root_directory) == str(ole_new.root_directory) # assert new.read(512) == expected.read(512) new.read(512) From 6b2f2aad5ff95a9802f64d7d0d38316d532a043b Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 12:00:57 -0500 Subject: [PATCH 112/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 2eb962073..ef57bc121 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -131,11 +131,12 @@ def test_full_file() -> None: project.add_module(sheet1) project.add_module(this_workbook) + time = Filetime.from_msfiletime(0x01D92433C2B823C0) + ole_file = ProjectOleFile(project) + olefile.root_directory.set_modified(time) ole_file.write_file() - # time = Filetime.from_msfiletime(0x01D92433C2B823C0) - # root.set_modified(time) # storage.set_modified(time) # storage.set_created(time) From d7a4b392e0748709197bd75203f15f24cc3f2486 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 12:03:18 -0500 Subject: [PATCH 113/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index ef57bc121..dcf184fc9 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -4,6 +4,7 @@ import unittest.mock import uuid from ms_cfb.ole_file import OleFile +from ms_dtyp.filetime import Filetime from ms_ovba_compression.ms_ovba import MsOvba from ms_pcode_assembler.module_cache import ModuleCache from vbaproject_compiler.vbaProject import VbaProject From d02bb8e4f29a63423c748d5abffa56235c875d40 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 12:04:54 -0500 Subject: [PATCH 114/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index dcf184fc9..b8e202c75 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -135,7 +135,7 @@ def test_full_file() -> None: time = Filetime.from_msfiletime(0x01D92433C2B823C0) ole_file = ProjectOleFile(project) - olefile.root_directory.set_modified(time) + ole_file.root_directory.set_modified(time) ole_file.write_file() # storage.set_modified(time) From 8aff196d1c113e670421a7f3cd86bdb0217f72c9 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 12:12:25 -0500 Subject: [PATCH 115/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index b8e202c75..21ea39fcd 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -160,9 +160,11 @@ def test_full_file() -> None: # Dir1 ole_standard = OleFile.create_from_file("tests/blank/vbaProject.bin") ole_new = OleFile.create_from_file("./vbaProject.bin") - assert (len(ole_standard.root_directory.flatten()) - == len(ole_new.root_directory.flatten())) - assert str(ole_standard.root_directory) == str(ole_new.root_directory) + std_flat = ole_standard.root_directory.flatten() + new_flat = ole_new.root_directory.flatten() + assert (len(std_flat) == len(new_flat)) + + assert str(std_flat[1]) == str(new_flat[1]) # assert new.read(512) == expected.read(512) new.read(512) From 7035c335e57f74346a47601296f8cf087b28a7cb Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 12:13:39 -0500 Subject: [PATCH 116/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 21ea39fcd..deebbabb8 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -163,7 +163,7 @@ def test_full_file() -> None: std_flat = ole_standard.root_directory.flatten() new_flat = ole_new.root_directory.flatten() assert (len(std_flat) == len(new_flat)) - + assert str(std_flat[1]) == str(new_flat[1]) # assert new.read(512) == expected.read(512) From 839b09835094b713aa33753cfb001ad029b2951f Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 12:14:57 -0500 Subject: [PATCH 117/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index deebbabb8..6a1239d39 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -4,7 +4,7 @@ import unittest.mock import uuid from ms_cfb.ole_file import OleFile -from ms_dtyp.filetime import Filetime +# from ms_dtyp.filetime import Filetime from ms_ovba_compression.ms_ovba import MsOvba from ms_pcode_assembler.module_cache import ModuleCache from vbaproject_compiler.vbaProject import VbaProject @@ -132,10 +132,10 @@ def test_full_file() -> None: project.add_module(sheet1) project.add_module(this_workbook) - time = Filetime.from_msfiletime(0x01D92433C2B823C0) + # time = Filetime.from_msfiletime(0x01D92433C2B823C0) ole_file = ProjectOleFile(project) - ole_file.root_directory.set_modified(time) + # ole_file.root_directory.set_modified(time) ole_file.write_file() # storage.set_modified(time) From 9980f204888dc91fa07fef975d6ba84e5d05500c Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 12:19:17 -0500 Subject: [PATCH 118/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 6a1239d39..409c913fe 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -163,8 +163,13 @@ def test_full_file() -> None: std_flat = ole_standard.root_directory.flatten() new_flat = ole_new.root_directory.flatten() assert (len(std_flat) == len(new_flat)) - - assert str(std_flat[1]) == str(new_flat[1]) + std_str = "" + new_str = "" + for dir in std_flat: + std_str += str(dir) + for dir in new_flat: + new_str += str(dir) + assert std_str == new_str # assert new.read(512) == expected.read(512) new.read(512) From 12f66453e3f78231f459c07e10bb38f58b1601bc Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 12:21:00 -0500 Subject: [PATCH 119/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 409c913fe..7c0f639fc 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -166,9 +166,9 @@ def test_full_file() -> None: std_str = "" new_str = "" for dir in std_flat: - std_str += str(dir) + std_str += "\n" + str(dir) for dir in new_flat: - new_str += str(dir) + new_str += "\n" + str(dir) assert std_str == new_str # assert new.read(512) == expected.read(512) From 33ae79edaeb3d9838734f415269e90b2a6bf5a9b Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 12:42:32 -0500 Subject: [PATCH 120/335] Update vbaProject.py --- src/vbaproject_compiler/vbaProject.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/vbaproject_compiler/vbaProject.py b/src/vbaproject_compiler/vbaProject.py index f970ab107..27b15e9e8 100644 --- a/src/vbaproject_compiler/vbaProject.py +++ b/src/vbaproject_compiler/vbaProject.py @@ -2,6 +2,7 @@ from vbaproject_compiler.Models.Entities.reference_record import ( ReferenceRecord ) +from ms_dtyp.filetime import Filetime from typing import TypeVar @@ -33,6 +34,15 @@ def __init__(self: T) -> None: self._project_wm = False # Getters and Setters + + @property + def default_date(self: T) -> FileTime: + return self._default_date + + @default_date.setter + def default_date(self: T, date: FileTime) -> None: + self._default_date = date + def set_project_id(self: T, id: str) -> None: self._project_id = id From 100ca8674ed19f1d4952eb0cc1865c60398135b1 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 12:43:59 -0500 Subject: [PATCH 121/335] Update vbaProject.py --- src/vbaproject_compiler/vbaProject.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vbaproject_compiler/vbaProject.py b/src/vbaproject_compiler/vbaProject.py index 27b15e9e8..32c0d4c4d 100644 --- a/src/vbaproject_compiler/vbaProject.py +++ b/src/vbaproject_compiler/vbaProject.py @@ -36,11 +36,11 @@ def __init__(self: T) -> None: # Getters and Setters @property - def default_date(self: T) -> FileTime: + def default_date(self: T) -> Filetime: return self._default_date @default_date.setter - def default_date(self: T, date: FileTime) -> None: + def default_date(self: T, date: Filetime) -> None: self._default_date = date def set_project_id(self: T, id: str) -> None: From b0686950d088313ee5fd4955713661a243645579 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 12:46:15 -0500 Subject: [PATCH 122/335] Update vbaProject.py --- src/vbaproject_compiler/vbaProject.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vbaproject_compiler/vbaProject.py b/src/vbaproject_compiler/vbaProject.py index 32c0d4c4d..0f1b76211 100644 --- a/src/vbaproject_compiler/vbaProject.py +++ b/src/vbaproject_compiler/vbaProject.py @@ -42,7 +42,7 @@ def default_date(self: T) -> Filetime: @default_date.setter def default_date(self: T, date: Filetime) -> None: self._default_date = date - + def set_project_id(self: T, id: str) -> None: self._project_id = id From f1b49d7838ad2f5c10f2577a5c351b21e210bb98 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 12:53:19 -0500 Subject: [PATCH 123/335] Update vbaProject.py --- src/vbaproject_compiler/vbaProject.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vbaproject_compiler/vbaProject.py b/src/vbaproject_compiler/vbaProject.py index 0f1b76211..5d1322b75 100644 --- a/src/vbaproject_compiler/vbaProject.py +++ b/src/vbaproject_compiler/vbaProject.py @@ -32,7 +32,7 @@ def __init__(self: T) -> None: self._project_cookie = 0xFFFF self._project_wm = False - + self._default_date = Filetime.from_msfiletime(0x0000000000000000) # Getters and Setters @property From df92994615a7cda68a0a77b1aac2a775db0bb50a Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 12:54:34 -0500 Subject: [PATCH 124/335] Update project_ole_file.py --- src/vbaproject_compiler/Views/project_ole_file.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vbaproject_compiler/Views/project_ole_file.py b/src/vbaproject_compiler/Views/project_ole_file.py index 4cfc3493c..a8f65334b 100644 --- a/src/vbaproject_compiler/Views/project_ole_file.py +++ b/src/vbaproject_compiler/Views/project_ole_file.py @@ -29,6 +29,7 @@ def _build_ole_directory(self: T) -> RootDirectory: Organize the modules and views into the correct storage directories """ directory = RootDirectory() + directory.set_modified(self.project.default_date) storage = StorageDirectory("VBA") for module in self._project.get_modules(): module.write_file() From abd395c10370f0cc5967c48784df36d15a46cf03 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 12:55:38 -0500 Subject: [PATCH 125/335] Update project_ole_file.py --- src/vbaproject_compiler/Views/project_ole_file.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vbaproject_compiler/Views/project_ole_file.py b/src/vbaproject_compiler/Views/project_ole_file.py index a8f65334b..1c8fdcc31 100644 --- a/src/vbaproject_compiler/Views/project_ole_file.py +++ b/src/vbaproject_compiler/Views/project_ole_file.py @@ -29,7 +29,7 @@ def _build_ole_directory(self: T) -> RootDirectory: Organize the modules and views into the correct storage directories """ directory = RootDirectory() - directory.set_modified(self.project.default_date) + directory.set_modified(self._project.default_date) storage = StorageDirectory("VBA") for module in self._project.get_modules(): module.write_file() From 141a3a4738f0a25c267c8f7d12c8f26bfcc214cb Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 12:57:27 -0500 Subject: [PATCH 126/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 7c0f639fc..74d8f7603 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -4,7 +4,7 @@ import unittest.mock import uuid from ms_cfb.ole_file import OleFile -# from ms_dtyp.filetime import Filetime +from ms_dtyp.filetime import Filetime from ms_ovba_compression.ms_ovba import MsOvba from ms_pcode_assembler.module_cache import ModuleCache from vbaproject_compiler.vbaProject import VbaProject @@ -76,6 +76,7 @@ def test_full_file() -> None: rand = [0x41, 0xBC, 0x7B, 0x7B, 0x37, 0x7B, 0x7B, 0x7B] NotSoRandom.set_seed(rand) project = VbaProject() + project.default_date(Filetime.from_msfiletime(0x01D92433C2B823C0)) project.set_include_projectwm(True) codepage = 0x04E4 codepage_name = "cp" + str(codepage) @@ -132,10 +133,7 @@ def test_full_file() -> None: project.add_module(sheet1) project.add_module(this_workbook) - # time = Filetime.from_msfiletime(0x01D92433C2B823C0) - ole_file = ProjectOleFile(project) - # ole_file.root_directory.set_modified(time) ole_file.write_file() # storage.set_modified(time) From 529f4fc78ce9e2d69cb844edae1ccf134323ead1 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 12:59:39 -0500 Subject: [PATCH 127/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 74d8f7603..812dc07e7 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -76,7 +76,7 @@ def test_full_file() -> None: rand = [0x41, 0xBC, 0x7B, 0x7B, 0x37, 0x7B, 0x7B, 0x7B] NotSoRandom.set_seed(rand) project = VbaProject() - project.default_date(Filetime.from_msfiletime(0x01D92433C2B823C0)) + project.default_date = Filetime.from_msfiletime(0x01D92433C2B823C0) project.set_include_projectwm(True) codepage = 0x04E4 codepage_name = "cp" + str(codepage) From fdec471a98a25ee9a8248744b19483cc0b4e6ad4 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 13:01:59 -0500 Subject: [PATCH 128/335] Update project_ole_file.py --- src/vbaproject_compiler/Views/project_ole_file.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vbaproject_compiler/Views/project_ole_file.py b/src/vbaproject_compiler/Views/project_ole_file.py index 1c8fdcc31..c8db6f287 100644 --- a/src/vbaproject_compiler/Views/project_ole_file.py +++ b/src/vbaproject_compiler/Views/project_ole_file.py @@ -31,6 +31,8 @@ def _build_ole_directory(self: T) -> RootDirectory: directory = RootDirectory() directory.set_modified(self._project.default_date) storage = StorageDirectory("VBA") + storage.set_created(self._project.default_date) + storage.set_modified(self._project.default_date) for module in self._project.get_modules(): module.write_file() dir = StreamDirectory(module.get_name(), module.get_bin_path()) From f2c09187e9c22a451bb5301ba597016b16952b6c Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 13 Nov 2024 13:06:43 -0500 Subject: [PATCH 129/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 812dc07e7..b826c4a80 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -167,7 +167,7 @@ def test_full_file() -> None: std_str += "\n" + str(dir) for dir in new_flat: new_str += "\n" + str(dir) - assert std_str == new_str + assert new_str == std_str # assert new.read(512) == expected.read(512) new.read(512) From 19da506edfc656bbe993e28cb8328a725971574c Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 15 Nov 2024 15:27:01 -0500 Subject: [PATCH 130/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index b826c4a80..764b7f299 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -262,18 +262,22 @@ def create_doc_module(project: VbaProject, name: str, cache_ver = project.get_performance_cache_version() proj_cookie = project.get_project_cookie() - module_cache = ModuleCache(cache_ver, proj_cookie) - module_cache.misc = [[0x0316, 0x0100, 0x88, 8], - [-1, 0x18], 0xFFFF, 0, [1, "00000000"]] + module_cache = ModuleCache(cache_ver, proj_cookie, signature=3) + cache.header.data3 = 0x88 + cache.header.data4 = 8 + module_cache.misc = [[-1, 0x18], 0xFFFF, 0, [1, "00000000"]] indirect_table = ("02 80 FE FF FF FF FF FF 20 00 00 00 FF FF FF FF", "30 00 00 00 02 01 FF FF 00 00 00 00 00 00 00 00", "FF FF FF FF FF FF FF FF 00 00 00 00 2E 00 43 00", "1D 00 00 00 25 00 00 00 FF FF FF FF 40 00 00 00") module_cache.indirect_table = bytes.fromhex(" ".join(indirect_table)) - object_table = ("02 00 53 4C FF FF FF FF 00 00 01 00 53 10 FF FF", - "FF FF 00 00 01 00 53 94 FF FF FF FF 00 00 00 00", - "02 3C FF FF FF FF 00 00") - module_cache.object_table = bytes.fromhex(" ".join(object_table)) + + object_table = [[2, 0x4C53], [1, 0x1053], [1, 0x9453], [0, 0x3C02]] + object_table_bytes = b'' + for entry in object_table: + object_table_bytes += struct.pack(" Date: Fri, 15 Nov 2024 17:08:01 -0500 Subject: [PATCH 131/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 764b7f299..929e9b792 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -263,8 +263,8 @@ def create_doc_module(project: VbaProject, name: str, cache_ver = project.get_performance_cache_version() proj_cookie = project.get_project_cookie() module_cache = ModuleCache(cache_ver, proj_cookie, signature=3) - cache.header.data3 = 0x88 - cache.header.data4 = 8 + module_cache.header.data3 = 0x88 + module_cache.header.data4 = 8 module_cache.misc = [[-1, 0x18], 0xFFFF, 0, [1, "00000000"]] indirect_table = ("02 80 FE FF FF FF FF FF 20 00 00 00 FF FF FF FF", "30 00 00 00 02 01 FF FF 00 00 00 00 00 00 00 00", From 9bdcfb9e14e8f3a0cf292f24bfb0530329bac8c6 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 15 Nov 2024 17:11:32 -0500 Subject: [PATCH 132/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 929e9b792..0ef047830 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -265,7 +265,7 @@ def create_doc_module(project: VbaProject, name: str, module_cache = ModuleCache(cache_ver, proj_cookie, signature=3) module_cache.header.data3 = 0x88 module_cache.header.data4 = 8 - module_cache.misc = [[-1, 0x18], 0xFFFF, 0, [1, "00000000"]] + module_cache.misc = [[-1, 0x18], 0x18, 0, [1, "00000000"]] indirect_table = ("02 80 FE FF FF FF FF FF 20 00 00 00 FF FF FF FF", "30 00 00 00 02 01 FF FF 00 00 00 00 00 00 00 00", "FF FF FF FF FF FF FF FF 00 00 00 00 2E 00 43 00", From 7392cbf47b91f44cabca0e44366972ea094476d7 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 15 Nov 2024 17:15:05 -0500 Subject: [PATCH 133/335] Update test_doc_module.py --- tests/Unit/Models/Entities/test_doc_module.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/Unit/Models/Entities/test_doc_module.py b/tests/Unit/Models/Entities/test_doc_module.py index eb341a397..1a25c01be 100644 --- a/tests/Unit/Models/Entities/test_doc_module.py +++ b/tests/Unit/Models/Entities/test_doc_module.py @@ -6,10 +6,11 @@ def test_normalize() -> None: - cache = ModuleCache(0xB5, 0x08F3) + cache = ModuleCache(0xB5, 0x08F3, signature=3) cache.module_cookie = 0xB81C - cache.misc = [[0x0316, 0, 0x0123, 0x88], - [-1, 8], 24, 0, [1, "00000000"]] + cache.header.data3 = 0x0123 + cache.header.data4 = 0x88 + cache.misc = [[-1, 8], 24, 0, [1, "00000000"]] guid = uuid.UUID('0002081900000000C000000000000046') cache.guid = [guid] From 2c99ead2d188edb800746ed938f759c369d7cdae Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 15 Nov 2024 22:52:45 -0500 Subject: [PATCH 134/335] Update test_dirObject.py --- tests/Functional/test_dirObject.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/Functional/test_dirObject.py b/tests/Functional/test_dirObject.py index 05c520b76..268337679 100644 --- a/tests/Functional/test_dirObject.py +++ b/tests/Functional/test_dirObject.py @@ -16,7 +16,7 @@ def test_dirstream() -> None: ''' The cache is not yet tested. ''' - module_cache = ModuleCache(0xB5, 0x08F3) + module_cache = ModuleCache(0xB5, 0x08F3, signature=3) # Read the data from the demo file and decompress it. f = open('tests/blank/vbaProject.bin', 'rb') offset = 0x1EC0 @@ -63,9 +63,10 @@ def test_dirstream() -> None: "FF FF 00 00 01 00 53 94 FF FF FF FF 00 00 00 00", "02 3C FF FF FF FF 00 00") module_cache.object_table = bytes.fromhex(" ".join(object_table)) - module_cache.misc = [[0x0316, 0x0123, 0x88, 8], - [-1, 0x18], 0xFF, 0, [1, "00000000"]] - + module_cache.misc = [[-1, 0x18], 0xFF, 0, [1, "00000000"]] + module_cache.header.data2 = 0x0123 + module_cache.header.data3 = 0x88 + module_cache.header.sata4 = 8 this_workbook = DocModule("ThisWorkbook") this_workbook.set_cookie(0xB81C) module_cache.cookie = 0xB81C @@ -86,8 +87,10 @@ def test_dirstream() -> None: module1.set_cookie(0xB241) module_cache.clear_variables() module_cache.cookie = 0xB241 - module_cache.misc = [[0x0316, 3, 0, 7], - [-1, 2], 0xFFFF, 0, [0, "FFFFFFFF"]] + module_cache.misc = [[-1, 2], 0xFFFF, 0, [0, "FFFFFFFF"]] + module_cache.header.data2 = 3 + module_cache.header.data3 = 0 + module_cache.header.sata4 = 7 module_cache.indirect_table = struct.pack(" Date: Sat, 16 Nov 2024 13:20:44 -0500 Subject: [PATCH 135/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 0ef047830..558200446 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -190,7 +190,6 @@ def create_cache() -> bytes: modules.append(module1) libraries = [] - delim = [] libraries.append(LibidReference( uuid.UUID("000204EF-0000-0000-C000-000000000046"), "4.2", @@ -199,7 +198,6 @@ def create_cache() -> bytes: "\\VBA7.1\\VBE7.DLL", "Visual Basic For Applications" )) - delim.append(0x011A) libraries.append(LibidReference( uuid.UUID("00020813-0000-0000-C000-000000000046"), "1.9", @@ -207,7 +205,6 @@ def create_cache() -> bytes: "C:\\Program Files\\Microsoft Office\\root\\Office16\\EXCEL.EXE", "Microsoft Excel 16.0 Object Library" )) - delim.append(0x00BC) libraries.append(LibidReference( uuid.UUID("00020430-0000-0000-C000-000000000046"), "2.0", @@ -215,7 +212,6 @@ def create_cache() -> bytes: "C:\\Windows\\System32\\stdole2.tlb", "OLE Automation" )) - delim.append(0x0128) libraries.append(LibidReference( uuid.UUID("2DF8D04C-5BFA-101B-BDE5-00AA0044DE52"), "2.8", @@ -223,14 +219,15 @@ def create_cache() -> bytes: "C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE16\\MSO.DLL", "Microsoft Office 16.0 Object Library" )) - delim.append(0x0003) ca = (b'' + b'\xFF\x09\x04\x00\x00\x09\x04\x00\x00\xE4\x04\x03\x00\x00\x00\x00' - + b'\x00\x00\x00\x00\x00\x01\x00\x04\x00\x02\x00\x20\x01') + + b'\x00\x00\x00\x00\x00\x01\x00\x04\x00\x02\x00') i = 0 for lib in libraries: - ca += bytearray(str(lib), "utf_16_le") - ca += struct.pack(" Date: Sat, 16 Nov 2024 13:40:31 -0500 Subject: [PATCH 136/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 558200446..3af80dfb4 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -226,7 +226,7 @@ def create_cache() -> bytes: for lib in libraries: lib_str = bytearray(str(lib), "utf_16_le") ca += struct.pack(" Date: Sat, 16 Nov 2024 13:43:18 -0500 Subject: [PATCH 137/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 3af80dfb4..21b1b7b68 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -227,7 +227,7 @@ def create_cache() -> bytes: lib_str = bytearray(str(lib), "utf_16_le") ca += struct.pack(" Date: Sat, 16 Nov 2024 13:47:57 -0500 Subject: [PATCH 138/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 21b1b7b68..01cbe3281 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -117,10 +117,10 @@ def test_full_file() -> None: module1 = StdModule("Module1") cookie = 0xB241 module1.set_cookie(cookie) - module_cache = ModuleCache(0xB5, proj_cookie) - module_cache.clear_variables() - module_cache.misc = [[0x0316, 3, 0, 2], - [-1, 0], 0xFFFF, 0, [0, "FFFFFFFF"]] + module_cache = ModuleCache(0xB5, proj_cookie, signature=3) + module_cache.header.data2 = 3 + module_cache.header.data4 = 2 + module_cache.misc = [[-1, 0], 0xFFFF, 0, [0, "FFFFFFFF"]] module_cache.indirect_table = struct.pack(" Date: Sun, 24 Nov 2024 15:09:30 -0500 Subject: [PATCH 139/335] changed dir name --- .../Models/Entities/doc_module.py | 0 .../Models/Entities/module_base.py | 0 .../Models/Entities/reference_record.py | 0 .../Models/Entities/std_module.py | 0 .../Models/Fields/doubleEncodedString.py | 0 src/{vbaproject_compiler => ms_ovba}/Models/Fields/idSizeField.py | 0 .../Models/Fields/libid_reference.py | 0 src/{vbaproject_compiler => ms_ovba}/Models/Fields/packed_data.py | 0 src/{vbaproject_compiler => ms_ovba}/Views/dirStream.py | 0 src/{vbaproject_compiler => ms_ovba}/Views/project.py | 0 src/{vbaproject_compiler => ms_ovba}/Views/projectWm.py | 0 src/{vbaproject_compiler => ms_ovba}/Views/project_ole_file.py | 0 src/{vbaproject_compiler => ms_ovba}/Views/project_view.py | 0 src/{vbaproject_compiler => ms_ovba}/__init__.py | 0 src/{vbaproject_compiler => ms_ovba}/__main__.py | 0 src/{vbaproject_compiler => ms_ovba}/blank_files/Sheet1.cls | 0 src/{vbaproject_compiler => ms_ovba}/blank_files/ThisWorkbook.cls | 0 src/{vbaproject_compiler => ms_ovba}/vbaProject.py | 0 18 files changed, 0 insertions(+), 0 deletions(-) rename src/{vbaproject_compiler => ms_ovba}/Models/Entities/doc_module.py (100%) rename src/{vbaproject_compiler => ms_ovba}/Models/Entities/module_base.py (100%) rename src/{vbaproject_compiler => ms_ovba}/Models/Entities/reference_record.py (100%) rename src/{vbaproject_compiler => ms_ovba}/Models/Entities/std_module.py (100%) rename src/{vbaproject_compiler => ms_ovba}/Models/Fields/doubleEncodedString.py (100%) rename src/{vbaproject_compiler => ms_ovba}/Models/Fields/idSizeField.py (100%) rename src/{vbaproject_compiler => ms_ovba}/Models/Fields/libid_reference.py (100%) rename src/{vbaproject_compiler => ms_ovba}/Models/Fields/packed_data.py (100%) rename src/{vbaproject_compiler => ms_ovba}/Views/dirStream.py (100%) rename src/{vbaproject_compiler => ms_ovba}/Views/project.py (100%) rename src/{vbaproject_compiler => ms_ovba}/Views/projectWm.py (100%) rename src/{vbaproject_compiler => ms_ovba}/Views/project_ole_file.py (100%) rename src/{vbaproject_compiler => ms_ovba}/Views/project_view.py (100%) rename src/{vbaproject_compiler => ms_ovba}/__init__.py (100%) rename src/{vbaproject_compiler => ms_ovba}/__main__.py (100%) rename src/{vbaproject_compiler => ms_ovba}/blank_files/Sheet1.cls (100%) rename src/{vbaproject_compiler => ms_ovba}/blank_files/ThisWorkbook.cls (100%) rename src/{vbaproject_compiler => ms_ovba}/vbaProject.py (100%) diff --git a/src/vbaproject_compiler/Models/Entities/doc_module.py b/src/ms_ovba/Models/Entities/doc_module.py similarity index 100% rename from src/vbaproject_compiler/Models/Entities/doc_module.py rename to src/ms_ovba/Models/Entities/doc_module.py diff --git a/src/vbaproject_compiler/Models/Entities/module_base.py b/src/ms_ovba/Models/Entities/module_base.py similarity index 100% rename from src/vbaproject_compiler/Models/Entities/module_base.py rename to src/ms_ovba/Models/Entities/module_base.py diff --git a/src/vbaproject_compiler/Models/Entities/reference_record.py b/src/ms_ovba/Models/Entities/reference_record.py similarity index 100% rename from src/vbaproject_compiler/Models/Entities/reference_record.py rename to src/ms_ovba/Models/Entities/reference_record.py diff --git a/src/vbaproject_compiler/Models/Entities/std_module.py b/src/ms_ovba/Models/Entities/std_module.py similarity index 100% rename from src/vbaproject_compiler/Models/Entities/std_module.py rename to src/ms_ovba/Models/Entities/std_module.py diff --git a/src/vbaproject_compiler/Models/Fields/doubleEncodedString.py b/src/ms_ovba/Models/Fields/doubleEncodedString.py similarity index 100% rename from src/vbaproject_compiler/Models/Fields/doubleEncodedString.py rename to src/ms_ovba/Models/Fields/doubleEncodedString.py diff --git a/src/vbaproject_compiler/Models/Fields/idSizeField.py b/src/ms_ovba/Models/Fields/idSizeField.py similarity index 100% rename from src/vbaproject_compiler/Models/Fields/idSizeField.py rename to src/ms_ovba/Models/Fields/idSizeField.py diff --git a/src/vbaproject_compiler/Models/Fields/libid_reference.py b/src/ms_ovba/Models/Fields/libid_reference.py similarity index 100% rename from src/vbaproject_compiler/Models/Fields/libid_reference.py rename to src/ms_ovba/Models/Fields/libid_reference.py diff --git a/src/vbaproject_compiler/Models/Fields/packed_data.py b/src/ms_ovba/Models/Fields/packed_data.py similarity index 100% rename from src/vbaproject_compiler/Models/Fields/packed_data.py rename to src/ms_ovba/Models/Fields/packed_data.py diff --git a/src/vbaproject_compiler/Views/dirStream.py b/src/ms_ovba/Views/dirStream.py similarity index 100% rename from src/vbaproject_compiler/Views/dirStream.py rename to src/ms_ovba/Views/dirStream.py diff --git a/src/vbaproject_compiler/Views/project.py b/src/ms_ovba/Views/project.py similarity index 100% rename from src/vbaproject_compiler/Views/project.py rename to src/ms_ovba/Views/project.py diff --git a/src/vbaproject_compiler/Views/projectWm.py b/src/ms_ovba/Views/projectWm.py similarity index 100% rename from src/vbaproject_compiler/Views/projectWm.py rename to src/ms_ovba/Views/projectWm.py diff --git a/src/vbaproject_compiler/Views/project_ole_file.py b/src/ms_ovba/Views/project_ole_file.py similarity index 100% rename from src/vbaproject_compiler/Views/project_ole_file.py rename to src/ms_ovba/Views/project_ole_file.py diff --git a/src/vbaproject_compiler/Views/project_view.py b/src/ms_ovba/Views/project_view.py similarity index 100% rename from src/vbaproject_compiler/Views/project_view.py rename to src/ms_ovba/Views/project_view.py diff --git a/src/vbaproject_compiler/__init__.py b/src/ms_ovba/__init__.py similarity index 100% rename from src/vbaproject_compiler/__init__.py rename to src/ms_ovba/__init__.py diff --git a/src/vbaproject_compiler/__main__.py b/src/ms_ovba/__main__.py similarity index 100% rename from src/vbaproject_compiler/__main__.py rename to src/ms_ovba/__main__.py diff --git a/src/vbaproject_compiler/blank_files/Sheet1.cls b/src/ms_ovba/blank_files/Sheet1.cls similarity index 100% rename from src/vbaproject_compiler/blank_files/Sheet1.cls rename to src/ms_ovba/blank_files/Sheet1.cls diff --git a/src/vbaproject_compiler/blank_files/ThisWorkbook.cls b/src/ms_ovba/blank_files/ThisWorkbook.cls similarity index 100% rename from src/vbaproject_compiler/blank_files/ThisWorkbook.cls rename to src/ms_ovba/blank_files/ThisWorkbook.cls diff --git a/src/vbaproject_compiler/vbaProject.py b/src/ms_ovba/vbaProject.py similarity index 100% rename from src/vbaproject_compiler/vbaProject.py rename to src/ms_ovba/vbaProject.py From 988983953e7a6f675ad95b52f49dea71400f7644 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 31 Dec 2025 09:54:40 -0500 Subject: [PATCH 140/335] Fix typo in README about CLI functionality --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ec24e023a..134b74e7f 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Create a vbaProject.bin file from VBA source files. ## Command Line Interface -Eventually it will ne possible to use the CLI to creatr a vbaProject.bin file from source files and an optional configuration file. +Eventually it will ne possible to use the CLI to create a vbaProject.bin file from source files and an optional configuration file. ## VBAProject Class The vbaProject class contains all the data and metadata that is used to create the OLE container. From cae4d1c0ff822920423daa64dc48cbf24e94c930 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 31 Dec 2025 09:54:55 -0500 Subject: [PATCH 141/335] Fix typo in README regarding CLI functionality --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 134b74e7f..d7278cbde 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Create a vbaProject.bin file from VBA source files. ## Command Line Interface -Eventually it will ne possible to use the CLI to create a vbaProject.bin file from source files and an optional configuration file. +Eventually it will be possible to use the CLI to create a vbaProject.bin file from source files and an optional configuration file. ## VBAProject Class The vbaProject class contains all the data and metadata that is used to create the OLE container. From 3596ac64306976de8590da8be3ad6461987bb8c9 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 31 Dec 2025 09:58:30 -0500 Subject: [PATCH 142/335] Update test_vba_project.py --- tests/Views/test_vba_project.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Views/test_vba_project.py b/tests/Views/test_vba_project.py index 80506973a..3893a79c3 100644 --- a/tests/Views/test_vba_project.py +++ b/tests/Views/test_vba_project.py @@ -1,5 +1,5 @@ -from vbaproject_compiler.vbaProject import VbaProject -from vbaproject_compiler.Views.project_view import ProjectView +from ms_ovba.vbaProject import VbaProject +from ms_ovba.Views.project_view import ProjectView def test_vba_project() -> None: From 010242fc771a9f93fa9d07ffd5856976e992f0ee Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 31 Dec 2025 10:02:07 -0500 Subject: [PATCH 143/335] Refactor import statements in module_base.py --- src/ms_ovba/Models/Entities/module_base.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ms_ovba/Models/Entities/module_base.py b/src/ms_ovba/Models/Entities/module_base.py index 9ef0a8ac3..4d2f0b399 100644 --- a/src/ms_ovba/Models/Entities/module_base.py +++ b/src/ms_ovba/Models/Entities/module_base.py @@ -1,9 +1,9 @@ from ms_ovba_compression.ms_ovba import MsOvba -from vbaproject_compiler.Models.Fields.doubleEncodedString import ( +from ms_ovba.Models.Fields.doubleEncodedString import ( DoubleEncodedString ) -from vbaproject_compiler.Models.Fields.packed_data import PackedData -from vbaproject_compiler.Models.Fields.idSizeField import IdSizeField +from ms_ovba.Models.Fields.packed_data import PackedData +from ms_ovba.Models.Fields.idSizeField import IdSizeField from typing import TypeVar From a3d6b5a91488fafccb055ee447111b00d1dde473 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 31 Dec 2025 10:04:47 -0500 Subject: [PATCH 144/335] Update import paths for module_base and reference_record --- src/ms_ovba/vbaProject.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ms_ovba/vbaProject.py b/src/ms_ovba/vbaProject.py index 5d1322b75..95ea0ee19 100644 --- a/src/ms_ovba/vbaProject.py +++ b/src/ms_ovba/vbaProject.py @@ -1,5 +1,5 @@ -from vbaproject_compiler.Models.Entities.module_base import ModuleBase -from vbaproject_compiler.Models.Entities.reference_record import ( +from ms_ovba.Models.Entities.module_base import ModuleBase +from ms_ovba.Models.Entities.reference_record import ( ReferenceRecord ) from ms_dtyp.filetime import Filetime From c4e3645e004e2dd87b6be1c242308d055c1aa5da Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 31 Dec 2025 10:05:17 -0500 Subject: [PATCH 145/335] Refactor imports to use ms_ovba module --- src/ms_ovba/__main__.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ms_ovba/__main__.py b/src/ms_ovba/__main__.py index 487b71f79..0f98616e4 100644 --- a/src/ms_ovba/__main__.py +++ b/src/ms_ovba/__main__.py @@ -2,14 +2,14 @@ import glob import os import uuid -from vbaproject_compiler.vbaProject import VbaProject -from vbaproject_compiler.Models.Entities.doc_module import DocModule -from vbaproject_compiler.Models.Entities.std_module import StdModule -from vbaproject_compiler.Views.project_ole_file import ProjectOleFile -from vbaproject_compiler.Models.Entities.reference_record import ( +from ms_ovba.vbaProject import VbaProject +from ms_ovba.Models.Entities.doc_module import DocModule +from ms_ovba.Models.Entities.std_module import StdModule +from ms_ovba.Views.project_ole_file import ProjectOleFile +from ms_ovba.Models.Entities.reference_record import ( ReferenceRecord ) -from vbaproject_compiler.Models.Fields.libid_reference import LibidReference +from ms_ovba.Models.Fields.libid_reference import LibidReference def main() -> None: From e9511e90d74848b05b6e245759900f767971df50 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 31 Dec 2025 10:05:42 -0500 Subject: [PATCH 146/335] Fix import path for ModuleBase in doc_module.py --- src/ms_ovba/Models/Entities/doc_module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Entities/doc_module.py b/src/ms_ovba/Models/Entities/doc_module.py index cbb3e3111..29f90073a 100644 --- a/src/ms_ovba/Models/Entities/doc_module.py +++ b/src/ms_ovba/Models/Entities/doc_module.py @@ -1,5 +1,5 @@ from ms_ovba_compression.ms_ovba import MsOvba -from vbaproject_compiler.Models.Entities.module_base import ModuleBase +from ms_ovba.Models.Entities.module_base import ModuleBase from typing import TypeVar From 5f20515642e8481632a2e0ed8b0b5ef3c7053cd9 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 31 Dec 2025 10:06:10 -0500 Subject: [PATCH 147/335] Update import paths for reference_record.py --- src/ms_ovba/Models/Entities/reference_record.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference_record.py b/src/ms_ovba/Models/Entities/reference_record.py index 76fba03b4..0e8dc578f 100644 --- a/src/ms_ovba/Models/Entities/reference_record.py +++ b/src/ms_ovba/Models/Entities/reference_record.py @@ -1,8 +1,8 @@ -from vbaproject_compiler.Models.Fields.doubleEncodedString import ( +from ms_ovba.Models.Fields.doubleEncodedString import ( DoubleEncodedString ) -from vbaproject_compiler.Models.Fields.libid_reference import LibidReference -from vbaproject_compiler.Models.Fields.packed_data import PackedData +from ms_ovba.Models.Fields.libid_reference import LibidReference +from ms_ovba.Models.Fields.packed_data import PackedData from typing import TypeVar From ad24b35725b13b57e948fea5beb0130996064dc8 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 31 Dec 2025 10:06:28 -0500 Subject: [PATCH 148/335] Fix import path for IdSizeField in doubleEncodedString.py --- src/ms_ovba/Models/Fields/doubleEncodedString.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Fields/doubleEncodedString.py b/src/ms_ovba/Models/Fields/doubleEncodedString.py index 04da1e9fe..41aee34ca 100644 --- a/src/ms_ovba/Models/Fields/doubleEncodedString.py +++ b/src/ms_ovba/Models/Fields/doubleEncodedString.py @@ -1,4 +1,4 @@ -from vbaproject_compiler.Models.Fields.idSizeField import IdSizeField +from ms_ovba.Models.Fields.idSizeField import IdSizeField from typing import TypeVar From 84f6f542d5f51cf475b444213b0eca545ef7a55c Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 31 Dec 2025 10:06:50 -0500 Subject: [PATCH 149/335] Update import path for ModuleBase --- src/ms_ovba/Models/Entities/std_module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Entities/std_module.py b/src/ms_ovba/Models/Entities/std_module.py index b517e8fdf..3763cedd5 100644 --- a/src/ms_ovba/Models/Entities/std_module.py +++ b/src/ms_ovba/Models/Entities/std_module.py @@ -1,4 +1,4 @@ -from vbaproject_compiler.Models.Entities.module_base import ModuleBase +from ms_ovba.Models.Entities.module_base import ModuleBase from typing import TypeVar From d00dbfdc4894ebe7b24d59d1fe70e922fc000425 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 31 Dec 2025 10:07:11 -0500 Subject: [PATCH 150/335] Update dirStream.py --- src/ms_ovba/Views/dirStream.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ms_ovba/Views/dirStream.py b/src/ms_ovba/Views/dirStream.py index 9ceec0eca..657105d18 100644 --- a/src/ms_ovba/Views/dirStream.py +++ b/src/ms_ovba/Views/dirStream.py @@ -1,11 +1,11 @@ import struct from ms_ovba_compression.ms_ovba import MsOvba -from vbaproject_compiler.vbaProject import VbaProject -from vbaproject_compiler.Models.Fields.idSizeField import IdSizeField -from vbaproject_compiler.Models.Fields.doubleEncodedString import ( +from ms_ovba.vbaProject import VbaProject +from ms_ovba.Models.Fields.idSizeField import IdSizeField +from ms_ovba.Models.Fields.doubleEncodedString import ( DoubleEncodedString ) -from vbaproject_compiler.Models.Fields.packed_data import PackedData +from ms_ovba.Models.Fields.packed_data import PackedData from typing import TypeVar From 5aabbb324c13c56c73ad6edbad485e233b616a4b Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 31 Dec 2025 10:07:24 -0500 Subject: [PATCH 151/335] Update project.py --- src/ms_ovba/Views/project.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ms_ovba/Views/project.py b/src/ms_ovba/Views/project.py index 1f64e7a90..5f6eff9de 100644 --- a/src/ms_ovba/Views/project.py +++ b/src/ms_ovba/Views/project.py @@ -1,6 +1,6 @@ import binascii import ms_ovba_crypto -from vbaproject_compiler.vbaProject import VbaProject +from ms_ovba.vbaProject import VbaProject from typing import TypeVar From 6e616e9b391a6a94fed87997d1d9cbf143f0f6f4 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 31 Dec 2025 10:07:37 -0500 Subject: [PATCH 152/335] Update projectWm.py --- src/ms_ovba/Views/projectWm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ms_ovba/Views/projectWm.py b/src/ms_ovba/Views/projectWm.py index fc651cf4e..cc3f86217 100644 --- a/src/ms_ovba/Views/projectWm.py +++ b/src/ms_ovba/Views/projectWm.py @@ -1,4 +1,4 @@ -from vbaproject_compiler.vbaProject import VbaProject +from ms_ovba.vbaProject import VbaProject from typing import TypeVar From 3e0fab7f8327b5033f5a921418c55e398c2cdfaf Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 31 Dec 2025 10:08:06 -0500 Subject: [PATCH 153/335] Refactor import statements for vbaProject module --- src/ms_ovba/Views/project_ole_file.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ms_ovba/Views/project_ole_file.py b/src/ms_ovba/Views/project_ole_file.py index c8db6f287..f7ac048f7 100644 --- a/src/ms_ovba/Views/project_ole_file.py +++ b/src/ms_ovba/Views/project_ole_file.py @@ -2,11 +2,11 @@ from ms_cfb.Models.Directories.root_directory import RootDirectory from ms_cfb.Models.Directories.storage_directory import StorageDirectory from ms_cfb.Models.Directories.stream_directory import StreamDirectory -from vbaproject_compiler.vbaProject import VbaProject -from vbaproject_compiler.Views.dirStream import DirStream -from vbaproject_compiler.Views.project_view import ProjectView -from vbaproject_compiler.Views.project import Project -from vbaproject_compiler.Views.projectWm import ProjectWm +from ms_ovba.vbaProject import VbaProject +from ms_ovba.Views.dirStream import DirStream +from ms_ovba.Views.project_view import ProjectView +from ms_ovba.Views.project import Project +from ms_ovba.Views.projectWm import ProjectWm from typing import TypeVar From 4a2fd6fd1cf46b2250caef36c517dee71bb60c4a Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 31 Dec 2025 10:08:19 -0500 Subject: [PATCH 154/335] Update import path for VbaProject --- src/ms_ovba/Views/project_view.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ms_ovba/Views/project_view.py b/src/ms_ovba/Views/project_view.py index cbb39b9b0..865d0d596 100644 --- a/src/ms_ovba/Views/project_view.py +++ b/src/ms_ovba/Views/project_view.py @@ -1,5 +1,5 @@ import struct -from vbaproject_compiler.vbaProject import VbaProject +from ms_ovba.vbaProject import VbaProject from typing import TypeVar From 60ee68248535ce766f46074d9d2e63bd706e6507 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 31 Dec 2025 10:09:42 -0500 Subject: [PATCH 155/335] Refactor imports to use ms_ovba module --- tests/Functional/test_dirObject.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/Functional/test_dirObject.py b/tests/Functional/test_dirObject.py index 268337679..535004ea8 100644 --- a/tests/Functional/test_dirObject.py +++ b/tests/Functional/test_dirObject.py @@ -2,12 +2,12 @@ import uuid from ms_ovba_compression.ms_ovba import MsOvba from ms_pcode_assembler.module_cache import ModuleCache -from vbaproject_compiler.vbaProject import VbaProject -from vbaproject_compiler.Views.dirStream import DirStream -from vbaproject_compiler.Models.Fields.libid_reference import LibidReference -from vbaproject_compiler.Models.Entities.doc_module import DocModule -from vbaproject_compiler.Models.Entities.std_module import StdModule -from vbaproject_compiler.Models.Entities.reference_record import ( +from ms_ovba.vbaProject import VbaProject +from ms_ovba.Views.dirStream import DirStream +from ms_ovba.Models.Fields.libid_reference import LibidReference +from ms_ovba.Models.Entities.doc_module import DocModule +from ms_ovba.Models.Entities.std_module import StdModule +from ms_ovba.Models.Entities.reference_record import ( ReferenceRecord ) From 39a5592889a2743dcc72a82b0eec3bf0aff00dbb Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 31 Dec 2025 10:10:02 -0500 Subject: [PATCH 156/335] Refactor import statements for ms_ovba module --- tests/Functional/test_fullFile.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 01cbe3281..6b0653615 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -7,14 +7,14 @@ from ms_dtyp.filetime import Filetime from ms_ovba_compression.ms_ovba import MsOvba from ms_pcode_assembler.module_cache import ModuleCache -from vbaproject_compiler.vbaProject import VbaProject -from vbaproject_compiler.Models.Entities.doc_module import DocModule -from vbaproject_compiler.Models.Entities.std_module import StdModule -from vbaproject_compiler.Models.Entities.reference_record import ( +from ms_ovba.vbaProject import VbaProject +from ms_ovba.Models.Entities.doc_module import DocModule +from ms_ovba.Models.Entities.std_module import StdModule +from ms_ovba.Models.Entities.reference_record import ( ReferenceRecord ) -from vbaproject_compiler.Models.Fields.libid_reference import LibidReference -from vbaproject_compiler.Views.project_ole_file import ProjectOleFile +from ms_ovba.Models.Fields.libid_reference import LibidReference +from ms_ovba.Views.project_ole_file import ProjectOleFile from typing import Type, TypeVar From 5c1fc73e8bf5a39a259af5c04c1edd94c9d8909d Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 31 Dec 2025 10:10:33 -0500 Subject: [PATCH 157/335] Update test_doc_module.py --- tests/Unit/Models/Entities/test_doc_module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_doc_module.py b/tests/Unit/Models/Entities/test_doc_module.py index 1a25c01be..c3a1dfcc3 100644 --- a/tests/Unit/Models/Entities/test_doc_module.py +++ b/tests/Unit/Models/Entities/test_doc_module.py @@ -1,7 +1,7 @@ import uuid from ms_ovba_compression.ms_ovba import MsOvba from ms_pcode_assembler.module_cache import ModuleCache -from vbaproject_compiler.Models.Entities.doc_module import DocModule +from ms_ovba.Models.Entities.doc_module import DocModule def test_normalize() -> None: From e67f3b2d57e1c46065ffb700c64f2b8a0740283f Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 31 Dec 2025 10:10:47 -0500 Subject: [PATCH 158/335] Update test_std_module.py --- tests/Unit/Models/Entities/test_std_module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_std_module.py b/tests/Unit/Models/Entities/test_std_module.py index 2b7730ef3..2541d4b89 100644 --- a/tests/Unit/Models/Entities/test_std_module.py +++ b/tests/Unit/Models/Entities/test_std_module.py @@ -1,4 +1,4 @@ -from vbaproject_compiler.Models.Entities.std_module import StdModule +from ms_ovba.Models.Entities.std_module import StdModule def test_set_get_cache() -> None: From 6494a1d0239b57832025347cadfbe7d2eee5a15f Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 31 Dec 2025 10:11:02 -0500 Subject: [PATCH 159/335] Update import path for IdSizeField --- tests/Unit/Models/Fields/test_idSizeField.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Fields/test_idSizeField.py b/tests/Unit/Models/Fields/test_idSizeField.py index fe8573c19..033ce3be9 100644 --- a/tests/Unit/Models/Fields/test_idSizeField.py +++ b/tests/Unit/Models/Fields/test_idSizeField.py @@ -1,5 +1,5 @@ import pytest -from vbaproject_compiler.Models.Fields.idSizeField import IdSizeField +from ms_ovba.Models.Fields.idSizeField import IdSizeField def test_bad_value() -> None: From 771147b406187996a5356dfe3e03a128283b88c2 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 31 Dec 2025 10:11:13 -0500 Subject: [PATCH 160/335] Update import path for LibidReference --- tests/Unit/Models/Fields/test_libidReference.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Fields/test_libidReference.py b/tests/Unit/Models/Fields/test_libidReference.py index d6261a350..3b2afddf6 100644 --- a/tests/Unit/Models/Fields/test_libidReference.py +++ b/tests/Unit/Models/Fields/test_libidReference.py @@ -1,5 +1,5 @@ import uuid -from vbaproject_compiler.Models.Fields.libid_reference import LibidReference +from ms_ovba.Models.Fields.libid_reference import LibidReference def test_str() -> None: From 53fe2f9781e9255911a304a8634f001c722d86b2 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 31 Dec 2025 10:11:25 -0500 Subject: [PATCH 161/335] Change import path for VbaProject --- tests/Unit/Models/test_vbaProject.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/test_vbaProject.py b/tests/Unit/Models/test_vbaProject.py index 77de05547..dfe9ae557 100644 --- a/tests/Unit/Models/test_vbaProject.py +++ b/tests/Unit/Models/test_vbaProject.py @@ -1,5 +1,5 @@ import pytest -from vbaproject_compiler.vbaProject import VbaProject +from ms_ovba.vbaProject import VbaProject def test_set_get_visibility() -> None: From eaef4c750efefaadf46fb4e530ca6155648744fa Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 31 Dec 2025 10:11:47 -0500 Subject: [PATCH 162/335] Update import paths for project modules --- tests/Views/test_project.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Views/test_project.py b/tests/Views/test_project.py index 38bf2e18f..df3a42167 100644 --- a/tests/Views/test_project.py +++ b/tests/Views/test_project.py @@ -1,9 +1,9 @@ import unittest.mock -from vbaproject_compiler.vbaProject import VbaProject -from vbaproject_compiler.Models.Entities.doc_module import DocModule -from vbaproject_compiler.Models.Entities.std_module import StdModule -from vbaproject_compiler.Views.project import Project +from ms_ovba.vbaProject import VbaProject +from ms_ovba.Models.Entities.doc_module import DocModule +from ms_ovba.Models.Entities.std_module import StdModule +from ms_ovba.Views.project import Project from typing import Type, TypeVar From 1e019c49b0021711a32eb71c32a98fa7ed118716 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 31 Dec 2025 10:12:03 -0500 Subject: [PATCH 163/335] Update import statements for projectWm test --- tests/Views/test_projectWm.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Views/test_projectWm.py b/tests/Views/test_projectWm.py index d14390a5c..e4f806e6f 100644 --- a/tests/Views/test_projectWm.py +++ b/tests/Views/test_projectWm.py @@ -1,7 +1,7 @@ -from vbaproject_compiler.vbaProject import VbaProject -from vbaproject_compiler.Models.Entities.doc_module import DocModule -from vbaproject_compiler.Models.Entities.std_module import StdModule -from vbaproject_compiler.Views.projectWm import ProjectWm +from ms_ovba.vbaProject import VbaProject +from ms_ovba.Models.Entities.doc_module import DocModule +from ms_ovba.Models.Entities.std_module import StdModule +from ms_ovba.Views.projectWm import ProjectWm def test_project_wm() -> None: From d4a70dbacda001e928b944d9802955c71cef13ff Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 31 Dec 2025 10:14:10 -0500 Subject: [PATCH 164/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index 6b0653615..f38120f52 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -40,7 +40,7 @@ def run_around_tests() -> None: # A test function will be run at this point yield # Code that will run after your test - root = "src/vbaproject_compiler/blank_files/" + root = "src/ms_ovba/blank_files/" root2 = "tests/blank/" names = [root + "ThisWorkbook.cls", root + "Sheet1.cls", root2 + "Module1.bas"] @@ -104,7 +104,7 @@ def test_full_file() -> None: project.set_performance_cache(create_cache()) project.set_performance_cache_version(0x00B5) - base_path = "src/vbaproject_compiler/blank_files/" + base_path = "src/ms_ovba/blank_files/" # Add Modules this_workbook = create_doc_module(project, "ThisWorkbook", 0xB81C, "0002081900000000C000000000000046", From e19f092d56645b4764977f3c0c6fe5c949cd9711 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 31 Dec 2025 10:15:10 -0500 Subject: [PATCH 165/335] Update file path in test_doc_module.py --- tests/Unit/Models/Entities/test_doc_module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_doc_module.py b/tests/Unit/Models/Entities/test_doc_module.py index c3a1dfcc3..f72a3f796 100644 --- a/tests/Unit/Models/Entities/test_doc_module.py +++ b/tests/Unit/Models/Entities/test_doc_module.py @@ -25,7 +25,7 @@ def test_normalize() -> None: cache.object_table = bytes.fromhex(" ".join(object_table)) module = DocModule("foo") - path1 = "src/vbaproject_compiler/blank_files/ThisWorkbook.cls" + path1 = "src/ms_ovba/blank_files/ThisWorkbook.cls" module.add_file(path1) module.cookie.value = 0xB81C guid = uuid.UUID('0002081900000000C000000000000046') From 6eab382418bbeb57ee985d8f36d6997d6162f1c6 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 31 Dec 2025 10:17:28 -0500 Subject: [PATCH 166/335] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d7278cbde..e31f14961 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ ole_file = OleFile(project) ole_file.create_file(".") ``` -The VbaProject class has many layers of customization available. For example a library referenece can be added to the project. +The VbaProject class has many layers of customization available. For example a library reference can be added to the project. ```python codePage = 0x04E4 From cf7ef27b866028df2d05aff77ec64fb74fa377cf Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 31 Dec 2025 10:18:47 -0500 Subject: [PATCH 167/335] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e31f14961..4f8085824 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Eventually it will be possible to use the CLI to create a vbaProject.bin file fr The vbaProject class contains all the data and metadata that is used to create the OLE container. ```python -from vbaProjectCompiler.vbaProject import VbaProject +from ms_ovba.vbaProject import VbaProject from ms_cfb.ole_file import OleFile From f47f7a898fe62b27b0663a80cc2a032dd52ea9aa Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Wed, 31 Dec 2025 10:41:24 -0500 Subject: [PATCH 168/335] Update python-package.yml --- .github/workflows/python-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 27946caea..d00593ed2 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -15,7 +15,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] steps: - uses: actions/checkout@v3 @@ -47,7 +47,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.13"] + python-version: ["3.14"] steps: - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} From 82fa59c2ca80d62fa1138c700a3733d6fb3a4daa Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 26 Feb 2026 13:28:14 -0500 Subject: [PATCH 169/335] Fix pip install command for MS-Pcode-Assembler --- .github/workflows/python-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index d00593ed2..56721ad6b 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -27,7 +27,7 @@ jobs: run: | python -m pip install --upgrade pip pip install git+https://github.com/Beakerboy/MS-CFB@dev - pip install git+https://github.com/Beakerboy/MS-Pcode-Assembler@dev + pip install git+https://github.com/Beakerboy/MS-Pcode-Assembler pip install -e .[tests] - name: Lint with flake8 run: | From 20e0a9c112206558e82febc7ada6f54edb30809a Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 26 Feb 2026 14:18:32 -0500 Subject: [PATCH 170/335] Create project_reference.py --- .../Models/Fields/project_reference.py | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/ms_ovba/Models/Fields/project_reference.py diff --git a/src/ms_ovba/Models/Fields/project_reference.py b/src/ms_ovba/Models/Fields/project_reference.py new file mode 100644 index 000000000..89964b67e --- /dev/null +++ b/src/ms_ovba/Models/Fields/project_reference.py @@ -0,0 +1,23 @@ +from typing import TypeVar + + +T = TypeVar('T', bound='ProjectReference') + + +class ProjectReference(): + def __init__(self: T, project_path: str, embedded: bool = true) -> None: + self.project_path = project_path + self.embedded = embedded + + def __str__(self): + project_kind = 0x41 + if not(self._is_windows_path(project_path)): + project_kind += 2 + if self.embedded: + project_kind += 1 + return "*\\" + \ + chr(self.project_kind) + \ + str(self.project_path) + + def __len__(self): + return len(str(self)) From 5e929e3d7d8ae3a8eaf8de29ca33b1a9aacf7e46 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 26 Feb 2026 14:38:11 -0500 Subject: [PATCH 171/335] Update project_reference.py --- .../Models/Fields/project_reference.py | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/ms_ovba/Models/Fields/project_reference.py b/src/ms_ovba/Models/Fields/project_reference.py index 89964b67e..38aa9cefc 100644 --- a/src/ms_ovba/Models/Fields/project_reference.py +++ b/src/ms_ovba/Models/Fields/project_reference.py @@ -5,19 +5,32 @@ class ProjectReference(): + """ + Specifies the identifier of a VBA project. + """ def __init__(self: T, project_path: str, embedded: bool = true) -> None: self.project_path = project_path self.embedded = embedded def __str__(self): + return self._header() + \ + str(self.project_path) + + def __len__(self): + return len(str(self)) + + def _header(self: T): str project_kind = 0x41 if not(self._is_windows_path(project_path)): project_kind += 2 if self.embedded: project_kind += 1 return "*\\" + \ - chr(self.project_kind) + \ - str(self.project_path) + chr(self.project_kind) - def __len__(self): - return len(str(self)) + def relative_to(self: T, path: str): + """ + Return the path relative to another path. + """ + return self._header() + \ + str(self.project_path) From cc8dad1f7cc0d0a568d1a03e332bf3948ff0751c Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 26 Feb 2026 14:38:59 -0500 Subject: [PATCH 172/335] Add reference_registered.py file --- .../Entities/{reference_record.py => reference_registered.py} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename src/ms_ovba/Models/Entities/{reference_record.py => reference_registered.py} (93%) diff --git a/src/ms_ovba/Models/Entities/reference_record.py b/src/ms_ovba/Models/Entities/reference_registered.py similarity index 93% rename from src/ms_ovba/Models/Entities/reference_record.py rename to src/ms_ovba/Models/Entities/reference_registered.py index 0e8dc578f..831d0ab7c 100644 --- a/src/ms_ovba/Models/Entities/reference_record.py +++ b/src/ms_ovba/Models/Entities/reference_registered.py @@ -6,10 +6,10 @@ from typing import TypeVar -T = TypeVar('T', bound='ReferenceRecord') +T = TypeVar('T', bound='ReferenceRegistered') -class ReferenceRecord(): +class ReferenceRegistered(): def __init__(self: T, codepage_name: str, name: str, libid_ref: LibidReference) -> None: From a656356a891d3fb0ead22c915addb94a184ea6f3 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 26 Feb 2026 14:40:19 -0500 Subject: [PATCH 173/335] Update vbaProject.py --- src/ms_ovba/vbaProject.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ms_ovba/vbaProject.py b/src/ms_ovba/vbaProject.py index 95ea0ee19..a610f4f5b 100644 --- a/src/ms_ovba/vbaProject.py +++ b/src/ms_ovba/vbaProject.py @@ -1,6 +1,6 @@ from ms_ovba.Models.Entities.module_base import ModuleBase -from ms_ovba.Models.Entities.reference_record import ( - ReferenceRecord +from ms_ovba.Models.Entities.reference_registered import ( + ReferenceRegistered ) from ms_dtyp.filetime import Filetime from typing import TypeVar @@ -107,5 +107,5 @@ def get_include_projectwm(self: T) -> bool: def add_module(self: T, mod: ModuleBase) -> None: self.modules.append(mod) - def add_reference(self: T, ref: ReferenceRecord) -> None: + def add_reference(self: T, ref: ReferenceRegistered) -> None: self.references.append(ref) From dcac878d88ff797edfbf68562a5bdf5166197a95 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 26 Feb 2026 14:41:36 -0500 Subject: [PATCH 174/335] Update project_reference.py --- src/ms_ovba/Models/Fields/project_reference.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Fields/project_reference.py b/src/ms_ovba/Models/Fields/project_reference.py index 38aa9cefc..f28fed087 100644 --- a/src/ms_ovba/Models/Fields/project_reference.py +++ b/src/ms_ovba/Models/Fields/project_reference.py @@ -19,7 +19,7 @@ def __str__(self): def __len__(self): return len(str(self)) - def _header(self: T): str + def _header(self: T): project_kind = 0x41 if not(self._is_windows_path(project_path)): project_kind += 2 From 79e53281983f5664dce0afef768b4253074409e6 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 26 Feb 2026 14:42:47 -0500 Subject: [PATCH 175/335] Update project_reference.py --- src/ms_ovba/Models/Fields/project_reference.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ms_ovba/Models/Fields/project_reference.py b/src/ms_ovba/Models/Fields/project_reference.py index f28fed087..9d51e9f68 100644 --- a/src/ms_ovba/Models/Fields/project_reference.py +++ b/src/ms_ovba/Models/Fields/project_reference.py @@ -12,14 +12,14 @@ def __init__(self: T, project_path: str, embedded: bool = true) -> None: self.project_path = project_path self.embedded = embedded - def __str__(self): + def __str__(self) -> str: return self._header() + \ str(self.project_path) def __len__(self): return len(str(self)) - def _header(self: T): + def _header(self: T) -> str: project_kind = 0x41 if not(self._is_windows_path(project_path)): project_kind += 2 @@ -28,7 +28,7 @@ def _header(self: T): return "*\\" + \ chr(self.project_kind) - def relative_to(self: T, path: str): + def relative_to(self: T, path: str) -> str: """ Return the path relative to another path. """ From fb603c109011c88478ba5665e1477c47692466c9 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 26 Feb 2026 14:43:07 -0500 Subject: [PATCH 176/335] Add return type annotation to __len__ method --- src/ms_ovba/Models/Fields/project_reference.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Fields/project_reference.py b/src/ms_ovba/Models/Fields/project_reference.py index 9d51e9f68..40aaff8de 100644 --- a/src/ms_ovba/Models/Fields/project_reference.py +++ b/src/ms_ovba/Models/Fields/project_reference.py @@ -16,7 +16,7 @@ def __str__(self) -> str: return self._header() + \ str(self.project_path) - def __len__(self): + def __len__(self) -> int: return len(str(self)) def _header(self: T) -> str: From 6de90a4ca57c397e0b17004709f8ed0e608414a7 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Thu, 26 Feb 2026 15:04:05 -0500 Subject: [PATCH 177/335] Create reference_project.py --- .../Models/Entities/reference_project.py | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/ms_ovba/Models/Entities/reference_project.py diff --git a/src/ms_ovba/Models/Entities/reference_project.py b/src/ms_ovba/Models/Entities/reference_project.py new file mode 100644 index 000000000..9c73acd4d --- /dev/null +++ b/src/ms_ovba/Models/Entities/reference_project.py @@ -0,0 +1,29 @@ +from ms_ovba.Models.Fields.doubleEncodedString import ( + DoubleEncodedString +) +from ms_ovba.Models.Fields.project_reference import ProjectReference +from ms_ovba.Models.Fields.packed_data import PackedData +from typing import TypeVar + + +T = TypeVar('T', bound='ReferenceProject') + + +class ReferenceProject(): + + def __init__(self: T, codepage_name: str, + ref: ProjectReference) -> None: + # is self._codepage_name even needed? + self._codepage_name = codepage_name + self._ref = ref + + def pack(self: T, codepage_name: str, endien: str) -> bytes: + size_of_libid_absolute = len(self._ref) + size_of_libid_relative = = len(self._ref.relative_to("")) + format = "HII" + str(size_of_libid_absolute) + "sI" + str(size_of_libid_relative) + "sIH" + ref_str = str(self._ref).encode(self._codepage_name) + ref_str_rel = str(self._ref.relative_to("")).encode(self._codepage_name) + ref_project = PackedData(format, 0x000E, size_of_libid_absolute + size_of_libid_relative + 20, + size_of_libid_absolute, ref_str, size_of_libid_relative, ref_str_rel, 0x65BE0257, 0x0017) + + return (ref_project.pack(codepage_name, endien)) From 1e0b27c0fc928bc3b3dc2106470febbc8999db21 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 08:02:30 -0500 Subject: [PATCH 178/335] Fix syntax error in pack method for reference_project --- src/ms_ovba/Models/Entities/reference_project.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Entities/reference_project.py b/src/ms_ovba/Models/Entities/reference_project.py index 9c73acd4d..0aa02bb56 100644 --- a/src/ms_ovba/Models/Entities/reference_project.py +++ b/src/ms_ovba/Models/Entities/reference_project.py @@ -19,7 +19,7 @@ def __init__(self: T, codepage_name: str, def pack(self: T, codepage_name: str, endien: str) -> bytes: size_of_libid_absolute = len(self._ref) - size_of_libid_relative = = len(self._ref.relative_to("")) + size_of_libid_relative = len(self._ref.relative_to("")) format = "HII" + str(size_of_libid_absolute) + "sI" + str(size_of_libid_relative) + "sIH" ref_str = str(self._ref).encode(self._codepage_name) ref_str_rel = str(self._ref.relative_to("")).encode(self._codepage_name) From e2f29e55d9600b771442c5b1d3830924c8ad3e87 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 08:08:10 -0500 Subject: [PATCH 179/335] Fix constructor parameter default value for embedded --- src/ms_ovba/Models/Fields/project_reference.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Fields/project_reference.py b/src/ms_ovba/Models/Fields/project_reference.py index 40aaff8de..e334c3ff1 100644 --- a/src/ms_ovba/Models/Fields/project_reference.py +++ b/src/ms_ovba/Models/Fields/project_reference.py @@ -6,9 +6,14 @@ class ProjectReference(): """ + 2.1.1.12 Specifies the identifier of a VBA project. + + ProjectReference = "*\" ProjectKind ProjectPath + ProjectKind = %x41-44 + ProjectPath = *(%x01-FF} """ - def __init__(self: T, project_path: str, embedded: bool = true) -> None: + def __init__(self: T, project_path: str, embedded: bool = True) -> None: self.project_path = project_path self.embedded = embedded From 76107d086c32475612be05c0df6942f839cc387c Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 08:11:09 -0500 Subject: [PATCH 180/335] Add docstring to LibidReference class Added a docstring to the LibidReference class that defines its structure and components. --- src/ms_ovba/Models/Fields/libid_reference.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/ms_ovba/Models/Fields/libid_reference.py b/src/ms_ovba/Models/Fields/libid_reference.py index 12fbb2de0..2c71c5be8 100644 --- a/src/ms_ovba/Models/Fields/libid_reference.py +++ b/src/ms_ovba/Models/Fields/libid_reference.py @@ -6,6 +6,22 @@ class LibidReference(): + """ + 2.1.1.8 + + LibidReference = "*\" LibidReferenceKind LibidGuid + "#" LibidMajorVersion "." LibidMinorVersion + "#" LibidLcid + "#" LibidPath + "#" LibidRegName + LibidReferenceKind = %x47 / %x48 + LibidGuid = GUID + LibidMajorVersion = 1*4HEXDIG + LibidMinorVersion = 1*4HEXDIG + LibidLcid = 1*8HEXDIG + LibidPath = *(%x01-22 / %x24-FF) + LibidRegName = *255(%x01-FF) + """ def __init__(self: T, libid_guid: uuid.UUID, version: str, libid_lcid: str, libid_path: str, libid_reg_name: str) -> None: From 52a427fd60a4cff8513081c6faa54c2382931f7e Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 08:24:03 -0500 Subject: [PATCH 181/335] Update python-package.yml --- .github/workflows/python-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 56721ad6b..00471a527 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -26,7 +26,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install git+https://github.com/Beakerboy/MS-CFB@dev + pip install git+https://github.com/Beakerboy/MS-CFB pip install git+https://github.com/Beakerboy/MS-Pcode-Assembler pip install -e .[tests] - name: Lint with flake8 From e9e886746de7f6b0199e9d6822e2b60f5468e588 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 08:26:13 -0500 Subject: [PATCH 182/335] Fix formatting issues in project_reference.py --- src/ms_ovba/Models/Fields/project_reference.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Fields/project_reference.py b/src/ms_ovba/Models/Fields/project_reference.py index e334c3ff1..691038fa6 100644 --- a/src/ms_ovba/Models/Fields/project_reference.py +++ b/src/ms_ovba/Models/Fields/project_reference.py @@ -8,7 +8,7 @@ class ProjectReference(): """ 2.1.1.12 Specifies the identifier of a VBA project. - + ProjectReference = "*\" ProjectKind ProjectPath ProjectKind = %x41-44 ProjectPath = *(%x01-FF} From 115b952c33fcaa21a5b218999f158b0c3e5c1626 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 08:26:38 -0500 Subject: [PATCH 183/335] Fix formatting in LibidReference class definition --- src/ms_ovba/Models/Fields/libid_reference.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ms_ovba/Models/Fields/libid_reference.py b/src/ms_ovba/Models/Fields/libid_reference.py index 2c71c5be8..9eef6d86d 100644 --- a/src/ms_ovba/Models/Fields/libid_reference.py +++ b/src/ms_ovba/Models/Fields/libid_reference.py @@ -8,17 +8,17 @@ class LibidReference(): """ 2.1.1.8 - - LibidReference = "*\" LibidReferenceKind LibidGuid - "#" LibidMajorVersion "." LibidMinorVersion - "#" LibidLcid - "#" LibidPath + + LibidReference = "*\" LibidReferenceKind LibidGuid + "#" LibidMajorVersion "." LibidMinorVersion + "#" LibidLcid + "#" LibidPath "#" LibidRegName LibidReferenceKind = %x47 / %x48 LibidGuid = GUID LibidMajorVersion = 1*4HEXDIG LibidMinorVersion = 1*4HEXDIG - LibidLcid = 1*8HEXDIG + LibidLcid = 1*8HEXDIG LibidPath = *(%x01-22 / %x24-FF) LibidRegName = *255(%x01-FF) """ From 9d898bf0346e548975e763aa7982bc7372733e72 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 08:28:31 -0500 Subject: [PATCH 184/335] Update project_reference.py --- src/ms_ovba/Models/Fields/project_reference.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Fields/project_reference.py b/src/ms_ovba/Models/Fields/project_reference.py index 691038fa6..05576e1e1 100644 --- a/src/ms_ovba/Models/Fields/project_reference.py +++ b/src/ms_ovba/Models/Fields/project_reference.py @@ -26,7 +26,7 @@ def __len__(self) -> int: def _header(self: T) -> str: project_kind = 0x41 - if not(self._is_windows_path(project_path)): + if not self._is_windows_path(self.project_path): project_kind += 2 if self.embedded: project_kind += 1 From 86b27dbb3adc3df5af1785efa920e11dac66526f Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 08:38:01 -0500 Subject: [PATCH 185/335] Update reference_project.py --- .../Models/Entities/reference_project.py | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference_project.py b/src/ms_ovba/Models/Entities/reference_project.py index 0aa02bb56..0a0cc92dd 100644 --- a/src/ms_ovba/Models/Entities/reference_project.py +++ b/src/ms_ovba/Models/Entities/reference_project.py @@ -18,12 +18,16 @@ def __init__(self: T, codepage_name: str, self._ref = ref def pack(self: T, codepage_name: str, endien: str) -> bytes: - size_of_libid_absolute = len(self._ref) - size_of_libid_relative = len(self._ref.relative_to("")) - format = "HII" + str(size_of_libid_absolute) + "sI" + str(size_of_libid_relative) + "sIH" - ref_str = str(self._ref).encode(self._codepage_name) - ref_str_rel = str(self._ref.relative_to("")).encode(self._codepage_name) - ref_project = PackedData(format, 0x000E, size_of_libid_absolute + size_of_libid_relative + 20, - size_of_libid_absolute, ref_str, size_of_libid_relative, ref_str_rel, 0x65BE0257, 0x0017) + cp_name = self._codepage_name + libid_abs_size = len(self._ref) + libid_rel_size = len(self._ref.relative_to("")) + format = ("HII" + str(libid_abs_size) + "sI" + + str(libid_rel_size) + "sIH") + ref_str = str(self._ref).encode(cp_name) + ref_str_rel = str(self._ref.relative_to("")).encode(cp_name) + ref_project = PackedData(format, 0x000E, + libid_abs_size + libid_rel_size + 20, + libid_abs_size, ref_str, libid_rel_size, + ref_str_rel, 0x65BE0257, 0x0017) - return (ref_project.pack(codepage_name, endien)) + return (ref_project.pack(cp_name, endien)) From b7e3f31c1a62d52c7f0e657d8e57237325eb8218 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 08:39:11 -0500 Subject: [PATCH 186/335] Update reference_project.py --- src/ms_ovba/Models/Entities/reference_project.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference_project.py b/src/ms_ovba/Models/Entities/reference_project.py index 0a0cc92dd..075f29c19 100644 --- a/src/ms_ovba/Models/Entities/reference_project.py +++ b/src/ms_ovba/Models/Entities/reference_project.py @@ -1,6 +1,3 @@ -from ms_ovba.Models.Fields.doubleEncodedString import ( - DoubleEncodedString -) from ms_ovba.Models.Fields.project_reference import ProjectReference from ms_ovba.Models.Fields.packed_data import PackedData from typing import TypeVar From b6de01708dd828259ba38735514c49e9ed27fa0f Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 08:43:21 -0500 Subject: [PATCH 187/335] Update reference_registered.py --- src/ms_ovba/Models/Entities/reference_registered.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Entities/reference_registered.py b/src/ms_ovba/Models/Entities/reference_registered.py index 831d0ab7c..1e21b0078 100644 --- a/src/ms_ovba/Models/Entities/reference_registered.py +++ b/src/ms_ovba/Models/Entities/reference_registered.py @@ -10,7 +10,10 @@ class ReferenceRegistered(): - + """ + 2.3.4.2.2.5 + Specifies a reference to an Automation type library. + """ def __init__(self: T, codepage_name: str, name: str, libid_ref: LibidReference) -> None: # is self._codepage_name even needed? From 01418ab81c1ddd30409b349a3f1a023e9e476286 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 08:44:45 -0500 Subject: [PATCH 188/335] Update reference_project.py --- src/ms_ovba/Models/Entities/reference_project.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Entities/reference_project.py b/src/ms_ovba/Models/Entities/reference_project.py index 075f29c19..ae0580917 100644 --- a/src/ms_ovba/Models/Entities/reference_project.py +++ b/src/ms_ovba/Models/Entities/reference_project.py @@ -24,7 +24,7 @@ def pack(self: T, codepage_name: str, endien: str) -> bytes: ref_str_rel = str(self._ref.relative_to("")).encode(cp_name) ref_project = PackedData(format, 0x000E, libid_abs_size + libid_rel_size + 20, - libid_abs_size, ref_str, libid_rel_size, + libid_abs_size, ref_str, libid_rel_size, ref_str_rel, 0x65BE0257, 0x0017) return (ref_project.pack(cp_name, endien)) From 5469b92bbaba5aa13ed609245c524c81f2dc1d9e Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 09:01:00 -0500 Subject: [PATCH 189/335] Create reference.py --- src/ms_ovba/Models/Entities/reference.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/ms_ovba/Models/Entities/reference.py diff --git a/src/ms_ovba/Models/Entities/reference.py b/src/ms_ovba/Models/Entities/reference.py new file mode 100644 index 000000000..bc3ffee3d --- /dev/null +++ b/src/ms_ovba/Models/Entities/reference.py @@ -0,0 +1,23 @@ +from ms_ovba.Models.Fields.project_reference import ProjectReference +from ms_ovba.Models.Fields.packed_data import PackedData +from typing import TypeVar + + +T = TypeVar('T', bound='Reference') + + +class Reference(): + """ + 2.3.4.2.2.1 REFERENCE Record + """ + def __init__(self: T, codepage_name: str, + ref: ReferenceType, name: ReferenceName = None) -> None: + # is self._codepage_name even needed? + self._codepage_name = codepage_name + self._ref = ref + self._name = name + + def pack(self: T, cp_name: str, endien: str) -> bytes: + name = self._name + pack_name = name.pack(cp_name, endien) if not name is None else "" + return pack_name + self._ref.pack(cp_name, endien) From 978a39816bd0df8b3c89c8ae24c098e603acad06 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 09:02:04 -0500 Subject: [PATCH 190/335] Update reference.py --- src/ms_ovba/Models/Entities/reference.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference.py b/src/ms_ovba/Models/Entities/reference.py index bc3ffee3d..1baf17cb6 100644 --- a/src/ms_ovba/Models/Entities/reference.py +++ b/src/ms_ovba/Models/Entities/reference.py @@ -1,5 +1,5 @@ -from ms_ovba.Models.Fields.project_reference import ProjectReference -from ms_ovba.Models.Fields.packed_data import PackedData +from ms_ovba.Models.Entities.reference_name import ReferenceName +from ms_ovba.Models.Entities.reference_type import ReferenceType from typing import TypeVar From b389f998d3c1d64cc138534f29cc02adb2d9bcd3 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 09:03:28 -0500 Subject: [PATCH 191/335] Update reference_project.py --- src/ms_ovba/Models/Entities/reference_project.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Entities/reference_project.py b/src/ms_ovba/Models/Entities/reference_project.py index ae0580917..c7c039757 100644 --- a/src/ms_ovba/Models/Entities/reference_project.py +++ b/src/ms_ovba/Models/Entities/reference_project.py @@ -1,3 +1,4 @@ +from ms_ovba.Models.Entities.reference_type import ReferenceType from ms_ovba.Models.Fields.project_reference import ProjectReference from ms_ovba.Models.Fields.packed_data import PackedData from typing import TypeVar @@ -6,7 +7,7 @@ T = TypeVar('T', bound='ReferenceProject') -class ReferenceProject(): +class ReferenceProject(ReferenceType): def __init__(self: T, codepage_name: str, ref: ProjectReference) -> None: From d2d40582aa3fa7aaeb68756dd3b2189e27411c0d Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 09:03:50 -0500 Subject: [PATCH 192/335] Update reference_registered.py --- src/ms_ovba/Models/Entities/reference_registered.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Entities/reference_registered.py b/src/ms_ovba/Models/Entities/reference_registered.py index 1e21b0078..a32e1b2df 100644 --- a/src/ms_ovba/Models/Entities/reference_registered.py +++ b/src/ms_ovba/Models/Entities/reference_registered.py @@ -1,3 +1,4 @@ +from ms_ovba.Models.Entities.reference_type import ReferenceType from ms_ovba.Models.Fields.doubleEncodedString import ( DoubleEncodedString ) @@ -9,7 +10,7 @@ T = TypeVar('T', bound='ReferenceRegistered') -class ReferenceRegistered(): +class ReferenceRegistered(ReferenceType): """ 2.3.4.2.2.5 Specifies a reference to an Automation type library. From 3c7cc3c4e3ebcd8a750685470922da751dd8f53d Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 09:04:48 -0500 Subject: [PATCH 193/335] Create reference_type --- src/ms_ovba/Models/Entities/reference_type | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/ms_ovba/Models/Entities/reference_type diff --git a/src/ms_ovba/Models/Entities/reference_type b/src/ms_ovba/Models/Entities/reference_type new file mode 100644 index 000000000..e582cf4c0 --- /dev/null +++ b/src/ms_ovba/Models/Entities/reference_type @@ -0,0 +1,7 @@ +from typing import TypeVar + + +T = TypeVar('T', bound='ReferenceType') + + +class ReferenceType: From 3d1fe1a38596972e61a6ca21b5fc88aca91b2b7b Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 09:06:28 -0500 Subject: [PATCH 194/335] Update reference.py --- src/ms_ovba/Models/Entities/reference.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Entities/reference.py b/src/ms_ovba/Models/Entities/reference.py index 1baf17cb6..f9d3d7d98 100644 --- a/src/ms_ovba/Models/Entities/reference.py +++ b/src/ms_ovba/Models/Entities/reference.py @@ -19,5 +19,5 @@ def __init__(self: T, codepage_name: str, def pack(self: T, cp_name: str, endien: str) -> bytes: name = self._name - pack_name = name.pack(cp_name, endien) if not name is None else "" + pack_name = name.pack(cp_name, endien) if is not name is None else "" return pack_name + self._ref.pack(cp_name, endien) From 91e206859511d18e9abd31304a71381b67bd2f41 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 09:07:10 -0500 Subject: [PATCH 195/335] Update reference.py --- src/ms_ovba/Models/Entities/reference.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Entities/reference.py b/src/ms_ovba/Models/Entities/reference.py index f9d3d7d98..bd02dbfec 100644 --- a/src/ms_ovba/Models/Entities/reference.py +++ b/src/ms_ovba/Models/Entities/reference.py @@ -19,5 +19,5 @@ def __init__(self: T, codepage_name: str, def pack(self: T, cp_name: str, endien: str) -> bytes: name = self._name - pack_name = name.pack(cp_name, endien) if is not name is None else "" + pack_name = name.pack(cp_name, endien) if name is not None else "" return pack_name + self._ref.pack(cp_name, endien) From 5269919518cf69f39c122ee5512a3c857e866190 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 09:36:26 -0500 Subject: [PATCH 196/335] Rename reference_type to reference_type.py --- src/ms_ovba/Models/Entities/{reference_type => reference_type.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/ms_ovba/Models/Entities/{reference_type => reference_type.py} (100%) diff --git a/src/ms_ovba/Models/Entities/reference_type b/src/ms_ovba/Models/Entities/reference_type.py similarity index 100% rename from src/ms_ovba/Models/Entities/reference_type rename to src/ms_ovba/Models/Entities/reference_type.py From c3383fd8c8a1c5cc281ab90657f94893d8dbc7cb Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 09:39:01 -0500 Subject: [PATCH 197/335] Update reference_type.py --- src/ms_ovba/Models/Entities/reference_type.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ms_ovba/Models/Entities/reference_type.py b/src/ms_ovba/Models/Entities/reference_type.py index e582cf4c0..f7fa14222 100644 --- a/src/ms_ovba/Models/Entities/reference_type.py +++ b/src/ms_ovba/Models/Entities/reference_type.py @@ -5,3 +5,6 @@ class ReferenceType: + + def pack(self: T, codepage_name: str, endien: str) -> bytes: + return b'' From 8201893bcd0729e9fb28bcf1561d94f3cf64d57d Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 09:40:27 -0500 Subject: [PATCH 198/335] Update reference_type.py --- src/ms_ovba/Models/Entities/reference_type.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference_type.py b/src/ms_ovba/Models/Entities/reference_type.py index f7fa14222..df229eef1 100644 --- a/src/ms_ovba/Models/Entities/reference_type.py +++ b/src/ms_ovba/Models/Entities/reference_type.py @@ -6,5 +6,5 @@ class ReferenceType: - def pack(self: T, codepage_name: str, endien: str) -> bytes: - return b'' + def pack(self: T, codepage_name: str, endien: str) -> bytes: + return b'' From 2ab355c093e369c052e15ae7933c296bc88f8eae Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 09:54:13 -0500 Subject: [PATCH 199/335] Update doubleEncodedString.py --- src/ms_ovba/Models/Fields/doubleEncodedString.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Fields/doubleEncodedString.py b/src/ms_ovba/Models/Fields/doubleEncodedString.py index 41aee34ca..09c43166c 100644 --- a/src/ms_ovba/Models/Fields/doubleEncodedString.py +++ b/src/ms_ovba/Models/Fields/doubleEncodedString.py @@ -7,7 +7,8 @@ class DoubleEncodedString(): """ - Encode text data twice with different ids and lengths + A union of two IdSizeFields + The strings are encoded differently in each. """ def __init__(self: T, ids: list, text: str) -> None: self.ids = ids From 43fe040937a07f47e336708868a08d73c6bec158 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 09:55:20 -0500 Subject: [PATCH 200/335] Update reference.py --- src/ms_ovba/Models/Entities/reference.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference.py b/src/ms_ovba/Models/Entities/reference.py index bd02dbfec..2118cd7a2 100644 --- a/src/ms_ovba/Models/Entities/reference.py +++ b/src/ms_ovba/Models/Entities/reference.py @@ -1,5 +1,7 @@ -from ms_ovba.Models.Entities.reference_name import ReferenceName from ms_ovba.Models.Entities.reference_type import ReferenceType +from ms_ovba.Models.Fields.doubleEncodedString import ( + DoubleEncodedString +) from typing import TypeVar @@ -11,7 +13,7 @@ class Reference(): 2.3.4.2.2.1 REFERENCE Record """ def __init__(self: T, codepage_name: str, - ref: ReferenceType, name: ReferenceName = None) -> None: + ref: ReferenceType, name: DoubleEncodedString = None) -> None: # is self._codepage_name even needed? self._codepage_name = codepage_name self._ref = ref From 948eaa363e82beaad8dd0ef202f660120d342cb4 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 10:03:20 -0500 Subject: [PATCH 201/335] Update reference class to use refname instead of name Refactor reference class to change name attribute handling. --- src/ms_ovba/Models/Entities/reference.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference.py b/src/ms_ovba/Models/Entities/reference.py index 2118cd7a2..1491cd585 100644 --- a/src/ms_ovba/Models/Entities/reference.py +++ b/src/ms_ovba/Models/Entities/reference.py @@ -13,13 +13,17 @@ class Reference(): 2.3.4.2.2.1 REFERENCE Record """ def __init__(self: T, codepage_name: str, - ref: ReferenceType, name: DoubleEncodedString = None) -> None: + ref: ReferenceType, + name: str = None) -> None: # is self._codepage_name even needed? self._codepage_name = codepage_name self._ref = ref - self._name = name + self._refname = name def pack(self: T, cp_name: str, endien: str) -> bytes: - name = self._name - pack_name = name.pack(cp_name, endien) if name is not None else "" - return pack_name + self._ref.pack(cp_name, endien) + name_pack = b'' + if self._refname is not None: + name_de = DoubleEncodedString([0x0016, 0x003E], name) + name_pack = name_de.pack(codepage_name, endien) + + return name_pack + self._ref.pack(cp_name, endien) From a63d1f67615f07da9fab065d4ad210c9d288b287 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 10:05:24 -0500 Subject: [PATCH 202/335] Update reference_registered.py --- src/ms_ovba/Models/Entities/reference_registered.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference_registered.py b/src/ms_ovba/Models/Entities/reference_registered.py index a32e1b2df..b3a97339c 100644 --- a/src/ms_ovba/Models/Entities/reference_registered.py +++ b/src/ms_ovba/Models/Entities/reference_registered.py @@ -16,18 +16,16 @@ class ReferenceRegistered(ReferenceType): Specifies a reference to an Automation type library. """ def __init__(self: T, codepage_name: str, - name: str, libid_ref: LibidReference) -> None: + libid_ref: LibidReference) -> None: # is self._codepage_name even needed? self._codepage_name = codepage_name - self._refname = DoubleEncodedString([0x0016, 0x003E], name) self._libid_ref = libid_ref - def pack(self: T, codepage_name: str, endien: str) -> bytes: + def pack(self: T, cp_name: str, endien: str) -> bytes: strlen = len(self._libid_ref) format = "HII" + str(strlen) + "sIH" - lib_str = str(self._libid_ref).encode(self._codepage_name) + lib_str = str(self._libid_ref).encode(cp_name) ref_registered = PackedData(format, 0x000D, strlen + 10, strlen, lib_str, 0, 0) - return (self._refname.pack(codepage_name, endien) - + ref_registered.pack(codepage_name, endien)) + return ref_registered.pack(cp_name, endien) From 59d51118d79a984c33738de576773e3f18b96885 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 10:07:03 -0500 Subject: [PATCH 203/335] Update reference.py --- src/ms_ovba/Models/Entities/reference.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference.py b/src/ms_ovba/Models/Entities/reference.py index 1491cd585..99cbc1f52 100644 --- a/src/ms_ovba/Models/Entities/reference.py +++ b/src/ms_ovba/Models/Entities/reference.py @@ -23,7 +23,7 @@ def __init__(self: T, codepage_name: str, def pack(self: T, cp_name: str, endien: str) -> bytes: name_pack = b'' if self._refname is not None: - name_de = DoubleEncodedString([0x0016, 0x003E], name) - name_pack = name_de.pack(codepage_name, endien) + name_de = DoubleEncodedString([0x0016, 0x003E], self._refname) + name_pack = name_de.pack(cp_name, endien) return name_pack + self._ref.pack(cp_name, endien) From a2374e44e18444f1148591fb146efed754681675 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 10:07:27 -0500 Subject: [PATCH 204/335] Update reference_registered.py --- src/ms_ovba/Models/Entities/reference_registered.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference_registered.py b/src/ms_ovba/Models/Entities/reference_registered.py index b3a97339c..df54c3796 100644 --- a/src/ms_ovba/Models/Entities/reference_registered.py +++ b/src/ms_ovba/Models/Entities/reference_registered.py @@ -1,7 +1,4 @@ from ms_ovba.Models.Entities.reference_type import ReferenceType -from ms_ovba.Models.Fields.doubleEncodedString import ( - DoubleEncodedString -) from ms_ovba.Models.Fields.libid_reference import LibidReference from ms_ovba.Models.Fields.packed_data import PackedData from typing import TypeVar From 0d5209a73c489b985280806fced33434ce26d583 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 10:14:41 -0500 Subject: [PATCH 205/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index f38120f52..ed8b210e9 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -10,8 +10,11 @@ from ms_ovba.vbaProject import VbaProject from ms_ovba.Models.Entities.doc_module import DocModule from ms_ovba.Models.Entities.std_module import StdModule -from ms_ovba.Models.Entities.reference_record import ( - ReferenceRecord +from ms_ovba.Models.Entities.reference import ( + Reference +) +from ms_ovba.Models.Entities.reference_registered import ( + ReferenceRegistered ) from ms_ovba.Models.Fields.libid_reference import LibidReference from ms_ovba.Views.project_ole_file import ProjectOleFile @@ -80,22 +83,22 @@ def test_full_file() -> None: project.set_include_projectwm(True) codepage = 0x04E4 codepage_name = "cp" + str(codepage) - libid_ref = LibidReference( + libid_ref = ReferenceRegistered(LibidReference( uuid.UUID("0002043000000000C000000000000046"), "2.0", "0", "C:\\Windows\\System32\\stdole2.tlb", "OLE Automation" - ) - ole_reference = ReferenceRecord(codepage_name, "stdole", libid_ref) - libid_ref2 = LibidReference( + )) + ole_reference = Reference(codepage_name, libid_refm, "stdole") + libid_ref2 = ReferenceRegistered(LibidReference( uuid.UUID("2DF8D04C5BFA101BBDE500AA0044DE52"), "2.0", "0", "C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE16\\MSO.DLL", "Microsoft Office 16.0 Object Library" - ) - office_reference = ReferenceRecord(codepage_name, "Office", libid_ref2) + )) + office_reference = Reference(codepage_name, libid_ref2, "Office") project.add_reference(ole_reference) project.add_reference(office_reference) proj_cookie = 0x08F3 From 0841d7c24aec6e8dcdbc679b665b5f999bbd22f6 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 10:16:14 -0500 Subject: [PATCH 206/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index ed8b210e9..dc8babd7f 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -90,7 +90,7 @@ def test_full_file() -> None: "C:\\Windows\\System32\\stdole2.tlb", "OLE Automation" )) - ole_reference = Reference(codepage_name, libid_refm, "stdole") + ole_reference = Reference(codepage_name, libid_ref, "stdole") libid_ref2 = ReferenceRegistered(LibidReference( uuid.UUID("2DF8D04C5BFA101BBDE500AA0044DE52"), "2.0", From dc675b10fb6f45dc87141c7e92235e8558d1a60a Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 10:18:46 -0500 Subject: [PATCH 207/335] Update test_dirObject.py --- tests/Functional/test_dirObject.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/tests/Functional/test_dirObject.py b/tests/Functional/test_dirObject.py index 535004ea8..d33ca4393 100644 --- a/tests/Functional/test_dirObject.py +++ b/tests/Functional/test_dirObject.py @@ -7,10 +7,15 @@ from ms_ovba.Models.Fields.libid_reference import LibidReference from ms_ovba.Models.Entities.doc_module import DocModule from ms_ovba.Models.Entities.std_module import StdModule -from ms_ovba.Models.Entities.reference_record import ( - ReferenceRecord +from ms_ovba.Models.Entities.reference import ( + Reference +) +from ms_ovba.Models.Entities.reference import ( + Reference +) +from ms_ovba.Models.Entities.reference_registered import ( + ReferenceRegistered ) - def test_dirstream() -> None: ''' @@ -33,23 +38,23 @@ def test_dirstream() -> None: codepage = 0x04E4 codepage_name = "cp" + str(codepage) guid = uuid.UUID('0002043000000000C000000000000046') - libid_ref = LibidReference( + libid_ref = ReferenceRegistered(LibidReference( guid, "2.0", "0", "C:\\Windows\\System32\\stdole2.tlb", "OLE Automation" - ) - ole_reference = ReferenceRecord(codepage_name, "stdole", libid_ref) + )) + ole_reference = Reference(codepage_name, libid_ref, "stdole") guid = uuid.UUID('2DF8D04C5BFA101BBDE500AA0044DE52') - libid_ref2 = LibidReference( + libid_ref2 = ReferenceRegistered(LibidReference( guid, "2.0", "0", "C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE16\\MSO.DLL", "Microsoft Office 16.0 Object Library" - ) - office_reference = ReferenceRecord(codepage_name, "Office", libid_ref2) + )) + office_reference = Reference(codepage_name, libid_ref2, "Office") project.add_reference(ole_reference) project.add_reference(office_reference) project.set_project_cookie(0x08F3) From 8d2d5ed703b25a321110526ce3a54fb9b22a54eb Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 10:22:35 -0500 Subject: [PATCH 208/335] Update test_fullFile.py --- tests/Functional/test_fullFile.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.py index dc8babd7f..82f6f749b 100644 --- a/tests/Functional/test_fullFile.py +++ b/tests/Functional/test_fullFile.py @@ -83,7 +83,7 @@ def test_full_file() -> None: project.set_include_projectwm(True) codepage = 0x04E4 codepage_name = "cp" + str(codepage) - libid_ref = ReferenceRegistered(LibidReference( + libid_ref = ReferenceRegistered(codepage_name, LibidReference( uuid.UUID("0002043000000000C000000000000046"), "2.0", "0", @@ -91,7 +91,7 @@ def test_full_file() -> None: "OLE Automation" )) ole_reference = Reference(codepage_name, libid_ref, "stdole") - libid_ref2 = ReferenceRegistered(LibidReference( + libid_ref2 = ReferenceRegistered(codepage_name, LibidReference( uuid.UUID("2DF8D04C5BFA101BBDE500AA0044DE52"), "2.0", "0", From 4d7fcc47ae4aad000b06211fad0bc3a0e4e521ec Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 10:22:56 -0500 Subject: [PATCH 209/335] Update test_dirObject.py --- tests/Functional/test_dirObject.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Functional/test_dirObject.py b/tests/Functional/test_dirObject.py index d33ca4393..5cc872482 100644 --- a/tests/Functional/test_dirObject.py +++ b/tests/Functional/test_dirObject.py @@ -38,7 +38,7 @@ def test_dirstream() -> None: codepage = 0x04E4 codepage_name = "cp" + str(codepage) guid = uuid.UUID('0002043000000000C000000000000046') - libid_ref = ReferenceRegistered(LibidReference( + libid_ref = ReferenceRegistered(codepage_name, LibidReference( guid, "2.0", "0", @@ -47,7 +47,7 @@ def test_dirstream() -> None: )) ole_reference = Reference(codepage_name, libid_ref, "stdole") guid = uuid.UUID('2DF8D04C5BFA101BBDE500AA0044DE52') - libid_ref2 = ReferenceRegistered(LibidReference( + libid_ref2 = ReferenceRegistered(codepage_name, LibidReference( guid, "2.0", "0", From 4c9e8dc350d34b5b668efe2e9a0f6e06573cccb5 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 10:24:18 -0500 Subject: [PATCH 210/335] Update test_dirObject.py --- tests/Functional/test_dirObject.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/Functional/test_dirObject.py b/tests/Functional/test_dirObject.py index 5cc872482..7a86f26a2 100644 --- a/tests/Functional/test_dirObject.py +++ b/tests/Functional/test_dirObject.py @@ -10,13 +10,11 @@ from ms_ovba.Models.Entities.reference import ( Reference ) -from ms_ovba.Models.Entities.reference import ( - Reference -) from ms_ovba.Models.Entities.reference_registered import ( ReferenceRegistered ) + def test_dirstream() -> None: ''' The cache is not yet tested. From f6cfec94f81965284e03fc6ec99e3f8783445ae5 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 10:43:06 -0500 Subject: [PATCH 211/335] Update reference_registered.py --- .../Models/Entities/reference_registered.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/ms_ovba/Models/Entities/reference_registered.py b/src/ms_ovba/Models/Entities/reference_registered.py index df54c3796..ab26b0343 100644 --- a/src/ms_ovba/Models/Entities/reference_registered.py +++ b/src/ms_ovba/Models/Entities/reference_registered.py @@ -18,6 +18,10 @@ def __init__(self: T, codepage_name: str, self._codepage_name = codepage_name self._libid_ref = libid_ref + @property + def libid(self: T): LibidReference + return self._libid_ref + def pack(self: T, cp_name: str, endien: str) -> bytes: strlen = len(self._libid_ref) format = "HII" + str(strlen) + "sIH" @@ -26,3 +30,19 @@ def pack(self: T, cp_name: str, endien: str) -> bytes: strlen, lib_str, 0, 0) return ref_registered.pack(cp_name, endien) + + @staticmethod + def unpack(data: bytes) -> T: + # Read two bytes into ID + # if id !== 0x000D throw exception + # Read 4 bytes into recordsize + # If size(data) !== recordsize + 6 throw notice + # Read 4 bytes into libidsize + # Read libidsize bytes into libid_ref_bytes + # Read 4 bytes into reserved1 + # If reserved1 !== 0 throw notice + # Read 2 bytes into reserved2 + # If reserved2 !== 0 throw notice + # libid_ref = LibidReference.create(libid_ref_bytes) + # return ReferenceRegistered("", libid_ref) + From 4c048412f601802ecd1f1bb7d1a0518f145df744 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 10:46:38 -0500 Subject: [PATCH 212/335] Update reference_registered.py --- src/ms_ovba/Models/Entities/reference_registered.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Entities/reference_registered.py b/src/ms_ovba/Models/Entities/reference_registered.py index ab26b0343..66c03b07f 100644 --- a/src/ms_ovba/Models/Entities/reference_registered.py +++ b/src/ms_ovba/Models/Entities/reference_registered.py @@ -19,7 +19,7 @@ def __init__(self: T, codepage_name: str, self._libid_ref = libid_ref @property - def libid(self: T): LibidReference + def libid(self: T) -> LibidReference: return self._libid_ref def pack(self: T, cp_name: str, endien: str) -> bytes: From 7da2347772ca02082cb3c4f96dceda95837cc8a5 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 11:01:58 -0500 Subject: [PATCH 213/335] Update reference_registered.py --- .../Models/Entities/reference_registered.py | 44 ++++++++++++++----- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference_registered.py b/src/ms_ovba/Models/Entities/reference_registered.py index 66c03b07f..853dea2af 100644 --- a/src/ms_ovba/Models/Entities/reference_registered.py +++ b/src/ms_ovba/Models/Entities/reference_registered.py @@ -33,16 +33,36 @@ def pack(self: T, cp_name: str, endien: str) -> bytes: @staticmethod def unpack(data: bytes) -> T: - # Read two bytes into ID - # if id !== 0x000D throw exception - # Read 4 bytes into recordsize - # If size(data) !== recordsize + 6 throw notice - # Read 4 bytes into libidsize - # Read libidsize bytes into libid_ref_bytes - # Read 4 bytes into reserved1 - # If reserved1 !== 0 throw notice - # Read 2 bytes into reserved2 - # If reserved2 !== 0 throw notice - # libid_ref = LibidReference.create(libid_ref_bytes) - # return ReferenceRegistered("", libid_ref) + start = 0 + end = 2 + id = bytes[start:end] + if id !== 0x000D: + raise ValueError("Incorrect id in data.") + + start = end + end = end + 4 + recordsize = bytes[start:end] + if len(data) !== recordsize + 6: + # raise a warning + + start = end + end = end + 4 + libidsize = bytes[start:end] + start = end + end = end + libidsize + libid_ref_bytes = bytes[start:end] + start = end + end = end + 4 + reserved1 = bytes[start:end] + if reserved1 !== 0: + # raise a warning + + start = end + end = end + 2 + reserved2 = bytes[start:end] + if reserved2 !== 0: + # raise a warning + + libid_ref = LibidReference.create(libid_ref_bytes) + return ReferenceRegistered("", libid_ref) From 431bb7fbcfbac418e3a478901140b3f2c4c807ff Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 11:03:31 -0500 Subject: [PATCH 214/335] Update reference_registered.py --- src/ms_ovba/Models/Entities/reference_registered.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference_registered.py b/src/ms_ovba/Models/Entities/reference_registered.py index 853dea2af..8a6178ec8 100644 --- a/src/ms_ovba/Models/Entities/reference_registered.py +++ b/src/ms_ovba/Models/Entities/reference_registered.py @@ -42,7 +42,7 @@ def unpack(data: bytes) -> T: start = end end = end + 4 recordsize = bytes[start:end] - if len(data) !== recordsize + 6: + if len(data) != recordsize + 6: # raise a warning start = end @@ -54,13 +54,13 @@ def unpack(data: bytes) -> T: start = end end = end + 4 reserved1 = bytes[start:end] - if reserved1 !== 0: + if reserved1 != 0: # raise a warning start = end end = end + 2 reserved2 = bytes[start:end] - if reserved2 !== 0: + if reserved2 != 0: # raise a warning libid_ref = LibidReference.create(libid_ref_bytes) From 81196309774d7bd01a05576ddfdff69f7d9d4fa8 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 11:04:24 -0500 Subject: [PATCH 215/335] Update reference_registered.py --- src/ms_ovba/Models/Entities/reference_registered.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Entities/reference_registered.py b/src/ms_ovba/Models/Entities/reference_registered.py index 8a6178ec8..c8a717ebf 100644 --- a/src/ms_ovba/Models/Entities/reference_registered.py +++ b/src/ms_ovba/Models/Entities/reference_registered.py @@ -36,7 +36,7 @@ def unpack(data: bytes) -> T: start = 0 end = 2 id = bytes[start:end] - if id !== 0x000D: + if id != 0x000D: raise ValueError("Incorrect id in data.") start = end From 5a24efbaf88983982af5671bf41778ac960fe4e7 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 11:08:41 -0500 Subject: [PATCH 216/335] Update reference_registered.py --- src/ms_ovba/Models/Entities/reference_registered.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference_registered.py b/src/ms_ovba/Models/Entities/reference_registered.py index c8a717ebf..f3d82410f 100644 --- a/src/ms_ovba/Models/Entities/reference_registered.py +++ b/src/ms_ovba/Models/Entities/reference_registered.py @@ -42,8 +42,8 @@ def unpack(data: bytes) -> T: start = end end = end + 4 recordsize = bytes[start:end] - if len(data) != recordsize + 6: - # raise a warning + # if len(data) != recordsize + 6: + # raise a warning start = end end = end + 4 @@ -54,14 +54,14 @@ def unpack(data: bytes) -> T: start = end end = end + 4 reserved1 = bytes[start:end] - if reserved1 != 0: - # raise a warning + # if reserved1 != 0: + # raise a warning start = end end = end + 2 reserved2 = bytes[start:end] - if reserved2 != 0: - # raise a warning + # if reserved2 != 0: + # raise a warning libid_ref = LibidReference.create(libid_ref_bytes) return ReferenceRegistered("", libid_ref) From af71926060d38db797ecc3fa7c25c579708a5d42 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 11:10:34 -0500 Subject: [PATCH 217/335] Update reference_registered.py --- src/ms_ovba/Models/Entities/reference_registered.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference_registered.py b/src/ms_ovba/Models/Entities/reference_registered.py index f3d82410f..86a88a65a 100644 --- a/src/ms_ovba/Models/Entities/reference_registered.py +++ b/src/ms_ovba/Models/Entities/reference_registered.py @@ -41,25 +41,27 @@ def unpack(data: bytes) -> T: start = end end = end + 4 - recordsize = bytes[start:end] + # recordsize = bytes[start:end] # if len(data) != recordsize + 6: # raise a warning start = end end = end + 4 libidsize = bytes[start:end] + start = end end = end + libidsize libid_ref_bytes = bytes[start:end] + start = end end = end + 4 - reserved1 = bytes[start:end] + # reserved1 = bytes[start:end] # if reserved1 != 0: # raise a warning start = end end = end + 2 - reserved2 = bytes[start:end] + # reserved2 = bytes[start:end] # if reserved2 != 0: # raise a warning From 2e0e7736eb39164d2905fe5e0a82a160a336273b Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 11:11:46 -0500 Subject: [PATCH 218/335] Update reference_registered.py --- src/ms_ovba/Models/Entities/reference_registered.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference_registered.py b/src/ms_ovba/Models/Entities/reference_registered.py index 86a88a65a..89041d0c4 100644 --- a/src/ms_ovba/Models/Entities/reference_registered.py +++ b/src/ms_ovba/Models/Entities/reference_registered.py @@ -64,7 +64,6 @@ def unpack(data: bytes) -> T: # reserved2 = bytes[start:end] # if reserved2 != 0: # raise a warning - + libid_ref = LibidReference.create(libid_ref_bytes) return ReferenceRegistered("", libid_ref) - From e7d1a3f05a11588d18c054cbf5ac53dcc0446e6d Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 11:15:48 -0500 Subject: [PATCH 219/335] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4f8085824..a22fcc907 100644 --- a/README.md +++ b/README.md @@ -28,13 +28,13 @@ The VbaProject class has many layers of customization available. For example a l ```python codePage = 0x04E4 codePageName = "cp" + str(codePage) -libidRef = LibidReference( +libidRef = ReferenceRecord(codePageName, LibidReference( "{00020430-0000-0000-C000-000000000046}", "2.0", "0", "C:\\Windows\\System32\\stdole2.tlb", "OLE Automation" -) -oleReference = ReferenceRecord(codePageName, "stdole", libidRef) +)) +oleReference = Reference(codePageName, libidRef, "stdole") project.addReference(oleReference) ``` From 444c787dec01f3ba307a77f4a36e5df0c5d1487f Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 11:26:36 -0500 Subject: [PATCH 220/335] Update README.md --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a22fcc907..45f9443eb 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Create a vbaProject.bin file from VBA source files. Eventually it will be possible to use the CLI to create a vbaProject.bin file from source files and an optional configuration file. ## VBAProject Class -The vbaProject class contains all the data and metadata that is used to create the OLE container. +The vbaProject class contains all the data and metadata that is used to create the OLE container. It can use this data to create several files, then compress and combine them into an OLE container ```python from ms_ovba.vbaProject import VbaProject @@ -19,8 +19,7 @@ thisWorkbook = DocModule("ThisWorkbook") thisWorkbook.addFile(path) project.addModule(thisWorkbook) -ole_file = OleFile(project) -ole_file.create_file(".") +ProjectOleFile.write_file(project) ``` The VbaProject class has many layers of customization available. For example a library reference can be added to the project. From 05819fc6a08743f71828b65a6291ed334083a2b8 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 12:44:48 -0500 Subject: [PATCH 221/335] Create test_reference_project.py --- tests/Unit/Models/Entities/test_reference_project.py | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 tests/Unit/Models/Entities/test_reference_project.py diff --git a/tests/Unit/Models/Entities/test_reference_project.py b/tests/Unit/Models/Entities/test_reference_project.py new file mode 100644 index 000000000..ea5f895cb --- /dev/null +++ b/tests/Unit/Models/Entities/test_reference_project.py @@ -0,0 +1,9 @@ +from ms_ovba.Models.Entities.reference_project import ReferenceProject +from ms_ovba.Models.Fields.project_reference import ProjectReference + + +def test_constructor() -> None: + ref = ProjectReference("") + module = ReferenceProject("cp1", ref) + + assert isinstance(module, ReferenceProject) From 06509df3fa93fafd8f478e8173db0d49a0a57bb5 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 12:45:54 -0500 Subject: [PATCH 222/335] Update reference_registered.py --- .../Models/Entities/reference_registered.py | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference_registered.py b/src/ms_ovba/Models/Entities/reference_registered.py index 89041d0c4..7f6fd2afa 100644 --- a/src/ms_ovba/Models/Entities/reference_registered.py +++ b/src/ms_ovba/Models/Entities/reference_registered.py @@ -41,9 +41,10 @@ def unpack(data: bytes) -> T: start = end end = end + 4 - # recordsize = bytes[start:end] - # if len(data) != recordsize + 6: - # raise a warning + recordsize = bytes[start:end] + if len(data) != recordsize + 6: + # raise a warning + pass start = end end = end + 4 @@ -55,15 +56,17 @@ def unpack(data: bytes) -> T: start = end end = end + 4 - # reserved1 = bytes[start:end] - # if reserved1 != 0: - # raise a warning + reserved1 = bytes[start:end] + if reserved1 != 0: + # raise a warning + pass start = end end = end + 2 - # reserved2 = bytes[start:end] - # if reserved2 != 0: - # raise a warning + reserved2 = bytes[start:end] + if reserved2 != 0: + # raise a warning + pass libid_ref = LibidReference.create(libid_ref_bytes) return ReferenceRegistered("", libid_ref) From 7883a201c8903e960293d701f6522c71ebcd0dd4 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 12:55:54 -0500 Subject: [PATCH 223/335] Update test_reference_project.py --- tests/Unit/Models/Entities/test_reference_project.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_reference_project.py b/tests/Unit/Models/Entities/test_reference_project.py index ea5f895cb..21339652e 100644 --- a/tests/Unit/Models/Entities/test_reference_project.py +++ b/tests/Unit/Models/Entities/test_reference_project.py @@ -3,7 +3,17 @@ def test_constructor() -> None: - ref = ProjectReference("") + ref = ProjectReference("C:/") module = ReferenceProject("cp1", ref) assert isinstance(module, ReferenceProject) + +def test_pack() -> None: + ref = ProjectReference("") + + expected = b'000E00180003673A2F00012E65BE02570017' + codepage = 0x04E4 + codepage_name = "cp" + str(codepage) + module = ReferenceProject(codepage_name, ref) + results = module.pack(codepage_name, 'little') + assert results == expected From 1fc029b8ab9e01709960cc4b8209fd2e53340043 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 13:04:10 -0500 Subject: [PATCH 224/335] Update project_reference.py --- src/ms_ovba/Models/Fields/project_reference.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ms_ovba/Models/Fields/project_reference.py b/src/ms_ovba/Models/Fields/project_reference.py index 05576e1e1..b005d2f66 100644 --- a/src/ms_ovba/Models/Fields/project_reference.py +++ b/src/ms_ovba/Models/Fields/project_reference.py @@ -14,28 +14,28 @@ class ProjectReference(): ProjectPath = *(%x01-FF} """ def __init__(self: T, project_path: str, embedded: bool = True) -> None: - self.project_path = project_path - self.embedded = embedded + self._project_path = project_path + self._embedded = embedded def __str__(self) -> str: return self._header() + \ - str(self.project_path) + str(self._project_path) def __len__(self) -> int: return len(str(self)) def _header(self: T) -> str: project_kind = 0x41 - if not self._is_windows_path(self.project_path): + if not self._is_windows_path(self._project_path): project_kind += 2 - if self.embedded: + if self._embedded: project_kind += 1 return "*\\" + \ - chr(self.project_kind) + chr(project_kind) def relative_to(self: T, path: str) -> str: """ Return the path relative to another path. """ return self._header() + \ - str(self.project_path) + str(self._project_path) From 772fae5df602b98be76f1bdc672541e812f9f3ef Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 13:15:02 -0500 Subject: [PATCH 225/335] Create test_project_reference.py --- .../Models/Fields/test_project_reference.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 tests/Unit/Models/Fields/test_project_reference.py diff --git a/tests/Unit/Models/Fields/test_project_reference.py b/tests/Unit/Models/Fields/test_project_reference.py new file mode 100644 index 000000000..6c4aa5ad2 --- /dev/null +++ b/tests/Unit/Models/Fields/test_project_reference.py @@ -0,0 +1,18 @@ +from ms_ovba.Models.Fields.project_reference import ProjectReference + + +def test_constructor() -> None: + ref = ProjectReference("C:\Example Path\Example-ReferencedProject.xls") + assert isinstance(module, ReferenceProject) + +def test_constructor() -> None: + ref = ProjectReference("C:/", False) + assert isinstance(module, ReferenceProject) + +def test_len() -> None: + ref = ProjectReference("C:\Example Path\Example-ReferencedProject.xls") + assert len(ref) == 48 + +def test_str() -> None: + ref = ProjectReference("C:\Example Path\Example-ReferencedProject.xls") + assert str(ref) == "*\CC:\Example Path\Example-ReferencedProject.xls" From 8382e7562c885558b1c750ae628c48d8bec04a3e Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 13:36:43 -0500 Subject: [PATCH 226/335] Update test_reference_project.py --- tests/Unit/Models/Entities/test_reference_project.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/Unit/Models/Entities/test_reference_project.py b/tests/Unit/Models/Entities/test_reference_project.py index 21339652e..77a0c15f7 100644 --- a/tests/Unit/Models/Entities/test_reference_project.py +++ b/tests/Unit/Models/Entities/test_reference_project.py @@ -10,8 +10,16 @@ def test_constructor() -> None: def test_pack() -> None: ref = ProjectReference("") - - expected = b'000E00180003673A2F00012E65BE02570017' + + module_cache.indirect_table = bytes.fromhex(" ".join(indirect_table)) + expected_hex = ("00 0E 00 00 00 5E 00 00 00 30 2A 5C 43 43 3A 5C", + "45 78 61 6D 70 6C 65 20 50 61 74 68 5C 45 78 61", + "6D 70 6C 65 2D 52 65 66 65 72 65 6E 63 65 64 50", + "72 6F 6A 65 63 74 2E 78 6C 73 00 00 00 20 2A 5C", + "43 45 78 61 6D 70 6C 65 2D 52 65 66 65 72 65 6E", + "63 65 64 50 72 6F 6A 65 63 74 2E 78 6C 73 49 A9", + "5F 46 00 0D") + expected = bytes.fromhex(" ".join(expected_hex)) codepage = 0x04E4 codepage_name = "cp" + str(codepage) module = ReferenceProject(codepage_name, ref) From 65b6d7a39c7acb7081d96e27e979a00bf92a9200 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 13:38:57 -0500 Subject: [PATCH 227/335] Update project_reference.py --- src/ms_ovba/Models/Fields/project_reference.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ms_ovba/Models/Fields/project_reference.py b/src/ms_ovba/Models/Fields/project_reference.py index b005d2f66..ef9419a74 100644 --- a/src/ms_ovba/Models/Fields/project_reference.py +++ b/src/ms_ovba/Models/Fields/project_reference.py @@ -27,9 +27,9 @@ def __len__(self) -> int: def _header(self: T) -> str: project_kind = 0x41 if not self._is_windows_path(self._project_path): - project_kind += 2 - if self._embedded: project_kind += 1 + if self._embedded: + project_kind += 2 return "*\\" + \ chr(project_kind) From b170ab0edd5bb7457581924547839ad86695d2a0 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 13:40:36 -0500 Subject: [PATCH 228/335] Update project_reference.py --- src/ms_ovba/Models/Fields/project_reference.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/ms_ovba/Models/Fields/project_reference.py b/src/ms_ovba/Models/Fields/project_reference.py index ef9419a74..c6c989d66 100644 --- a/src/ms_ovba/Models/Fields/project_reference.py +++ b/src/ms_ovba/Models/Fields/project_reference.py @@ -17,6 +17,7 @@ def __init__(self: T, project_path: str, embedded: bool = True) -> None: self._project_path = project_path self._embedded = embedded + # Dunder Methods def __str__(self) -> str: return self._header() + \ str(self._project_path) @@ -24,6 +25,13 @@ def __str__(self) -> str: def __len__(self) -> int: return len(str(self)) + def relative_to(self: T, path: str) -> str: + """ + Return the path relative to another path. + """ + return self._header() + \ + str(self._project_path) + def _header(self: T) -> str: project_kind = 0x41 if not self._is_windows_path(self._project_path): @@ -32,10 +40,6 @@ def _header(self: T) -> str: project_kind += 2 return "*\\" + \ chr(project_kind) - - def relative_to(self: T, path: str) -> str: - """ - Return the path relative to another path. - """ - return self._header() + \ - str(self._project_path) + + def _is_windows_path(self: T, path: str) -> bool: + return path[0] != '/' From 982e64e8c7935edac8d361c04a1ab920168b1b7e Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 13:44:08 -0500 Subject: [PATCH 229/335] Update project_reference.py --- src/ms_ovba/Models/Fields/project_reference.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ms_ovba/Models/Fields/project_reference.py b/src/ms_ovba/Models/Fields/project_reference.py index c6c989d66..825d9e162 100644 --- a/src/ms_ovba/Models/Fields/project_reference.py +++ b/src/ms_ovba/Models/Fields/project_reference.py @@ -25,12 +25,12 @@ def __str__(self) -> str: def __len__(self) -> int: return len(str(self)) - def relative_to(self: T, path: str) -> str: + def relative(self: T) -> T: """ - Return the path relative to another path. + Strip off the path and just return the file. """ - return self._header() + \ - str(self._project_path) + rel_path = self._project_path + return ProjectReference(rel_path, self._embedded) def _header(self: T) -> str: project_kind = 0x41 From f669b726df1cdd08cab564b8921f94973aca01b8 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 13:46:41 -0500 Subject: [PATCH 230/335] Update project_reference.py --- src/ms_ovba/Models/Fields/project_reference.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Fields/project_reference.py b/src/ms_ovba/Models/Fields/project_reference.py index 825d9e162..1f50bb893 100644 --- a/src/ms_ovba/Models/Fields/project_reference.py +++ b/src/ms_ovba/Models/Fields/project_reference.py @@ -29,7 +29,10 @@ def relative(self: T) -> T: """ Strip off the path and just return the file. """ - rel_path = self._project_path + # Find last '\' + pos = self._project_path.rfind('\') + + rel_path = self._project_path[pos + 1:] return ProjectReference(rel_path, self._embedded) def _header(self: T) -> str: From 9dfc4b65ef5d8dc4a1400f9a85a4317e2efadfd4 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 13:52:37 -0500 Subject: [PATCH 231/335] Update project_reference.py --- src/ms_ovba/Models/Fields/project_reference.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Fields/project_reference.py b/src/ms_ovba/Models/Fields/project_reference.py index 1f50bb893..396106fae 100644 --- a/src/ms_ovba/Models/Fields/project_reference.py +++ b/src/ms_ovba/Models/Fields/project_reference.py @@ -30,7 +30,7 @@ def relative(self: T) -> T: Strip off the path and just return the file. """ # Find last '\' - pos = self._project_path.rfind('\') + pos = self._project_path.rfind('\\') rel_path = self._project_path[pos + 1:] return ProjectReference(rel_path, self._embedded) From af43a4af1682f8dddbc185203a147c7004a0b1a9 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 13:53:17 -0500 Subject: [PATCH 232/335] Update test_project_reference.py --- tests/Unit/Models/Fields/test_project_reference.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/Unit/Models/Fields/test_project_reference.py b/tests/Unit/Models/Fields/test_project_reference.py index 6c4aa5ad2..7e740f012 100644 --- a/tests/Unit/Models/Fields/test_project_reference.py +++ b/tests/Unit/Models/Fields/test_project_reference.py @@ -2,17 +2,17 @@ def test_constructor() -> None: - ref = ProjectReference("C:\Example Path\Example-ReferencedProject.xls") + ref = ProjectReference("C:\\Example Path\\Example-ReferencedProject.xls") assert isinstance(module, ReferenceProject) def test_constructor() -> None: - ref = ProjectReference("C:/", False) + ref = ProjectReference("C:\\", False) assert isinstance(module, ReferenceProject) def test_len() -> None: - ref = ProjectReference("C:\Example Path\Example-ReferencedProject.xls") + ref = ProjectReference("C:\\Example Path\\Example-ReferencedProject.xls") assert len(ref) == 48 def test_str() -> None: - ref = ProjectReference("C:\Example Path\Example-ReferencedProject.xls") - assert str(ref) == "*\CC:\Example Path\Example-ReferencedProject.xls" + ref = ProjectReference("C:\\Example Path\\Example-ReferencedProject.xls") + assert str(ref) == "*\\CC:\\Example Path\\Example-ReferencedProject.xls" From 03ebaa715fb63703a995cf0009fa0f7bf7902f38 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 13:54:25 -0500 Subject: [PATCH 233/335] Update test_project_reference.py --- tests/Unit/Models/Fields/test_project_reference.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/Unit/Models/Fields/test_project_reference.py b/tests/Unit/Models/Fields/test_project_reference.py index 7e740f012..eab11c137 100644 --- a/tests/Unit/Models/Fields/test_project_reference.py +++ b/tests/Unit/Models/Fields/test_project_reference.py @@ -5,14 +5,17 @@ def test_constructor() -> None: ref = ProjectReference("C:\\Example Path\\Example-ReferencedProject.xls") assert isinstance(module, ReferenceProject) + def test_constructor() -> None: ref = ProjectReference("C:\\", False) assert isinstance(module, ReferenceProject) + def test_len() -> None: ref = ProjectReference("C:\\Example Path\\Example-ReferencedProject.xls") assert len(ref) == 48 + def test_str() -> None: ref = ProjectReference("C:\\Example Path\\Example-ReferencedProject.xls") assert str(ref) == "*\\CC:\\Example Path\\Example-ReferencedProject.xls" From f102eb8684a5ba275531a7346194b1ca66577590 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 13:55:22 -0500 Subject: [PATCH 234/335] Update test_project_reference.py --- tests/Unit/Models/Fields/test_project_reference.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Fields/test_project_reference.py b/tests/Unit/Models/Fields/test_project_reference.py index eab11c137..5ac769d54 100644 --- a/tests/Unit/Models/Fields/test_project_reference.py +++ b/tests/Unit/Models/Fields/test_project_reference.py @@ -3,7 +3,7 @@ def test_constructor() -> None: ref = ProjectReference("C:\\Example Path\\Example-ReferencedProject.xls") - assert isinstance(module, ReferenceProject) + assert isinstance(ref, ReferenceProject) def test_constructor() -> None: From 7d458d6e101d6e37bf353ea13d5aa08036db511c Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 13:55:40 -0500 Subject: [PATCH 235/335] Update test_project_reference.py --- tests/Unit/Models/Fields/test_project_reference.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Fields/test_project_reference.py b/tests/Unit/Models/Fields/test_project_reference.py index 5ac769d54..5843ed971 100644 --- a/tests/Unit/Models/Fields/test_project_reference.py +++ b/tests/Unit/Models/Fields/test_project_reference.py @@ -7,7 +7,7 @@ def test_constructor() -> None: def test_constructor() -> None: - ref = ProjectReference("C:\\", False) + ref = ProjectReference("C:\\Example Path\\Example-ReferencedProject.xls", False) assert isinstance(module, ReferenceProject) From 5e0b76b6d62e565d0f0311cba8bfbdc352d57afe Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 13:57:47 -0500 Subject: [PATCH 236/335] Update test_project_reference.py --- tests/Unit/Models/Fields/test_project_reference.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/Unit/Models/Fields/test_project_reference.py b/tests/Unit/Models/Fields/test_project_reference.py index 5843ed971..578ba5ade 100644 --- a/tests/Unit/Models/Fields/test_project_reference.py +++ b/tests/Unit/Models/Fields/test_project_reference.py @@ -1,14 +1,15 @@ from ms_ovba.Models.Fields.project_reference import ProjectReference -def test_constructor() -> None: +def test_constructor1() -> None: ref = ProjectReference("C:\\Example Path\\Example-ReferencedProject.xls") - assert isinstance(ref, ReferenceProject) + assert isinstance(ref, ProjectReference) -def test_constructor() -> None: - ref = ProjectReference("C:\\Example Path\\Example-ReferencedProject.xls", False) - assert isinstance(module, ReferenceProject) +def test_constructor2() -> None: + path = "C:\\Example Path\\Example-ReferencedProject.xls" + ref = ProjectReference(path, False) + assert isinstance(ref, ProjectReference) def test_len() -> None: From 0abf185fa6ecd6af8fe8b583401b12a3dcc97e96 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 13:59:13 -0500 Subject: [PATCH 237/335] Update project_reference.py --- src/ms_ovba/Models/Fields/project_reference.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ms_ovba/Models/Fields/project_reference.py b/src/ms_ovba/Models/Fields/project_reference.py index 396106fae..436677afb 100644 --- a/src/ms_ovba/Models/Fields/project_reference.py +++ b/src/ms_ovba/Models/Fields/project_reference.py @@ -31,7 +31,7 @@ def relative(self: T) -> T: """ # Find last '\' pos = self._project_path.rfind('\\') - + rel_path = self._project_path[pos + 1:] return ProjectReference(rel_path, self._embedded) @@ -43,6 +43,6 @@ def _header(self: T) -> str: project_kind += 2 return "*\\" + \ chr(project_kind) - + def _is_windows_path(self: T, path: str) -> bool: return path[0] != '/' From 4c78366d10a5d09ae1188f732f11bccef11e531b Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 14:00:39 -0500 Subject: [PATCH 238/335] Update test_reference_project.py --- tests/Unit/Models/Entities/test_reference_project.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Unit/Models/Entities/test_reference_project.py b/tests/Unit/Models/Entities/test_reference_project.py index 77a0c15f7..9fe510b0c 100644 --- a/tests/Unit/Models/Entities/test_reference_project.py +++ b/tests/Unit/Models/Entities/test_reference_project.py @@ -3,15 +3,15 @@ def test_constructor() -> None: - ref = ProjectReference("C:/") + ref = ProjectReference("C:\\Example Path\\Example-ReferencedProject.xls") module = ReferenceProject("cp1", ref) assert isinstance(module, ReferenceProject) + def test_pack() -> None: - ref = ProjectReference("") + ref = ProjectReference("C:\\Example Path\\Example-ReferencedProject.xls") - module_cache.indirect_table = bytes.fromhex(" ".join(indirect_table)) expected_hex = ("00 0E 00 00 00 5E 00 00 00 30 2A 5C 43 43 3A 5C", "45 78 61 6D 70 6C 65 20 50 61 74 68 5C 45 78 61", "6D 70 6C 65 2D 52 65 66 65 72 65 6E 63 65 64 50", From 4aa664c27e87f0e08e3b3f239688f19727accd86 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 14:03:21 -0500 Subject: [PATCH 239/335] Update reference_project.py --- src/ms_ovba/Models/Entities/reference_project.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference_project.py b/src/ms_ovba/Models/Entities/reference_project.py index c7c039757..46200a701 100644 --- a/src/ms_ovba/Models/Entities/reference_project.py +++ b/src/ms_ovba/Models/Entities/reference_project.py @@ -15,14 +15,14 @@ def __init__(self: T, codepage_name: str, self._codepage_name = codepage_name self._ref = ref - def pack(self: T, codepage_name: str, endien: str) -> bytes: - cp_name = self._codepage_name + def pack(self: T, cp_name: str, endien: str) -> bytes: + lib_rel = self._ref.relative() libid_abs_size = len(self._ref) - libid_rel_size = len(self._ref.relative_to("")) + libid_rel_size = len(lib_rel) format = ("HII" + str(libid_abs_size) + "sI" + str(libid_rel_size) + "sIH") ref_str = str(self._ref).encode(cp_name) - ref_str_rel = str(self._ref.relative_to("")).encode(cp_name) + ref_str_rel = str(lib_rel).encode(cp_name) ref_project = PackedData(format, 0x000E, libid_abs_size + libid_rel_size + 20, libid_abs_size, ref_str, libid_rel_size, From 148d4c7e07b609e6cb9602b6acf08610ccb7338e Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 14:07:10 -0500 Subject: [PATCH 240/335] Update test_reference_project.py --- tests/Unit/Models/Entities/test_reference_project.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Unit/Models/Entities/test_reference_project.py b/tests/Unit/Models/Entities/test_reference_project.py index 9fe510b0c..498b96885 100644 --- a/tests/Unit/Models/Entities/test_reference_project.py +++ b/tests/Unit/Models/Entities/test_reference_project.py @@ -22,6 +22,6 @@ def test_pack() -> None: expected = bytes.fromhex(" ".join(expected_hex)) codepage = 0x04E4 codepage_name = "cp" + str(codepage) - module = ReferenceProject(codepage_name, ref) - results = module.pack(codepage_name, 'little') + ref_proj = ReferenceProject(codepage_name, ref) + results = ref_proj.pack(codepage_name, 'little') assert results == expected From 1cb71972ccb4496392f6ace8487496e18b1aff26 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 14:12:05 -0500 Subject: [PATCH 241/335] Update test_reference_project.py --- tests/Unit/Models/Entities/test_reference_project.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_reference_project.py b/tests/Unit/Models/Entities/test_reference_project.py index 498b96885..839d9e64c 100644 --- a/tests/Unit/Models/Entities/test_reference_project.py +++ b/tests/Unit/Models/Entities/test_reference_project.py @@ -12,7 +12,7 @@ def test_constructor() -> None: def test_pack() -> None: ref = ProjectReference("C:\\Example Path\\Example-ReferencedProject.xls") - expected_hex = ("00 0E 00 00 00 5E 00 00 00 30 2A 5C 43 43 3A 5C", + expected_hex = ("0E 00 5E 00 00 00 30 00 00 00 2A 5C 43 43 3A 5C", "45 78 61 6D 70 6C 65 20 50 61 74 68 5C 45 78 61", "6D 70 6C 65 2D 52 65 66 65 72 65 6E 63 65 64 50", "72 6F 6A 65 63 74 2E 78 6C 73 00 00 00 20 2A 5C", From 56d30fb950a5a3b5f2e0b667e2b1594836d244a4 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 14:17:32 -0500 Subject: [PATCH 242/335] Update test_reference_project.py --- tests/Unit/Models/Entities/test_reference_project.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_reference_project.py b/tests/Unit/Models/Entities/test_reference_project.py index 839d9e64c..ce0638a93 100644 --- a/tests/Unit/Models/Entities/test_reference_project.py +++ b/tests/Unit/Models/Entities/test_reference_project.py @@ -15,7 +15,7 @@ def test_pack() -> None: expected_hex = ("0E 00 5E 00 00 00 30 00 00 00 2A 5C 43 43 3A 5C", "45 78 61 6D 70 6C 65 20 50 61 74 68 5C 45 78 61", "6D 70 6C 65 2D 52 65 66 65 72 65 6E 63 65 64 50", - "72 6F 6A 65 63 74 2E 78 6C 73 00 00 00 20 2A 5C", + "72 6F 6A 65 63 74 2E 78 6C 73 20 00 00 00 2A 5C", "43 45 78 61 6D 70 6C 65 2D 52 65 66 65 72 65 6E", "63 65 64 50 72 6F 6A 65 63 74 2E 78 6C 73 49 A9", "5F 46 00 0D") From fda3d2b04122311f3b2b7d34d0ac76e638e1852b Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 14:19:25 -0500 Subject: [PATCH 243/335] Update test_reference_project.py --- tests/Unit/Models/Entities/test_reference_project.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_reference_project.py b/tests/Unit/Models/Entities/test_reference_project.py index ce0638a93..1efaf4ea5 100644 --- a/tests/Unit/Models/Entities/test_reference_project.py +++ b/tests/Unit/Models/Entities/test_reference_project.py @@ -18,7 +18,7 @@ def test_pack() -> None: "72 6F 6A 65 63 74 2E 78 6C 73 20 00 00 00 2A 5C", "43 45 78 61 6D 70 6C 65 2D 52 65 66 65 72 65 6E", "63 65 64 50 72 6F 6A 65 63 74 2E 78 6C 73 49 A9", - "5F 46 00 0D") + "5F 46 17 00") expected = bytes.fromhex(" ".join(expected_hex)) codepage = 0x04E4 codepage_name = "cp" + str(codepage) From c7fa8cff0292a5f15957f7a2ea6aca4bf4ec5892 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 14:20:58 -0500 Subject: [PATCH 244/335] Update test_reference_project.py --- tests/Unit/Models/Entities/test_reference_project.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Unit/Models/Entities/test_reference_project.py b/tests/Unit/Models/Entities/test_reference_project.py index 1efaf4ea5..ee5c29d58 100644 --- a/tests/Unit/Models/Entities/test_reference_project.py +++ b/tests/Unit/Models/Entities/test_reference_project.py @@ -17,8 +17,8 @@ def test_pack() -> None: "6D 70 6C 65 2D 52 65 66 65 72 65 6E 63 65 64 50", "72 6F 6A 65 63 74 2E 78 6C 73 20 00 00 00 2A 5C", "43 45 78 61 6D 70 6C 65 2D 52 65 66 65 72 65 6E", - "63 65 64 50 72 6F 6A 65 63 74 2E 78 6C 73 49 A9", - "5F 46 17 00") + "63 65 64 50 72 6F 6A 65 63 74 2E 78 6C 73 57 02", + "BE 65 17 00") expected = bytes.fromhex(" ".join(expected_hex)) codepage = 0x04E4 codepage_name = "cp" + str(codepage) From d107251fd67f483adba293600e84cfcbf339c40a Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 14:25:29 -0500 Subject: [PATCH 245/335] Update reference_project.py --- src/ms_ovba/Models/Entities/reference_project.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Entities/reference_project.py b/src/ms_ovba/Models/Entities/reference_project.py index 46200a701..b3ab85458 100644 --- a/src/ms_ovba/Models/Entities/reference_project.py +++ b/src/ms_ovba/Models/Entities/reference_project.py @@ -24,7 +24,7 @@ def pack(self: T, cp_name: str, endien: str) -> bytes: ref_str = str(self._ref).encode(cp_name) ref_str_rel = str(lib_rel).encode(cp_name) ref_project = PackedData(format, 0x000E, - libid_abs_size + libid_rel_size + 20, + libid_abs_size + libid_rel_size + 14, libid_abs_size, ref_str, libid_rel_size, ref_str_rel, 0x65BE0257, 0x0017) From 7aacc9dcecc47d805d329891d4ab520154fea549 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 14:37:38 -0500 Subject: [PATCH 246/335] Create test_reference_registered.py --- .../Entities/test_reference_registered.py | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 tests/Unit/Models/Entities/test_reference_registered.py diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py new file mode 100644 index 000000000..e2b4ac0d2 --- /dev/null +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -0,0 +1,42 @@ +import uuid +from ms_ovba.Models.Entities.reference_registered import ReferenceRegistered +from ms_ovba.Models.Fields.libid_reference import LibidReference + + +def test_constructor() -> None: + guid = uuid.UUID('0002043000000000C000000000000046') + ref = ref = LibidReference( + guid, + "2.0", + "0", + "C:\\Windows\\System32\\stdole2.tlb", + "OLE Automation" + ) + module = ReferenceProject("cp1", ref) + assert isinstance(module, ReferenceRegistered) + + +def test_pack() -> None: + guid = uuid.UUID('0002043000000000C000000000000046') + ref = ref = LibidReference( + guid, + "2.0", + "0", + "C:\\Windows\\System32\\stdole2.tlb", + "OLE Automation" + ) + + expected_hex = ("0D 00 68 00 00 00 5E 00 00 00 2A 5C 00 00 00 00", + "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", + "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", + "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", + "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", + "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", + "00 00 00 00 00 00 00 00 00 00 00 00 00 00", + ) + expected = bytes.fromhex(" ".join(expected_hex)) + codepage = 0x04E4 + codepage_name = "cp" + str(codepage) + ref_reg = ReferenceRegistered(codepage_name, ref) + results = ref_reg.pack(codepage_name, 'little') + assert results == expected From 7a0827fbedf1a5b6964d745bdec8408d26ab41dd Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 14:39:55 -0500 Subject: [PATCH 247/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index e2b4ac0d2..4fa7df54d 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -12,7 +12,7 @@ def test_constructor() -> None: "C:\\Windows\\System32\\stdole2.tlb", "OLE Automation" ) - module = ReferenceProject("cp1", ref) + module = ReferenceRegistered("cp1", ref) assert isinstance(module, ReferenceRegistered) @@ -32,8 +32,7 @@ def test_pack() -> None: "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", - "00 00 00 00 00 00 00 00 00 00 00 00 00 00", - ) + "00 00 00 00 00 00 00 00 00 00 00 00 00 00") expected = bytes.fromhex(" ".join(expected_hex)) codepage = 0x04E4 codepage_name = "cp" + str(codepage) From 144607c819e26a48f5f116ee078347a853c27a80 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 14:45:23 -0500 Subject: [PATCH 248/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index 4fa7df54d..45401c318 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -26,9 +26,9 @@ def test_pack() -> None: "OLE Automation" ) - expected_hex = ("0D 00 68 00 00 00 5E 00 00 00 2A 5C 00 00 00 00", - "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", - "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", + expected_hex = ("0D 00 68 00 00 00 5E 00 00 00 2A 5C 47 7B 30 30", + "30 32 30 34 33 30 2D 30 30 30 30 2D 30 30 30 30", + "2D 43 30 30 30 2D 30 30 30 30 30 30 30 30 30 30", "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", From 9c939da82f7c2c4135740c3cb42fd290a5c049f4 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 14:48:30 -0500 Subject: [PATCH 249/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index 45401c318..a260dedb3 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -29,7 +29,7 @@ def test_pack() -> None: expected_hex = ("0D 00 68 00 00 00 5E 00 00 00 2A 5C 47 7B 30 30", "30 32 30 34 33 30 2D 30 30 30 30 2D 30 30 30 30", "2D 43 30 30 30 2D 30 30 30 30 30 30 30 30 30 30", - "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", + "34 36 7D 23 32 2E 30 23 30 23 43 3A 5C 00 00 00", "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", "00 00 00 00 00 00 00 00 00 00 00 00 00 00") From 31e6ff11c1ee3a57484dd88ef4d2534efb645abc Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 14:52:39 -0500 Subject: [PATCH 250/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index a260dedb3..0da613780 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -31,8 +31,8 @@ def test_pack() -> None: "2D 43 30 30 30 2D 30 30 30 30 30 30 30 30 30 30", "34 36 7D 23 32 2E 30 23 30 23 43 3A 5C 00 00 00", "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", - "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", - "00 00 00 00 00 00 00 00 00 00 00 00 00 00") + "00 00 00 00 00 00 00 00 00 23 4F 4C 45 20 41 75", + "74 6F 6D 61 74 69 6F 6E 00 00 00 00 00 00") expected = bytes.fromhex(" ".join(expected_hex)) codepage = 0x04E4 codepage_name = "cp" + str(codepage) From d6c649fb9c8e8756a57adb93efa02ee031c4fd8a Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 14:57:41 -0500 Subject: [PATCH 251/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index 0da613780..46508ee47 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -29,9 +29,9 @@ def test_pack() -> None: expected_hex = ("0D 00 68 00 00 00 5E 00 00 00 2A 5C 47 7B 30 30", "30 32 30 34 33 30 2D 30 30 30 30 2D 30 30 30 30", "2D 43 30 30 30 2D 30 30 30 30 30 30 30 30 30 30", - "34 36 7D 23 32 2E 30 23 30 23 43 3A 5C 00 00 00", - "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", - "00 00 00 00 00 00 00 00 00 23 4F 4C 45 20 41 75", + "34 36 7D 23 32 2E 30 23 30 23 43 3A 5C 57 69 6E", + "64 6F 77 73 5C 73 79 73 74 65 6D 33 32 5C 73 74", + "64 6F 6C 65 32 2E 74 6C 62 23 4F 4C 45 20 41 75", "74 6F 6D 61 74 69 6F 6E 00 00 00 00 00 00") expected = bytes.fromhex(" ".join(expected_hex)) codepage = 0x04E4 From c05294f192f5f1a8aebbb53e2ba07d6ec72b741c Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 14:58:29 -0500 Subject: [PATCH 252/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index 46508ee47..1daab17c7 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -5,7 +5,7 @@ def test_constructor() -> None: guid = uuid.UUID('0002043000000000C000000000000046') - ref = ref = LibidReference( + ref = LibidReference( guid, "2.0", "0", @@ -18,7 +18,7 @@ def test_constructor() -> None: def test_pack() -> None: guid = uuid.UUID('0002043000000000C000000000000046') - ref = ref = LibidReference( + ref = LibidReference( guid, "2.0", "0", From 9f49cad8a1cb27d34c66dfafcd19535c32c09509 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 14:59:41 -0500 Subject: [PATCH 253/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index 1daab17c7..574b99b93 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -9,7 +9,7 @@ def test_constructor() -> None: guid, "2.0", "0", - "C:\\Windows\\System32\\stdole2.tlb", + "C:\\Windows\\system32\\stdole2.tlb", "OLE Automation" ) module = ReferenceRegistered("cp1", ref) @@ -22,7 +22,7 @@ def test_pack() -> None: guid, "2.0", "0", - "C:\\Windows\\System32\\stdole2.tlb", + "C:\\Windows\\system32\\stdole2.tlb", "OLE Automation" ) From dcc79950b48fcec4c8200540d81469f81b6bbde5 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 15:16:38 -0500 Subject: [PATCH 254/335] Create test_reference.py --- tests/Unit/Models/Entities/test_reference.py | 38 ++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 tests/Unit/Models/Entities/test_reference.py diff --git a/tests/Unit/Models/Entities/test_reference.py b/tests/Unit/Models/Entities/test_reference.py new file mode 100644 index 000000000..b4e739f54 --- /dev/null +++ b/tests/Unit/Models/Entities/test_reference.py @@ -0,0 +1,38 @@ +from ms_ovba.Models.Entities.reference import Reference +from ms_ovba.Models.Entities.reference_project import ReferenceProject +from ms_ovba.Models.Fields.project_reference import ProjectReference + + +def test_constructor1() -> None: + proj_ref = ProjectReference("C:\\Example Path\\Example-ReferencedProject.xls") + ref_proj = ReferenceProject("cp1", proj_ref) + ref = Reference("cp1", ref_proj) + assert isinstance(ref, Reference) + + +def test_constructor2() -> None: + proj_ref = ProjectReference("C:\\Example Path\\Example-ReferencedProject.xls") + ref_proj = ReferenceProject("cp1", proj_ref) + ref = Reference("cp1", ref_proj, "VBAProject1") + assert isinstance(ref, Reference) + + +def test_pack() -> None: + proj_ref = ProjectReference("C:\\Example Path\\Example-ReferencedProject.xls") + ref_proj = ReferenceProject("cp1", proj_ref) + ref = Reference("cp1", ref_proj, "VBAProject1") + + expected_hex = ("16 00 0B 00 00 00 56 42 41 50 72 6F 6A 65 63 74", + "31 3E 00 56 00 42 00 41 00 50 00 72 00 6F 00 6A", + "00 65 00 73 00 74 00 31 00 0E 00 5E 00 00 00 30", + "00 00 00 2A 5C 43 43 3A 5C 45 78 61 6D 70 6C 65", + "20 50 61 74 68 5C 45 78 61 6D 70 6C 65 2D 52 65", + "66 65 72 65 6E 63 65 64 50 72 6F 6A 65 63 74 2E", + "78 6C 73 20 00 00 00 2A 5C 43 45 78 61 6D 70 6C", + "65 2D 52 65 66 65 72 65 6E 63 65 64 50 72 6F 6A", + "65 63 74 2E 78 6C 73 57 02 BE 65 17 00") + expected = bytes.fromhex(" ".join(expected_hex)) + codepage = 0x04E4 + codepage_name = "cp" + str(codepage) + results = ref.pack(codepage_name, 'little') + assert results == expected From 0343cae9de7407a77cf37a706c5e38f249bd3179 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 15:18:23 -0500 Subject: [PATCH 255/335] Update test_reference.py --- tests/Unit/Models/Entities/test_reference.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/Unit/Models/Entities/test_reference.py b/tests/Unit/Models/Entities/test_reference.py index b4e739f54..5956621c5 100644 --- a/tests/Unit/Models/Entities/test_reference.py +++ b/tests/Unit/Models/Entities/test_reference.py @@ -4,21 +4,24 @@ def test_constructor1() -> None: - proj_ref = ProjectReference("C:\\Example Path\\Example-ReferencedProject.xls") + path = "C:\\Example Path\\Example-ReferencedProject.xls" + proj_ref = ProjectReference(path) ref_proj = ReferenceProject("cp1", proj_ref) ref = Reference("cp1", ref_proj) assert isinstance(ref, Reference) def test_constructor2() -> None: - proj_ref = ProjectReference("C:\\Example Path\\Example-ReferencedProject.xls") + path = "C:\\Example Path\\Example-ReferencedProject.xls" + proj_ref = ProjectReference(path) ref_proj = ReferenceProject("cp1", proj_ref) ref = Reference("cp1", ref_proj, "VBAProject1") assert isinstance(ref, Reference) def test_pack() -> None: - proj_ref = ProjectReference("C:\\Example Path\\Example-ReferencedProject.xls") + path = "C:\\Example Path\\Example-ReferencedProject.xls" + proj_ref = ProjectReference(path) ref_proj = ReferenceProject("cp1", proj_ref) ref = Reference("cp1", ref_proj, "VBAProject1") From e9a13457ba8f47b99f972390b9a9f9d7b39e9a8e Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 15:22:03 -0500 Subject: [PATCH 256/335] Update test_reference.py --- tests/Unit/Models/Entities/test_reference.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tests/Unit/Models/Entities/test_reference.py b/tests/Unit/Models/Entities/test_reference.py index 5956621c5..941a2d697 100644 --- a/tests/Unit/Models/Entities/test_reference.py +++ b/tests/Unit/Models/Entities/test_reference.py @@ -26,14 +26,15 @@ def test_pack() -> None: ref = Reference("cp1", ref_proj, "VBAProject1") expected_hex = ("16 00 0B 00 00 00 56 42 41 50 72 6F 6A 65 63 74", - "31 3E 00 56 00 42 00 41 00 50 00 72 00 6F 00 6A", - "00 65 00 73 00 74 00 31 00 0E 00 5E 00 00 00 30", - "00 00 00 2A 5C 43 43 3A 5C 45 78 61 6D 70 6C 65", - "20 50 61 74 68 5C 45 78 61 6D 70 6C 65 2D 52 65", - "66 65 72 65 6E 63 65 64 50 72 6F 6A 65 63 74 2E", - "78 6C 73 20 00 00 00 2A 5C 43 45 78 61 6D 70 6C", + "31 3E 00 16 00 00 00 56 00 42 00 41 00 50 00 72", + "00 6F 00 6A 00 65 00 73 00 74 00 31 00 0E 00 5E", + "00 00 00 30 00 00 00 2A 5C 43 43 3A 5C 45 78 61", + "6D 70 6C 65 20 50 61 74 68 5C 45 78 61 6D 70 6C", "65 2D 52 65 66 65 72 65 6E 63 65 64 50 72 6F 6A", - "65 63 74 2E 78 6C 73 57 02 BE 65 17 00") + "65 63 74 2E 78 6C 73 20 00 00 00 2A 5C 43 45 78", + "61 6D 70 6C 65 2D 52 65 66 65 72 65 6E 63 65 64", + "50 72 6F 6A 65 63 74 2E 78 6C 73 57 02 BE 65 17", + "00") expected = bytes.fromhex(" ".join(expected_hex)) codepage = 0x04E4 codepage_name = "cp" + str(codepage) From 852d87f601cd5039268cecd02b0577558ccd01f6 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 15:24:00 -0500 Subject: [PATCH 257/335] Update test_reference.py --- tests/Unit/Models/Entities/test_reference.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_reference.py b/tests/Unit/Models/Entities/test_reference.py index 941a2d697..831c9466e 100644 --- a/tests/Unit/Models/Entities/test_reference.py +++ b/tests/Unit/Models/Entities/test_reference.py @@ -27,7 +27,7 @@ def test_pack() -> None: expected_hex = ("16 00 0B 00 00 00 56 42 41 50 72 6F 6A 65 63 74", "31 3E 00 16 00 00 00 56 00 42 00 41 00 50 00 72", - "00 6F 00 6A 00 65 00 73 00 74 00 31 00 0E 00 5E", + "00 6F 00 6A 00 65 00 63 00 74 00 31 00 0E 00 5E", "00 00 00 30 00 00 00 2A 5C 43 43 3A 5C 45 78 61", "6D 70 6C 65 20 50 61 74 68 5C 45 78 61 6D 70 6C", "65 2D 52 65 66 65 72 65 6E 63 65 64 50 72 6F 6A", From 6e914225a8a06ac19e7d0c8be1c420b316742e06 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 15:30:24 -0500 Subject: [PATCH 258/335] Rename test_fullFile.py to test_fullFile.pyt --- tests/Functional/{test_fullFile.py => test_fullFile.pyt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/Functional/{test_fullFile.py => test_fullFile.pyt} (100%) diff --git a/tests/Functional/test_fullFile.py b/tests/Functional/test_fullFile.pyt similarity index 100% rename from tests/Functional/test_fullFile.py rename to tests/Functional/test_fullFile.pyt From 855bb703cdc776222ac37fd7c35f58e97923483f Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 15:34:32 -0500 Subject: [PATCH 259/335] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 45f9443eb..33b32249e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Coverage Status](https://coveralls.io/repos/github/Beakerboy/vbaProject-Compiler/badge.svg?branch=main)](https://coveralls.io/github/Beakerboy/vbaProject-Compiler?branch=main) +[![Coverage Status](https://coveralls.io/repos/github/Beakerboy/MS-OVBA/badge.svg?branch=main)](https://coveralls.io/github/Beakerboy/MS-OVBA?branch=main) # vbaProject-Compiler Create a vbaProject.bin file from VBA source files. From 0688a00b44dc37264a080a904de76840d43676ef Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 20:12:32 -0500 Subject: [PATCH 260/335] Update and rename reference_type.py to reference_record.py (#118) * Update and rename reference_type.py to reference_record.py * Update reference_project.py * Update reference.py * Update reference_registered.py --- src/ms_ovba/Models/Entities/reference.py | 4 ++-- src/ms_ovba/Models/Entities/reference_project.py | 4 ++-- .../Entities/{reference_type.py => reference_record.py} | 4 ++-- src/ms_ovba/Models/Entities/reference_registered.py | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) rename src/ms_ovba/Models/Entities/{reference_type.py => reference_record.py} (64%) diff --git a/src/ms_ovba/Models/Entities/reference.py b/src/ms_ovba/Models/Entities/reference.py index 99cbc1f52..f7df2ce4c 100644 --- a/src/ms_ovba/Models/Entities/reference.py +++ b/src/ms_ovba/Models/Entities/reference.py @@ -1,4 +1,4 @@ -from ms_ovba.Models.Entities.reference_type import ReferenceType +from ms_ovba.Models.Entities.reference_record import ReferenceRecord from ms_ovba.Models.Fields.doubleEncodedString import ( DoubleEncodedString ) @@ -13,7 +13,7 @@ class Reference(): 2.3.4.2.2.1 REFERENCE Record """ def __init__(self: T, codepage_name: str, - ref: ReferenceType, + ref: ReferenceRecord, name: str = None) -> None: # is self._codepage_name even needed? self._codepage_name = codepage_name diff --git a/src/ms_ovba/Models/Entities/reference_project.py b/src/ms_ovba/Models/Entities/reference_project.py index b3ab85458..c95aea2b7 100644 --- a/src/ms_ovba/Models/Entities/reference_project.py +++ b/src/ms_ovba/Models/Entities/reference_project.py @@ -1,4 +1,4 @@ -from ms_ovba.Models.Entities.reference_type import ReferenceType +from ms_ovba.Models.Entities.reference_record import ReferenceRecord from ms_ovba.Models.Fields.project_reference import ProjectReference from ms_ovba.Models.Fields.packed_data import PackedData from typing import TypeVar @@ -7,7 +7,7 @@ T = TypeVar('T', bound='ReferenceProject') -class ReferenceProject(ReferenceType): +class ReferenceProject(ReferenceRecord): def __init__(self: T, codepage_name: str, ref: ProjectReference) -> None: diff --git a/src/ms_ovba/Models/Entities/reference_type.py b/src/ms_ovba/Models/Entities/reference_record.py similarity index 64% rename from src/ms_ovba/Models/Entities/reference_type.py rename to src/ms_ovba/Models/Entities/reference_record.py index df229eef1..b30e9ef62 100644 --- a/src/ms_ovba/Models/Entities/reference_type.py +++ b/src/ms_ovba/Models/Entities/reference_record.py @@ -1,10 +1,10 @@ from typing import TypeVar -T = TypeVar('T', bound='ReferenceType') +T = TypeVar('T', bound='ReferenceRecord') -class ReferenceType: +class ReferenceRecord: def pack(self: T, codepage_name: str, endien: str) -> bytes: return b'' diff --git a/src/ms_ovba/Models/Entities/reference_registered.py b/src/ms_ovba/Models/Entities/reference_registered.py index 7f6fd2afa..039f7053c 100644 --- a/src/ms_ovba/Models/Entities/reference_registered.py +++ b/src/ms_ovba/Models/Entities/reference_registered.py @@ -1,4 +1,4 @@ -from ms_ovba.Models.Entities.reference_type import ReferenceType +from ms_ovba.Models.Entities.reference_record import ReferenceRecord from ms_ovba.Models.Fields.libid_reference import LibidReference from ms_ovba.Models.Fields.packed_data import PackedData from typing import TypeVar @@ -7,7 +7,7 @@ T = TypeVar('T', bound='ReferenceRegistered') -class ReferenceRegistered(ReferenceType): +class ReferenceRegistered(ReferenceRecord): """ 2.3.4.2.2.5 Specifies a reference to an Automation type library. From 60b736e20e118ec2d154c6fc8024a60135f5418b Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 20:27:02 -0500 Subject: [PATCH 261/335] Update reference.py --- src/ms_ovba/Models/Entities/reference.py | 29 ++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/ms_ovba/Models/Entities/reference.py b/src/ms_ovba/Models/Entities/reference.py index f7df2ce4c..1a1bd344d 100644 --- a/src/ms_ovba/Models/Entities/reference.py +++ b/src/ms_ovba/Models/Entities/reference.py @@ -27,3 +27,32 @@ def pack(self: T, cp_name: str, endien: str) -> bytes: name_pack = name_de.pack(cp_name, endien) return name_pack + self._ref.pack(cp_name, endien) + + @staticmethod + def unpack(data: bytes) -> T: + # Read 2 bytes into id + # if id == 0x0016: + # Read 4 bytes into size1 + # Read size1 bytes into name + # Read 4 bytes into size2 + # if size2 != size1 * 2: + # raise warning + # read size2 bytes into name2 + # if name2 != unicode version on name1: + # raise warning + # read 2 bytes into id + # + # if id == 0x0000D: + # return ReferenceRegistered.unpack(bytestring) + # else if id == 0x0000E: + # return ReferenceProject.unpack(bytestring) + # else if id == 0x0002F: + # return ReferenceControl.unpack(bytestring) + # else if id == 0x00033: + # return ReferenceOriginal.unpack(bytestring) + # else raise warning + + + + + From f6ccd48a30ebb94fed88ef46d7b88c578402e826 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 20:29:26 -0500 Subject: [PATCH 262/335] Update reference.py --- src/ms_ovba/Models/Entities/reference.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference.py b/src/ms_ovba/Models/Entities/reference.py index 1a1bd344d..ccc2ede59 100644 --- a/src/ms_ovba/Models/Entities/reference.py +++ b/src/ms_ovba/Models/Entities/reference.py @@ -30,6 +30,7 @@ def pack(self: T, cp_name: str, endien: str) -> bytes: @staticmethod def unpack(data: bytes) -> T: + # name = None # Read 2 bytes into id # if id == 0x0016: # Read 4 bytes into size1 @@ -43,14 +44,15 @@ def unpack(data: bytes) -> T: # read 2 bytes into id # # if id == 0x0000D: - # return ReferenceRegistered.unpack(bytestring) + # ref = ReferenceRegistered.unpack(bytestring) # else if id == 0x0000E: - # return ReferenceProject.unpack(bytestring) + # ref = ReferenceProject.unpack(bytestring) # else if id == 0x0002F: - # return ReferenceControl.unpack(bytestring) + # ref = ReferenceControl.unpack(bytestring) # else if id == 0x00033: - # return ReferenceOriginal.unpack(bytestring) + # ref = ReferenceOriginal.unpack(bytestring) # else raise warning + # return Record("cp", ref, name) From 0b8204bb855a87da6ccfa90b7f6b23e5f6c668d8 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 20:48:50 -0500 Subject: [PATCH 263/335] Update reference.py --- src/ms_ovba/Models/Entities/reference.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ms_ovba/Models/Entities/reference.py b/src/ms_ovba/Models/Entities/reference.py index ccc2ede59..fbd010f9a 100644 --- a/src/ms_ovba/Models/Entities/reference.py +++ b/src/ms_ovba/Models/Entities/reference.py @@ -53,6 +53,7 @@ def unpack(data: bytes) -> T: # ref = ReferenceOriginal.unpack(bytestring) # else raise warning # return Record("cp", ref, name) + pass From b041cfb4658f5706b5db2a2a6a7c824ed5d23c02 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 20:56:53 -0500 Subject: [PATCH 264/335] Update reference.py --- src/ms_ovba/Models/Entities/reference.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference.py b/src/ms_ovba/Models/Entities/reference.py index fbd010f9a..54476ca9d 100644 --- a/src/ms_ovba/Models/Entities/reference.py +++ b/src/ms_ovba/Models/Entities/reference.py @@ -29,7 +29,7 @@ def pack(self: T, cp_name: str, endien: str) -> bytes: return name_pack + self._ref.pack(cp_name, endien) @staticmethod - def unpack(data: bytes) -> T: + def unpack(data: bytes, endien: str) -> T: # name = None # Read 2 bytes into id # if id == 0x0016: @@ -44,14 +44,16 @@ def unpack(data: bytes) -> T: # read 2 bytes into id # # if id == 0x0000D: - # ref = ReferenceRegistered.unpack(bytestring) + # ref = ReferenceRegistered.unpack(bytestring, endien) # else if id == 0x0000E: - # ref = ReferenceProject.unpack(bytestring) + # ref = ReferenceProject.unpack(bytestring, endien) # else if id == 0x0002F: - # ref = ReferenceControl.unpack(bytestring) + # ref = ReferenceControl.unpack(bytestring, endien) # else if id == 0x00033: - # ref = ReferenceOriginal.unpack(bytestring) - # else raise warning + # ref = ReferenceOriginal.unpack(bytestring, endien) + # else: + # raise warning + # return None # return Record("cp", ref, name) pass From 39f807b84eaef5b06fb7332d91afd9421b40fa5e Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 20:58:04 -0500 Subject: [PATCH 265/335] Update reference.py --- src/ms_ovba/Models/Entities/reference.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference.py b/src/ms_ovba/Models/Entities/reference.py index 54476ca9d..23a9edb30 100644 --- a/src/ms_ovba/Models/Entities/reference.py +++ b/src/ms_ovba/Models/Entities/reference.py @@ -56,8 +56,3 @@ def unpack(data: bytes, endien: str) -> T: # return None # return Record("cp", ref, name) pass - - - - - From 7a2f1b6a3d181bdb5d09319f2c230adedc9bb1f0 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 21:25:08 -0500 Subject: [PATCH 266/335] Update reference.py --- src/ms_ovba/Models/Entities/reference.py | 61 ++++++++++++++---------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference.py b/src/ms_ovba/Models/Entities/reference.py index 23a9edb30..873660276 100644 --- a/src/ms_ovba/Models/Entities/reference.py +++ b/src/ms_ovba/Models/Entities/reference.py @@ -30,29 +30,38 @@ def pack(self: T, cp_name: str, endien: str) -> bytes: @staticmethod def unpack(data: bytes, endien: str) -> T: - # name = None - # Read 2 bytes into id - # if id == 0x0016: - # Read 4 bytes into size1 - # Read size1 bytes into name - # Read 4 bytes into size2 - # if size2 != size1 * 2: - # raise warning - # read size2 bytes into name2 - # if name2 != unicode version on name1: - # raise warning - # read 2 bytes into id - # - # if id == 0x0000D: - # ref = ReferenceRegistered.unpack(bytestring, endien) - # else if id == 0x0000E: - # ref = ReferenceProject.unpack(bytestring, endien) - # else if id == 0x0002F: - # ref = ReferenceControl.unpack(bytestring, endien) - # else if id == 0x00033: - # ref = ReferenceOriginal.unpack(bytestring, endien) - # else: - # raise warning - # return None - # return Record("cp", ref, name) - pass + endien_symbol = '<' if endien == 'little' else '>' + name = None + offset = 0 + id = struct.unpack_from(endien_stmbol + "H", data, offset) + offset += 2 + if id == 0x0016: + size1 = struct.unpack_from(endien_stmbol + "I", data, offset) + offset += 4 + name = struct.unpack_from(endien_stmbol + size1 + "s", data, offset) + offset += size1 + size2 = struct.unpack_from(endien_stmbol + "I", data, offset) + offset += 4 + if size2 != size1 * 2: + # raise warning + pass + name2 = struct.unpack_from(endien_stmbol + size2 + "s", data, offset) + offset += size2 + # if name2 != unicode version on name1: + # raise warning + id = struct.unpack_from(endien_stmbol + "H", data, offset) + offset += 2 + + + if id == 0x0000D: + ref = ReferenceRegistered.unpack(bytestring, endien) + else if id == 0x0000E: + ref = ReferenceProject.unpack(bytestring, endien) + else if id == 0x0002F: + ref = ReferenceControl.unpack(bytestring, endien) + else if id == 0x00033: + ref = ReferenceOriginal.unpack(bytestring, endien) + else: + # raise warning + return None + return Record("cp", ref, name) From 8535f8fb8720b89e5f26074d06f0666b4e09cd86 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 21:29:49 -0500 Subject: [PATCH 267/335] Update reference.py --- src/ms_ovba/Models/Entities/reference.py | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference.py b/src/ms_ovba/Models/Entities/reference.py index 873660276..28351a6dc 100644 --- a/src/ms_ovba/Models/Entities/reference.py +++ b/src/ms_ovba/Models/Entities/reference.py @@ -1,3 +1,4 @@ +import struct from ms_ovba.Models.Entities.reference_record import ReferenceRecord from ms_ovba.Models.Fields.doubleEncodedString import ( DoubleEncodedString @@ -34,8 +35,8 @@ def unpack(data: bytes, endien: str) -> T: name = None offset = 0 id = struct.unpack_from(endien_stmbol + "H", data, offset) - offset += 2 if id == 0x0016: + offset += 2 size1 = struct.unpack_from(endien_stmbol + "I", data, offset) offset += 4 name = struct.unpack_from(endien_stmbol + size1 + "s", data, offset) @@ -50,18 +51,6 @@ def unpack(data: bytes, endien: str) -> T: # if name2 != unicode version on name1: # raise warning id = struct.unpack_from(endien_stmbol + "H", data, offset) - offset += 2 - - - if id == 0x0000D: - ref = ReferenceRegistered.unpack(bytestring, endien) - else if id == 0x0000E: - ref = ReferenceProject.unpack(bytestring, endien) - else if id == 0x0002F: - ref = ReferenceControl.unpack(bytestring, endien) - else if id == 0x00033: - ref = ReferenceOriginal.unpack(bytestring, endien) - else: - # raise warning - return None + bytestring = data[offset:] + ref = ReferenceRecord.unpack(bytestring, endien) return Record("cp", ref, name) From 03023277afe1d8bbbdf5c336999f806f84873390 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 21:33:54 -0500 Subject: [PATCH 268/335] Update reference_record.py --- .../Models/Entities/reference_record.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference_record.py b/src/ms_ovba/Models/Entities/reference_record.py index b30e9ef62..6431b69b2 100644 --- a/src/ms_ovba/Models/Entities/reference_record.py +++ b/src/ms_ovba/Models/Entities/reference_record.py @@ -1,3 +1,4 @@ +import struct from typing import TypeVar @@ -6,5 +7,19 @@ class ReferenceRecord: - def pack(self: T, codepage_name: str, endien: str) -> bytes: - return b'' + @staticmethod + def unpack(bytestring: bytes, endien: str) -> T: + endien_symbol = '<' if endien == 'little' else '>' + id = struct.unpack(endien_symbol + "H", bytestring) + if id == 0x0000D: + ref = ReferenceRegistered.unpack(bytestring, endien) + else if id == 0x0000E: + ref = ReferenceProject.unpack(bytestring, endien) + else if id == 0x0002F: + ref = ReferenceControl.unpack(bytestring, endien) + else if id == 0x00033: + ref = ReferenceOriginal.unpack(bytestring, endien) + else: + # raise warning + return None + return ref From 2a41355975f1e0a3cb80f728c25a60c454632364 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 21:34:30 -0500 Subject: [PATCH 269/335] Update reference_record.py --- src/ms_ovba/Models/Entities/reference_record.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Entities/reference_record.py b/src/ms_ovba/Models/Entities/reference_record.py index 6431b69b2..682a394e2 100644 --- a/src/ms_ovba/Models/Entities/reference_record.py +++ b/src/ms_ovba/Models/Entities/reference_record.py @@ -10,7 +10,7 @@ class ReferenceRecord: @staticmethod def unpack(bytestring: bytes, endien: str) -> T: endien_symbol = '<' if endien == 'little' else '>' - id = struct.unpack(endien_symbol + "H", bytestring) + id = struct.unpack(endien_symbol + "I", bytestring) if id == 0x0000D: ref = ReferenceRegistered.unpack(bytestring, endien) else if id == 0x0000E: From b7b97505d66e4a08ea6188b04b31fd615ede12c7 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 21:37:14 -0500 Subject: [PATCH 270/335] Update reference_record.py --- src/ms_ovba/Models/Entities/reference_record.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference_record.py b/src/ms_ovba/Models/Entities/reference_record.py index 682a394e2..1555565b0 100644 --- a/src/ms_ovba/Models/Entities/reference_record.py +++ b/src/ms_ovba/Models/Entities/reference_record.py @@ -10,14 +10,14 @@ class ReferenceRecord: @staticmethod def unpack(bytestring: bytes, endien: str) -> T: endien_symbol = '<' if endien == 'little' else '>' - id = struct.unpack(endien_symbol + "I", bytestring) - if id == 0x0000D: + id = struct.unpack(endien_symbol + "H", bytestring) + if id == 0x000D: ref = ReferenceRegistered.unpack(bytestring, endien) - else if id == 0x0000E: + else if id == 0x000E: ref = ReferenceProject.unpack(bytestring, endien) - else if id == 0x0002F: + else if id == 0x002F: ref = ReferenceControl.unpack(bytestring, endien) - else if id == 0x00033: + else if id == 0x0033: ref = ReferenceOriginal.unpack(bytestring, endien) else: # raise warning From 4a496fac43dac9d72fd839ca007f3a0214c58860 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 21:45:47 -0500 Subject: [PATCH 271/335] Update reference_registered.py --- .../Models/Entities/reference_registered.py | 40 +++++++++---------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference_registered.py b/src/ms_ovba/Models/Entities/reference_registered.py index 039f7053c..552fc5377 100644 --- a/src/ms_ovba/Models/Entities/reference_registered.py +++ b/src/ms_ovba/Models/Entities/reference_registered.py @@ -1,3 +1,4 @@ +import struct from ms_ovba.Models.Entities.reference_record import ReferenceRecord from ms_ovba.Models.Fields.libid_reference import LibidReference from ms_ovba.Models.Fields.packed_data import PackedData @@ -32,38 +33,33 @@ def pack(self: T, cp_name: str, endien: str) -> bytes: return ref_registered.pack(cp_name, endien) @staticmethod - def unpack(data: bytes) -> T: - start = 0 - end = 2 - id = bytes[start:end] + def unpack(data: bytes, endien: str) -> T: + endien_symbol = '<' if endien == 'little' else '>' + offset = 0 + id = struct.unpack_from(endien_symbol + "H", data, offset) + offset += 2 if id != 0x000D: raise ValueError("Incorrect id in data.") - start = end - end = end + 4 - recordsize = bytes[start:end] + recordsize = struct.unpack_from(endien_symbol + "I", data, offset) if len(data) != recordsize + 6: # raise a warning pass - start = end - end = end + 4 - libidsize = bytes[start:end] - - start = end - end = end + libidsize - libid_ref_bytes = bytes[start:end] - - start = end - end = end + 4 - reserved1 = bytes[start:end] + offset += 4 + libidsize = struct.unpack_from(endien_symbol + "I", data, offset) + offset += 4 + + libid_ref_bytes = struct.unpack_from(endien_symbol + libidsize + "s", data, offset) + offset += libidsize + + reserved1 = struct.unpack_from(endien_symbol + "I", data, offset) + offset += 4 + if reserved1 != 0: # raise a warning pass - - start = end - end = end + 2 - reserved2 = bytes[start:end] + reserved2 = struct.unpack_from(endien_symbol + "H", data, offset) if reserved2 != 0: # raise a warning pass From b8061fd20c9a7f835b3fae8612d87f2f781becf3 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 21:48:25 -0500 Subject: [PATCH 272/335] Update reference_registered.py --- src/ms_ovba/Models/Entities/reference_registered.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Entities/reference_registered.py b/src/ms_ovba/Models/Entities/reference_registered.py index 552fc5377..68485f8a6 100644 --- a/src/ms_ovba/Models/Entities/reference_registered.py +++ b/src/ms_ovba/Models/Entities/reference_registered.py @@ -64,5 +64,5 @@ def unpack(data: bytes, endien: str) -> T: # raise a warning pass - libid_ref = LibidReference.create(libid_ref_bytes) + libid_ref = LibidReference.create(libid_ref_bytes, endien) return ReferenceRegistered("", libid_ref) From 58a920f9c55f4758ff26c85064332a66df107b44 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 21:50:43 -0500 Subject: [PATCH 273/335] Update reference_registered.py --- src/ms_ovba/Models/Entities/reference_registered.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Entities/reference_registered.py b/src/ms_ovba/Models/Entities/reference_registered.py index 68485f8a6..64ea856f2 100644 --- a/src/ms_ovba/Models/Entities/reference_registered.py +++ b/src/ms_ovba/Models/Entities/reference_registered.py @@ -50,7 +50,7 @@ def unpack(data: bytes, endien: str) -> T: libidsize = struct.unpack_from(endien_symbol + "I", data, offset) offset += 4 - libid_ref_bytes = struct.unpack_from(endien_symbol + libidsize + "s", data, offset) + libid_ref_bytes = data[offset:offset + libidsize] offset += libidsize reserved1 = struct.unpack_from(endien_symbol + "I", data, offset) From 81913de53bf891733db0bd3f4f8a6411f7aa97cd Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 21:52:52 -0500 Subject: [PATCH 274/335] Update reference_registered.py --- src/ms_ovba/Models/Entities/reference_registered.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference_registered.py b/src/ms_ovba/Models/Entities/reference_registered.py index 64ea856f2..fc570d371 100644 --- a/src/ms_ovba/Models/Entities/reference_registered.py +++ b/src/ms_ovba/Models/Entities/reference_registered.py @@ -49,13 +49,13 @@ def unpack(data: bytes, endien: str) -> T: offset += 4 libidsize = struct.unpack_from(endien_symbol + "I", data, offset) offset += 4 - + libid_ref_bytes = data[offset:offset + libidsize] offset += libidsize - + reserved1 = struct.unpack_from(endien_symbol + "I", data, offset) offset += 4 - + if reserved1 != 0: # raise a warning pass From 6ca9bb108cd8f4dd2d45012e75a0cb9981d914f0 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 21:54:22 -0500 Subject: [PATCH 275/335] Update reference_record.py --- src/ms_ovba/Models/Entities/reference_record.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference_record.py b/src/ms_ovba/Models/Entities/reference_record.py index 1555565b0..a5420bbe8 100644 --- a/src/ms_ovba/Models/Entities/reference_record.py +++ b/src/ms_ovba/Models/Entities/reference_record.py @@ -13,11 +13,11 @@ def unpack(bytestring: bytes, endien: str) -> T: id = struct.unpack(endien_symbol + "H", bytestring) if id == 0x000D: ref = ReferenceRegistered.unpack(bytestring, endien) - else if id == 0x000E: + elif id == 0x000E: ref = ReferenceProject.unpack(bytestring, endien) - else if id == 0x002F: + elif id == 0x002F: ref = ReferenceControl.unpack(bytestring, endien) - else if id == 0x0033: + elif id == 0x0033: ref = ReferenceOriginal.unpack(bytestring, endien) else: # raise warning From 028bc11660f2ec18507b3e3e2da71a931b90c0db Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 21:56:29 -0500 Subject: [PATCH 276/335] Update reference.py --- src/ms_ovba/Models/Entities/reference.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference.py b/src/ms_ovba/Models/Entities/reference.py index 28351a6dc..1c7341ac3 100644 --- a/src/ms_ovba/Models/Entities/reference.py +++ b/src/ms_ovba/Models/Entities/reference.py @@ -34,23 +34,23 @@ def unpack(data: bytes, endien: str) -> T: endien_symbol = '<' if endien == 'little' else '>' name = None offset = 0 - id = struct.unpack_from(endien_stmbol + "H", data, offset) + id = struct.unpack_from(endien_symbol + "H", data, offset) if id == 0x0016: offset += 2 - size1 = struct.unpack_from(endien_stmbol + "I", data, offset) + size1 = struct.unpack_from(endien_symbol + "I", data, offset) offset += 4 - name = struct.unpack_from(endien_stmbol + size1 + "s", data, offset) + name = struct.unpack_from(endien_symbol + size1 + "s", data, offset) offset += size1 - size2 = struct.unpack_from(endien_stmbol + "I", data, offset) + size2 = struct.unpack_from(endien_symbol + "I", data, offset) offset += 4 if size2 != size1 * 2: # raise warning pass - name2 = struct.unpack_from(endien_stmbol + size2 + "s", data, offset) + name2 = struct.unpack_from(endien_symbol + size2 + "s", data, offset) offset += size2 # if name2 != unicode version on name1: # raise warning - id = struct.unpack_from(endien_stmbol + "H", data, offset) + id = struct.unpack_from(endien_symbol + "H", data, offset) bytestring = data[offset:] ref = ReferenceRecord.unpack(bytestring, endien) return Record("cp", ref, name) From 01b90aab32b75144eadd34e169be430a9b9fdd00 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 22:02:58 -0500 Subject: [PATCH 277/335] Update reference.py --- src/ms_ovba/Models/Entities/reference.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference.py b/src/ms_ovba/Models/Entities/reference.py index 1c7341ac3..ac53215b9 100644 --- a/src/ms_ovba/Models/Entities/reference.py +++ b/src/ms_ovba/Models/Entities/reference.py @@ -46,11 +46,11 @@ def unpack(data: bytes, endien: str) -> T: if size2 != size1 * 2: # raise warning pass - name2 = struct.unpack_from(endien_symbol + size2 + "s", data, offset) + # name2 = struct.unpack_from(endien_symbol + size2 + "s", data, offset) offset += size2 # if name2 != unicode version on name1: # raise warning - id = struct.unpack_from(endien_symbol + "H", data, offset) + bytestring = data[offset:] ref = ReferenceRecord.unpack(bytestring, endien) return Record("cp", ref, name) From 145d2bc47201c3f100def1aebcc443e47e0e55c7 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 22:05:12 -0500 Subject: [PATCH 278/335] Update reference_record.py --- src/ms_ovba/Models/Entities/reference_record.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ms_ovba/Models/Entities/reference_record.py b/src/ms_ovba/Models/Entities/reference_record.py index a5420bbe8..a65ab8a16 100644 --- a/src/ms_ovba/Models/Entities/reference_record.py +++ b/src/ms_ovba/Models/Entities/reference_record.py @@ -1,4 +1,6 @@ import struct +from ms_ovba.Models.Entities.reference_project import ReferenceProject +from ms_ovba.Models.Entities.reference_registered import ReferenceRegistered from typing import TypeVar From 0c831818d0db6aa78ae955f7015028caacd4231b Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 22:06:27 -0500 Subject: [PATCH 279/335] Update reference.py --- src/ms_ovba/Models/Entities/reference.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Entities/reference.py b/src/ms_ovba/Models/Entities/reference.py index ac53215b9..54a93e4c3 100644 --- a/src/ms_ovba/Models/Entities/reference.py +++ b/src/ms_ovba/Models/Entities/reference.py @@ -53,4 +53,4 @@ def unpack(data: bytes, endien: str) -> T: bytestring = data[offset:] ref = ReferenceRecord.unpack(bytestring, endien) - return Record("cp", ref, name) + return Reference("cp", ref, name) From fa7aa4ab1a6ec29aa891ba4958370bcd7ad10ce7 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 22:09:17 -0500 Subject: [PATCH 280/335] Update reference.py --- src/ms_ovba/Models/Entities/reference.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Entities/reference.py b/src/ms_ovba/Models/Entities/reference.py index 54a93e4c3..5afb574c6 100644 --- a/src/ms_ovba/Models/Entities/reference.py +++ b/src/ms_ovba/Models/Entities/reference.py @@ -49,7 +49,7 @@ def unpack(data: bytes, endien: str) -> T: # name2 = struct.unpack_from(endien_symbol + size2 + "s", data, offset) offset += size2 # if name2 != unicode version on name1: - # raise warning + # raise warning bytestring = data[offset:] ref = ReferenceRecord.unpack(bytestring, endien) From 00cc4f8f972de01c8ca5b7da07f3af9a68618990 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 22:12:26 -0500 Subject: [PATCH 281/335] Update reference_record.py --- src/ms_ovba/Models/Entities/reference_record.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference_record.py b/src/ms_ovba/Models/Entities/reference_record.py index a65ab8a16..509dd4cf3 100644 --- a/src/ms_ovba/Models/Entities/reference_record.py +++ b/src/ms_ovba/Models/Entities/reference_record.py @@ -18,9 +18,11 @@ def unpack(bytestring: bytes, endien: str) -> T: elif id == 0x000E: ref = ReferenceProject.unpack(bytestring, endien) elif id == 0x002F: - ref = ReferenceControl.unpack(bytestring, endien) + # ref = ReferenceControl.unpack(bytestring, endien) + pass elif id == 0x0033: - ref = ReferenceOriginal.unpack(bytestring, endien) + # ref = ReferenceOriginal.unpack(bytestring, endien) + pass else: # raise warning return None From 32ce0a497d543a7245e0b0219ea444919fe97359 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 22:13:50 -0500 Subject: [PATCH 282/335] Update reference.py --- src/ms_ovba/Models/Entities/reference.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Entities/reference.py b/src/ms_ovba/Models/Entities/reference.py index 5afb574c6..abca30b03 100644 --- a/src/ms_ovba/Models/Entities/reference.py +++ b/src/ms_ovba/Models/Entities/reference.py @@ -46,7 +46,8 @@ def unpack(data: bytes, endien: str) -> T: if size2 != size1 * 2: # raise warning pass - # name2 = struct.unpack_from(endien_symbol + size2 + "s", data, offset) + # format = endien_symbol + size2 + "s" + # name2 = struct.unpack_from(format, data, offset) offset += size2 # if name2 != unicode version on name1: # raise warning From cbb378d591890c174fbbe4d3545668b3dacf2a8a Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 22:15:12 -0500 Subject: [PATCH 283/335] Update reference.py --- src/ms_ovba/Models/Entities/reference.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Entities/reference.py b/src/ms_ovba/Models/Entities/reference.py index abca30b03..a78bc90eb 100644 --- a/src/ms_ovba/Models/Entities/reference.py +++ b/src/ms_ovba/Models/Entities/reference.py @@ -39,7 +39,8 @@ def unpack(data: bytes, endien: str) -> T: offset += 2 size1 = struct.unpack_from(endien_symbol + "I", data, offset) offset += 4 - name = struct.unpack_from(endien_symbol + size1 + "s", data, offset) + format = endien_symbol + size1 + "s" + name = struct.unpack_from(format, data, offset) offset += size1 size2 = struct.unpack_from(endien_symbol + "I", data, offset) offset += 4 From 5d793397a05ced8e5e7a3f73bf75a3183dbcd87c Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 22:23:52 -0500 Subject: [PATCH 284/335] Update reference_record.py --- src/ms_ovba/Models/Entities/reference_record.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference_record.py b/src/ms_ovba/Models/Entities/reference_record.py index 509dd4cf3..cea8209a8 100644 --- a/src/ms_ovba/Models/Entities/reference_record.py +++ b/src/ms_ovba/Models/Entities/reference_record.py @@ -1,6 +1,4 @@ import struct -from ms_ovba.Models.Entities.reference_project import ReferenceProject -from ms_ovba.Models.Entities.reference_registered import ReferenceRegistered from typing import TypeVar @@ -11,6 +9,8 @@ class ReferenceRecord: @staticmethod def unpack(bytestring: bytes, endien: str) -> T: + from ms_ovba.Models.Entities.reference_project import ReferenceProject + from ms_ovba.Models.Entities.reference_registered import ReferenceRegistered endien_symbol = '<' if endien == 'little' else '>' id = struct.unpack(endien_symbol + "H", bytestring) if id == 0x000D: From b0ee824212c661e3751786a80fbf6e7211055567 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 22:26:00 -0500 Subject: [PATCH 285/335] Update reference_record.py --- src/ms_ovba/Models/Entities/reference_record.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Entities/reference_record.py b/src/ms_ovba/Models/Entities/reference_record.py index cea8209a8..6cb14819b 100644 --- a/src/ms_ovba/Models/Entities/reference_record.py +++ b/src/ms_ovba/Models/Entities/reference_record.py @@ -10,7 +10,9 @@ class ReferenceRecord: @staticmethod def unpack(bytestring: bytes, endien: str) -> T: from ms_ovba.Models.Entities.reference_project import ReferenceProject - from ms_ovba.Models.Entities.reference_registered import ReferenceRegistered + from ms_ovba.Models.Entities.reference_registered import ( + ReferenceRegistered + ) endien_symbol = '<' if endien == 'little' else '>' id = struct.unpack(endien_symbol + "H", bytestring) if id == 0x000D: From c5fce2145e8398a14c276cbbc9683a32bc208f24 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 22:44:16 -0500 Subject: [PATCH 286/335] Update test_reference_registered.py --- .../Models/Entities/test_reference_registered.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index 574b99b93..0cc05a9a4 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -39,3 +39,16 @@ def test_pack() -> None: ref_reg = ReferenceRegistered(codepage_name, ref) results = ref_reg.pack(codepage_name, 'little') assert results == expected + + +def test_unpack() -> None: + hex = ("0D 00 68 00 00 00 5E 00 00 00 2A 5C 47 7B 30 30", + "30 32 30 34 33 30 2D 30 30 30 30 2D 30 30 30 30", + "2D 43 30 30 30 2D 30 30 30 30 30 30 30 30 30 30", + "34 36 7D 23 32 2E 30 23 30 23 43 3A 5C 57 69 6E", + "64 6F 77 73 5C 73 79 73 74 65 6D 33 32 5C 73 74", + "64 6F 6C 65 32 2E 74 6C 62 23 4F 4C 45 20 41 75", + "74 6F 6D 61 74 69 6F 6E 00 00 00 00 00 00") + data = bytes.fromhex(" ".join(hex)) + ref = ReferenceRegistered.unpack(data, "little") + assert isinstance(ref.libid, LibidReference) From e0f5b7322118f123455f0fef1e2f1d1ff2021a8d Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 22:48:59 -0500 Subject: [PATCH 287/335] Update reference_registered.py --- src/ms_ovba/Models/Entities/reference_registered.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Entities/reference_registered.py b/src/ms_ovba/Models/Entities/reference_registered.py index fc570d371..d62e97e42 100644 --- a/src/ms_ovba/Models/Entities/reference_registered.py +++ b/src/ms_ovba/Models/Entities/reference_registered.py @@ -39,7 +39,7 @@ def unpack(data: bytes, endien: str) -> T: id = struct.unpack_from(endien_symbol + "H", data, offset) offset += 2 if id != 0x000D: - raise ValueError("Incorrect id in data.") + raise ValueError("Incorrect id in data. Received " + id + " but expected 0x000D") recordsize = struct.unpack_from(endien_symbol + "I", data, offset) if len(data) != recordsize + 6: From c01134f601883b0ef80f71cbbcca9ab096d03d26 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 22:53:20 -0500 Subject: [PATCH 288/335] Update reference_registered.py --- src/ms_ovba/Models/Entities/reference_registered.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Entities/reference_registered.py b/src/ms_ovba/Models/Entities/reference_registered.py index d62e97e42..29865f2b8 100644 --- a/src/ms_ovba/Models/Entities/reference_registered.py +++ b/src/ms_ovba/Models/Entities/reference_registered.py @@ -36,7 +36,7 @@ def pack(self: T, cp_name: str, endien: str) -> bytes: def unpack(data: bytes, endien: str) -> T: endien_symbol = '<' if endien == 'little' else '>' offset = 0 - id = struct.unpack_from(endien_symbol + "H", data, offset) + id, _ = struct.unpack_from(endien_symbol + "H", data, offset) offset += 2 if id != 0x000D: raise ValueError("Incorrect id in data. Received " + id + " but expected 0x000D") From eb022982515f0be911570fd9ccf73bc57893176c Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 22:55:31 -0500 Subject: [PATCH 289/335] Update reference_registered.py --- src/ms_ovba/Models/Entities/reference_registered.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Entities/reference_registered.py b/src/ms_ovba/Models/Entities/reference_registered.py index 29865f2b8..f88474cb0 100644 --- a/src/ms_ovba/Models/Entities/reference_registered.py +++ b/src/ms_ovba/Models/Entities/reference_registered.py @@ -39,7 +39,8 @@ def unpack(data: bytes, endien: str) -> T: id, _ = struct.unpack_from(endien_symbol + "H", data, offset) offset += 2 if id != 0x000D: - raise ValueError("Incorrect id in data. Received " + id + " but expected 0x000D") + msg = "Incorrect id in data. Received " + id + " but expected 0x000D" + raise ValueError(msg) recordsize = struct.unpack_from(endien_symbol + "I", data, offset) if len(data) != recordsize + 6: From 42df9b6d7e3986222db26c504ef696a095c336dd Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 22:56:27 -0500 Subject: [PATCH 290/335] Update reference_registered.py --- src/ms_ovba/Models/Entities/reference_registered.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Entities/reference_registered.py b/src/ms_ovba/Models/Entities/reference_registered.py index f88474cb0..70c1561ce 100644 --- a/src/ms_ovba/Models/Entities/reference_registered.py +++ b/src/ms_ovba/Models/Entities/reference_registered.py @@ -36,7 +36,7 @@ def pack(self: T, cp_name: str, endien: str) -> bytes: def unpack(data: bytes, endien: str) -> T: endien_symbol = '<' if endien == 'little' else '>' offset = 0 - id, _ = struct.unpack_from(endien_symbol + "H", data, offset) + id, = struct.unpack_from(endien_symbol + "H", data, offset) offset += 2 if id != 0x000D: msg = "Incorrect id in data. Received " + id + " but expected 0x000D" From 5540afcb38faaf8d054eda80660a9ac32a1002e8 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 22:58:05 -0500 Subject: [PATCH 291/335] Update reference_registered.py --- src/ms_ovba/Models/Entities/reference_registered.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Entities/reference_registered.py b/src/ms_ovba/Models/Entities/reference_registered.py index 70c1561ce..3b22b71aa 100644 --- a/src/ms_ovba/Models/Entities/reference_registered.py +++ b/src/ms_ovba/Models/Entities/reference_registered.py @@ -39,7 +39,7 @@ def unpack(data: bytes, endien: str) -> T: id, = struct.unpack_from(endien_symbol + "H", data, offset) offset += 2 if id != 0x000D: - msg = "Incorrect id in data. Received " + id + " but expected 0x000D" + msg = "Incorrect id in data. Received " + id + ", expected 0x000D" raise ValueError(msg) recordsize = struct.unpack_from(endien_symbol + "I", data, offset) From 03899bdd6b2a8ee987fb15cedf690adf6eaa5bb9 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 23:01:00 -0500 Subject: [PATCH 292/335] Update reference_registered.py --- src/ms_ovba/Models/Entities/reference_registered.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference_registered.py b/src/ms_ovba/Models/Entities/reference_registered.py index 3b22b71aa..51a154ad4 100644 --- a/src/ms_ovba/Models/Entities/reference_registered.py +++ b/src/ms_ovba/Models/Entities/reference_registered.py @@ -42,25 +42,26 @@ def unpack(data: bytes, endien: str) -> T: msg = "Incorrect id in data. Received " + id + ", expected 0x000D" raise ValueError(msg) - recordsize = struct.unpack_from(endien_symbol + "I", data, offset) + recordsize, = struct.unpack_from(endien_symbol + "I", data, offset) if len(data) != recordsize + 6: # raise a warning pass offset += 4 - libidsize = struct.unpack_from(endien_symbol + "I", data, offset) + libidsize, = struct.unpack_from(endien_symbol + "I", data, offset) offset += 4 libid_ref_bytes = data[offset:offset + libidsize] offset += libidsize - reserved1 = struct.unpack_from(endien_symbol + "I", data, offset) - offset += 4 + format = endien_symbol + "IH" + reserved1, reserved2 = struct.unpack_from(format, data, offset) + offset += 6 if reserved1 != 0: # raise a warning pass - reserved2 = struct.unpack_from(endien_symbol + "H", data, offset) + if reserved2 != 0: # raise a warning pass From 73b5998075261c8852630e9ae8acbd53f9fadf24 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 23:03:02 -0500 Subject: [PATCH 293/335] Update reference_registered.py --- src/ms_ovba/Models/Entities/reference_registered.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/ms_ovba/Models/Entities/reference_registered.py b/src/ms_ovba/Models/Entities/reference_registered.py index 51a154ad4..1288602cd 100644 --- a/src/ms_ovba/Models/Entities/reference_registered.py +++ b/src/ms_ovba/Models/Entities/reference_registered.py @@ -42,14 +42,13 @@ def unpack(data: bytes, endien: str) -> T: msg = "Incorrect id in data. Received " + id + ", expected 0x000D" raise ValueError(msg) - recordsize, = struct.unpack_from(endien_symbol + "I", data, offset) + format = endien_symbol + "II" + recordsize, libidsize = struct.unpack_from(format, data, offset) if len(data) != recordsize + 6: # raise a warning pass - offset += 4 - libidsize, = struct.unpack_from(endien_symbol + "I", data, offset) - offset += 4 + offset += 8 libid_ref_bytes = data[offset:offset + libidsize] offset += libidsize From 1974937de89fa56b60d3de287cbf25a84369c8ce Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 23:04:20 -0500 Subject: [PATCH 294/335] Update reference_registered.py --- src/ms_ovba/Models/Entities/reference_registered.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Entities/reference_registered.py b/src/ms_ovba/Models/Entities/reference_registered.py index 1288602cd..ea64c93bf 100644 --- a/src/ms_ovba/Models/Entities/reference_registered.py +++ b/src/ms_ovba/Models/Entities/reference_registered.py @@ -65,5 +65,5 @@ def unpack(data: bytes, endien: str) -> T: # raise a warning pass - libid_ref = LibidReference.create(libid_ref_bytes, endien) + libid_ref = LibidReference.unpack(libid_ref_bytes, endien) return ReferenceRegistered("", libid_ref) From c59eb09f13da892929877095236153f91b245443 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 23:31:20 -0500 Subject: [PATCH 295/335] Update libid_reference.py --- src/ms_ovba/Models/Fields/libid_reference.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/ms_ovba/Models/Fields/libid_reference.py b/src/ms_ovba/Models/Fields/libid_reference.py index 9eef6d86d..e8beac6bc 100644 --- a/src/ms_ovba/Models/Fields/libid_reference.py +++ b/src/ms_ovba/Models/Fields/libid_reference.py @@ -1,3 +1,4 @@ +import struct import uuid from typing import TypeVar @@ -47,5 +48,18 @@ def __str__(self: T) -> str: def __len__(self: T) -> int: return len(str(self)) + @staticmethod + def unpack(data: bytes): + guid, version, lcid, path, name = data.decode('ascii').split("#") + prefix = guid[:3] + guid = uuid.UUID(guid[3:]) + if prefix[:2] != "*\\": + raise Exception("Improper prefix") + kind = prefix[2:] + if kind != "G" and kind != "H": + raise Exception("Unknown Reference Kind") + return LibidReference(guid, version, lcid, + path, name) + def _is_windows_path(self: T, path: str) -> bool: return path[0] != '/' From 7d8b4730e003d62235052858b2339f8c55f94623 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 23:36:32 -0500 Subject: [PATCH 296/335] Update libid_reference.py --- src/ms_ovba/Models/Fields/libid_reference.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ms_ovba/Models/Fields/libid_reference.py b/src/ms_ovba/Models/Fields/libid_reference.py index e8beac6bc..ff492ee27 100644 --- a/src/ms_ovba/Models/Fields/libid_reference.py +++ b/src/ms_ovba/Models/Fields/libid_reference.py @@ -1,4 +1,3 @@ -import struct import uuid from typing import TypeVar @@ -60,6 +59,6 @@ def unpack(data: bytes): raise Exception("Unknown Reference Kind") return LibidReference(guid, version, lcid, path, name) - + def _is_windows_path(self: T, path: str) -> bool: return path[0] != '/' From cd37694e273aba9b84115cb8bae5186e4e1ebd0e Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 27 Feb 2026 23:37:34 -0500 Subject: [PATCH 297/335] Update reference_registered.py --- src/ms_ovba/Models/Entities/reference_registered.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ms_ovba/Models/Entities/reference_registered.py b/src/ms_ovba/Models/Entities/reference_registered.py index ea64c93bf..5b358a6dc 100644 --- a/src/ms_ovba/Models/Entities/reference_registered.py +++ b/src/ms_ovba/Models/Entities/reference_registered.py @@ -65,5 +65,5 @@ def unpack(data: bytes, endien: str) -> T: # raise a warning pass - libid_ref = LibidReference.unpack(libid_ref_bytes, endien) + libid_ref = LibidReference.unpack(libid_ref_bytes) return ReferenceRegistered("", libid_ref) From 913626a7aee5814e94b08cedbebcddbd16cf53da Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 20:29:20 -0500 Subject: [PATCH 298/335] Update test_vba_project.py (#119) Mocking Views Unit Tests --- tests/Unit/Views/test_project.py | 85 ++++++++++++++++++++++++ tests/{ => Unit}/Views/test_projectWm.py | 27 +++++--- tests/Unit/Views/test_vba_project.py | 35 ++++++++++ tests/Views/test_project.py | 55 --------------- tests/Views/test_vba_project.py | 13 ---- 5 files changed, 137 insertions(+), 78 deletions(-) create mode 100644 tests/Unit/Views/test_project.py rename tests/{ => Unit}/Views/test_projectWm.py (54%) create mode 100644 tests/Unit/Views/test_vba_project.py delete mode 100644 tests/Views/test_project.py delete mode 100644 tests/Views/test_vba_project.py diff --git a/tests/Unit/Views/test_project.py b/tests/Unit/Views/test_project.py new file mode 100644 index 000000000..6fae080d0 --- /dev/null +++ b/tests/Unit/Views/test_project.py @@ -0,0 +1,85 @@ +import unittest.mock +from ms_ovba.Views.project import Project +from typing import Type, TypeVar + + +T = TypeVar('T', bound='NotSoRandom') + + +class NotSoRandom(): + _rand = [] + + @classmethod + def set_seed(cls: Type[T], seeds: list) -> None: + cls._rand = seeds + + @classmethod + def randint(cls: Type[T], param1: int, param2: int) -> int: + return cls._rand.pop(0) + + +class Obj: + def __init__(self, name) -> None: + self.value = name + + +class Mod: + def __init__(self, name) -> None: + self.modName = Obj(name) + self.workspace = [0, 0, 0, 0, 'C'] + + def to_project_module_string(self): + return "Document" + "=" + self.modName.value + "/&H00000000" + + +class Mod1: + def __init__(self, name) -> None: + self.modName = Obj(name) + self.workspace = [26, 26, 1349, 522, 'Z'] + + def to_project_module_string(self): + return "Module=Module1" + + +class MockVbaProject: + def __init__(self) -> None: + mod1 = Mod1("Module1") + self.modules = [Mod("ThisWorkbook"), + Mod("Sheet1"), mod1] + self.project_id = '{9E394C0B-697E-4AEE-9FA6-446F51FB30DC}' + + def get_codepage_name(self): + return 'cp1252' + + def get_project_id(self): + return self.project_id + + def get_protection_state(self): + return b'\x00\x00\x00\x00' + + def get_password(self): + return b'\x00' + + def get_visibility_state(self): + return b'\xFF' + + +@unittest.mock.patch('random.randint', NotSoRandom.randint) +def test_blank() -> None: + rand = [0x41, 0xBC, 0x7B, 0x7B, 0x37, 0x7B, 0x7B, 0x7B] + NotSoRandom.set_seed(rand) + vba_project = MockVbaProject() + project = Project(vba_project) + project.add_attribute("HelpContextID", "0") + project.add_attribute("VersionCompatible32", "393222000") + + project.hostExtenderInfo = ("&H00000001=" + + "{3832D640-CF90-11CF-8E43-00A0C911005A};VBE;" + + "&H00000000") + file = open("tests/blank/vbaProject.bin", "rb") + file.seek(0x2180) + expected = file.read(0x0080) + file.seek(0x2400) + expected += file.read(0x0152) + + assert project.to_bytes() == expected diff --git a/tests/Views/test_projectWm.py b/tests/Unit/Views/test_projectWm.py similarity index 54% rename from tests/Views/test_projectWm.py rename to tests/Unit/Views/test_projectWm.py index e4f806e6f..65b359258 100644 --- a/tests/Views/test_projectWm.py +++ b/tests/Unit/Views/test_projectWm.py @@ -1,18 +1,25 @@ -from ms_ovba.vbaProject import VbaProject -from ms_ovba.Models.Entities.doc_module import DocModule -from ms_ovba.Models.Entities.std_module import StdModule from ms_ovba.Views.projectWm import ProjectWm +class Obj: + def __init__(self, name) -> None: + self.value = name + + +class Mod: + def __init__(self, name) -> None: + self.modName = Obj(name) + + +class MockVbaProject: + def __init__(self) -> None: + self.modules = [Mod("ThisWorkbook"), Mod("Sheet1"), Mod("Module1")] + + def test_project_wm() -> None: - vba_project = VbaProject() + vba_project = MockVbaProject() project_wm = ProjectWm(vba_project) - this_workbook = DocModule("ThisWorkbook") - sheet1 = DocModule("Sheet1") - module1 = StdModule("Module1") - vba_project.add_module(this_workbook) - vba_project.add_module(sheet1) - vba_project.add_module(module1) + expected = (b'ThisWorkbook\x00T\x00h\x00i\x00s\x00W\x00o\x00r\x00k\x00b' + b'\x00o\x00o\x00k\x00\x00\x00Sheet1\x00S\x00h\x00e\x00e\x00' + b't\x001\x00\x00\x00Module1\x00M\x00o\x00d\x00u\x00l\x00e' diff --git a/tests/Unit/Views/test_vba_project.py b/tests/Unit/Views/test_vba_project.py new file mode 100644 index 000000000..3a2e6d35c --- /dev/null +++ b/tests/Unit/Views/test_vba_project.py @@ -0,0 +1,35 @@ +from ms_ovba.Views.project_view import ProjectView + + +class MockVbaProject(): + + def __init__(self) -> None: + self.endien = 'little' + self.performance_cache = b'' + self.performance_cache_version = 0xFFFF + + def get_performance_cache(self) -> bytes: + return self.performance_cache + + def get_performance_cache_version(self): + return self.performance_cache_version + + +def test_vba_project_default() -> None: + vba_project = MockVbaProject() + vba_project_view = ProjectView(vba_project) + expected = b'\xCC\x61\xFF\xFF\x00\x03\x00' + assert vba_project_view.to_bytes() == expected + + +def test_vba_project() -> None: + """ + Demonstrate the effect of performance cache on the project + """ + vba_project = MockVbaProject() + vba_project.performance_cache = b'\x00\x01\x02\x03' + vba_project.performance_cache_version = 0x00B5 + + vba_project_view = ProjectView(vba_project) + expected = b'\xCC\x61\xB5\x00\x00\x03\x00\x00\x01\x02\x03' + assert vba_project_view.to_bytes() == expected diff --git a/tests/Views/test_project.py b/tests/Views/test_project.py deleted file mode 100644 index df3a42167..000000000 --- a/tests/Views/test_project.py +++ /dev/null @@ -1,55 +0,0 @@ -import unittest.mock - -from ms_ovba.vbaProject import VbaProject -from ms_ovba.Models.Entities.doc_module import DocModule -from ms_ovba.Models.Entities.std_module import StdModule -from ms_ovba.Views.project import Project -from typing import Type, TypeVar - - -T = TypeVar('T', bound='NotSoRandom') - - -class NotSoRandom(): - _rand = [] - - @classmethod - def set_seed(cls: Type[T], seeds: list) -> None: - cls._rand = seeds - - @classmethod - def randint(cls: Type[T], param1: int, param2: int) -> int: - return cls._rand.pop(0) - - -@unittest.mock.patch('random.randint', NotSoRandom.randint) -def test_blank() -> None: - rand = [0x41, 0xBC, 0x7B, 0x7B, 0x37, 0x7B, 0x7B, 0x7B] - NotSoRandom.set_seed(rand) - vba_project = VbaProject() - vba_project.set_project_id('{9E394C0B-697E-4AEE-9FA6-446F51FB30DC}') - project = Project(vba_project) - project.add_attribute("HelpContextID", "0") - project.add_attribute("VersionCompatible32", "393222000") - - project.hostExtenderInfo = ("&H00000001=" - + "{3832D640-CF90-11CF-8E43-00A0C911005A};VBE;" - + "&H00000000") - - this_workbook = DocModule("ThisWorkbook") - sheet1 = DocModule("Sheet1") - module1 = StdModule("Module1") - module1.add_workspace(26, 26, 1349, 522, 'Z') - - vba_project.add_module(this_workbook) - vba_project.add_module(sheet1) - vba_project.add_module(module1) - - # expected = Path("tests/blank/vbaProject.bin").read_text() - file = open("tests/blank/vbaProject.bin", "rb") - file.seek(0x2180) - expected = file.read(0x0080) - file.seek(0x2400) - expected += file.read(0x0152) - - assert project.to_bytes() == expected diff --git a/tests/Views/test_vba_project.py b/tests/Views/test_vba_project.py deleted file mode 100644 index 3893a79c3..000000000 --- a/tests/Views/test_vba_project.py +++ /dev/null @@ -1,13 +0,0 @@ -from ms_ovba.vbaProject import VbaProject -from ms_ovba.Views.project_view import ProjectView - - -def test_vba_project() -> None: - vba_project = VbaProject() - vba_project_view = ProjectView(vba_project) - expected = b'\xCC\x61\xFF\xFF\x00\x03\x00' - assert vba_project_view.to_bytes() == expected - vba_project.set_performance_cache(b'\x00\x01\x02\x03') - vba_project.set_performance_cache_version(0x00B5) - expected = b'\xCC\x61\xB5\x00\x00\x03\x00\x00\x01\x02\x03' - assert vba_project_view.to_bytes() == expected From 89b94b8a39542b16d22bb231e4c693d0edb04aa7 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 20:46:43 -0500 Subject: [PATCH 299/335] Update test_reference_registered.py --- .../Entities/test_reference_registered.py | 30 +++++++------------ 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index 0cc05a9a4..a99c77dfc 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -3,29 +3,21 @@ from ms_ovba.Models.Fields.libid_reference import LibidReference +class MockLibid: + def __str__(): + return ("*{00020430-0000-0000-C000-000000000046}#2.0#0#" + + "C:\\Windows\\system32\\stdole2.tlb#OLE Automation") + def unpack(data, endien): + self.data = data + + def test_constructor() -> None: - guid = uuid.UUID('0002043000000000C000000000000046') - ref = LibidReference( - guid, - "2.0", - "0", - "C:\\Windows\\system32\\stdole2.tlb", - "OLE Automation" - ) + ref = MockLibid() module = ReferenceRegistered("cp1", ref) assert isinstance(module, ReferenceRegistered) -def test_pack() -> None: - guid = uuid.UUID('0002043000000000C000000000000046') - ref = LibidReference( - guid, - "2.0", - "0", - "C:\\Windows\\system32\\stdole2.tlb", - "OLE Automation" - ) - +def test_pack() -> None expected_hex = ("0D 00 68 00 00 00 5E 00 00 00 2A 5C 47 7B 30 30", "30 32 30 34 33 30 2D 30 30 30 30 2D 30 30 30 30", "2D 43 30 30 30 2D 30 30 30 30 30 30 30 30 30 30", @@ -36,7 +28,7 @@ def test_pack() -> None: expected = bytes.fromhex(" ".join(expected_hex)) codepage = 0x04E4 codepage_name = "cp" + str(codepage) - ref_reg = ReferenceRegistered(codepage_name, ref) + ref_reg = ReferenceRegistered(codepage_name, MockLibid()) results = ref_reg.pack(codepage_name, 'little') assert results == expected From 1aa6360d0b8e4c5ac35a6301eb099a1b2d3bb49f Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 20:53:43 -0500 Subject: [PATCH 300/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index a99c77dfc..f384b2834 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -17,7 +17,7 @@ def test_constructor() -> None: assert isinstance(module, ReferenceRegistered) -def test_pack() -> None +def test_pack() -> None: expected_hex = ("0D 00 68 00 00 00 5E 00 00 00 2A 5C 47 7B 30 30", "30 32 30 34 33 30 2D 30 30 30 30 2D 30 30 30 30", "2D 43 30 30 30 2D 30 30 30 30 30 30 30 30 30 30", From 4c578015301a7fee1e145b2256b80daffd676bb7 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 20:56:40 -0500 Subject: [PATCH 301/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index f384b2834..1ea1121f4 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -6,7 +6,9 @@ class MockLibid: def __str__(): return ("*{00020430-0000-0000-C000-000000000046}#2.0#0#" + - "C:\\Windows\\system32\\stdole2.tlb#OLE Automation") + "C:\\Windows\\system32\\stdole2.tlb#OLE Automation") + + @staticmethod def unpack(data, endien): self.data = data From ce99b6347334b0fead150dac2beed9385b63fe79 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 20:58:18 -0500 Subject: [PATCH 302/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index 1ea1121f4..0fff61e41 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -7,9 +7,8 @@ class MockLibid: def __str__(): return ("*{00020430-0000-0000-C000-000000000046}#2.0#0#" + "C:\\Windows\\system32\\stdole2.tlb#OLE Automation") - - @staticmethod - def unpack(data, endien): + + def unpack(self, data, endien): self.data = data From b723a60ff53208c4fae4c7d8d4d2400e7a38e816 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 21:14:09 -0500 Subject: [PATCH 303/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index 0fff61e41..f9945b9b3 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -1,6 +1,5 @@ -import uuid from ms_ovba.Models.Entities.reference_registered import ReferenceRegistered -from ms_ovba.Models.Fields.libid_reference import LibidReference +from unittest.mock import patch class MockLibid: @@ -34,7 +33,8 @@ def test_pack() -> None: assert results == expected -def test_unpack() -> None: +def test_unpack() + with mock.patch('ms_ovba.Models.Entities.reference_registered.LibidReference', MockLibid): hex = ("0D 00 68 00 00 00 5E 00 00 00 2A 5C 47 7B 30 30", "30 32 30 34 33 30 2D 30 30 30 30 2D 30 30 30 30", "2D 43 30 30 30 2D 30 30 30 30 30 30 30 30 30 30", @@ -44,4 +44,5 @@ def test_unpack() -> None: "74 6F 6D 61 74 69 6F 6E 00 00 00 00 00 00") data = bytes.fromhex(" ".join(hex)) ref = ReferenceRegistered.unpack(data, "little") - assert isinstance(ref.libid, LibidReference) + assert ref.libid.data == (b'*{00020430-0000-0000-C000-000000000046}#2.0#0#' + + b'C:\Windows\system32\stdole2.tlb#OLE Automation') From f02ce840c3c0f6687d6443ed3873e76e0704e2dc Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 21:15:40 -0500 Subject: [PATCH 304/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index f9945b9b3..f609d9c71 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -2,17 +2,19 @@ from unittest.mock import patch -class MockLibid: +class MockLibid1: def __str__(): return ("*{00020430-0000-0000-C000-000000000046}#2.0#0#" + "C:\\Windows\\system32\\stdole2.tlb#OLE Automation") + +class MockLibid2: def unpack(self, data, endien): self.data = data def test_constructor() -> None: - ref = MockLibid() + ref = MockLibid1() module = ReferenceRegistered("cp1", ref) assert isinstance(module, ReferenceRegistered) @@ -34,7 +36,7 @@ def test_pack() -> None: def test_unpack() - with mock.patch('ms_ovba.Models.Entities.reference_registered.LibidReference', MockLibid): + with mock.patch('ms_ovba.Models.Entities.reference_registered.LibidReference', MockLibid2): hex = ("0D 00 68 00 00 00 5E 00 00 00 2A 5C 47 7B 30 30", "30 32 30 34 33 30 2D 30 30 30 30 2D 30 30 30 30", "2D 43 30 30 30 2D 30 30 30 30 30 30 30 30 30 30", From 97d03d11897e2ce4926d6f7f3ff99d62fe65e53f Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 21:16:11 -0500 Subject: [PATCH 305/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index f609d9c71..ef733f06e 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -30,7 +30,7 @@ def test_pack() -> None: expected = bytes.fromhex(" ".join(expected_hex)) codepage = 0x04E4 codepage_name = "cp" + str(codepage) - ref_reg = ReferenceRegistered(codepage_name, MockLibid()) + ref_reg = ReferenceRegistered(codepage_name, MockLibid1()) results = ref_reg.pack(codepage_name, 'little') assert results == expected From 307ac23e91d06baa9af6cd62deb4d71e187ea6d6 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 21:17:07 -0500 Subject: [PATCH 306/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index ef733f06e..b492b3788 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -35,7 +35,7 @@ def test_pack() -> None: assert results == expected -def test_unpack() +def test_unpack(): with mock.patch('ms_ovba.Models.Entities.reference_registered.LibidReference', MockLibid2): hex = ("0D 00 68 00 00 00 5E 00 00 00 2A 5C 47 7B 30 30", "30 32 30 34 33 30 2D 30 30 30 30 2D 30 30 30 30", From 7fa6c6a1efe4754961bbc62d6644b4ae39565148 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 21:24:33 -0500 Subject: [PATCH 307/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index b492b3788..068fea946 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -36,7 +36,6 @@ def test_pack() -> None: def test_unpack(): - with mock.patch('ms_ovba.Models.Entities.reference_registered.LibidReference', MockLibid2): hex = ("0D 00 68 00 00 00 5E 00 00 00 2A 5C 47 7B 30 30", "30 32 30 34 33 30 2D 30 30 30 30 2D 30 30 30 30", "2D 43 30 30 30 2D 30 30 30 30 30 30 30 30 30 30", @@ -45,6 +44,7 @@ def test_unpack(): "64 6F 6C 65 32 2E 74 6C 62 23 4F 4C 45 20 41 75", "74 6F 6D 61 74 69 6F 6E 00 00 00 00 00 00") data = bytes.fromhex(" ".join(hex)) - ref = ReferenceRegistered.unpack(data, "little") - assert ref.libid.data == (b'*{00020430-0000-0000-C000-000000000046}#2.0#0#' + - b'C:\Windows\system32\stdole2.tlb#OLE Automation') + with mock.patch('ms_ovba.Models.Entities.reference_registered.LibidReference', MockLibid2): + ref = ReferenceRegistered.unpack(data, "little") + assert ref.libid.data == (b'*{00020430-0000-0000-C000-000000000046}#2.0#0#' + + b'C:\Windows\system32\stdole2.tlb#OLE Automation') From b2e83fe2fb2cfdf3c4750715acb4baa52f418b4c Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 21:26:37 -0500 Subject: [PATCH 308/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index 068fea946..c3e230b16 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -1,5 +1,5 @@ +import unittest.mock from ms_ovba.Models.Entities.reference_registered import ReferenceRegistered -from unittest.mock import patch class MockLibid1: From d8a47a508b8eb391bc4eb811ea2b1c39db147ec6 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 21:28:22 -0500 Subject: [PATCH 309/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index c3e230b16..ce592ac72 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -47,4 +47,4 @@ def test_unpack(): with mock.patch('ms_ovba.Models.Entities.reference_registered.LibidReference', MockLibid2): ref = ReferenceRegistered.unpack(data, "little") assert ref.libid.data == (b'*{00020430-0000-0000-C000-000000000046}#2.0#0#' + - b'C:\Windows\system32\stdole2.tlb#OLE Automation') + b'C:\\Windows\\system32\\stdole2.tlb#OLE Automation') From c2f65356b9cb581060fee4b878309db4c35f5029 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 21:32:05 -0500 Subject: [PATCH 310/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index ce592ac72..6f9273e2d 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -44,7 +44,9 @@ def test_unpack(): "64 6F 6C 65 32 2E 74 6C 62 23 4F 4C 45 20 41 75", "74 6F 6D 61 74 69 6F 6E 00 00 00 00 00 00") data = bytes.fromhex(" ".join(hex)) - with mock.patch('ms_ovba.Models.Entities.reference_registered.LibidReference', MockLibid2): + path = 'ms_ovba.Models.Entities.reference_registered.LibidReference' + with mock.patch(path, MockLibid2): ref = ReferenceRegistered.unpack(data, "little") - assert ref.libid.data == (b'*{00020430-0000-0000-C000-000000000046}#2.0#0#' + - b'C:\\Windows\\system32\\stdole2.tlb#OLE Automation') + assert ref.libid.data == (b'*{00020430-0000-0000-C000-000000000046}" + + b'#2.0#0#C:\\Windows\\system32\\stdole2.tlb#' + + b'OLE Automation') From 48386bda2925a7aa6d320ab4a29d0c335943967a Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 21:33:34 -0500 Subject: [PATCH 311/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index 6f9273e2d..bc8895b33 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -47,6 +47,6 @@ def test_unpack(): path = 'ms_ovba.Models.Entities.reference_registered.LibidReference' with mock.patch(path, MockLibid2): ref = ReferenceRegistered.unpack(data, "little") - assert ref.libid.data == (b'*{00020430-0000-0000-C000-000000000046}" + + assert ref.libid.data == (b'*{00020430-0000-0000-C000-000000000046}' + b'#2.0#0#C:\\Windows\\system32\\stdole2.tlb#' + b'OLE Automation') From ecc98b537873e601f7c9c0dffb7ac720b65ab611 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 21:38:57 -0500 Subject: [PATCH 312/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index bc8895b33..4d8120a9f 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -48,5 +48,6 @@ def test_unpack(): with mock.patch(path, MockLibid2): ref = ReferenceRegistered.unpack(data, "little") assert ref.libid.data == (b'*{00020430-0000-0000-C000-000000000046}' + - b'#2.0#0#C:\\Windows\\system32\\stdole2.tlb#' + + b'#2.0#0#' + + b'C:\\Windows\\system32\\stdole2.tlb#' + b'OLE Automation') From 086f9def893beb0211cf20ece1403b60dcb13ff3 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 21:40:32 -0500 Subject: [PATCH 313/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index 4d8120a9f..46329641a 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -1,4 +1,4 @@ -import unittest.mock +from unittest import mock from ms_ovba.Models.Entities.reference_registered import ReferenceRegistered From 8a32019c1d575ada2fae498f70e86e9731591495 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 21:42:35 -0500 Subject: [PATCH 314/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index 46329641a..fa1608ed3 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -3,6 +3,9 @@ class MockLibid1: + def __len__(): + return x005E + def __str__(): return ("*{00020430-0000-0000-C000-000000000046}#2.0#0#" + "C:\\Windows\\system32\\stdole2.tlb#OLE Automation") From 77545c8a814ccf6d14e81084429d28e3863dc8f7 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 21:44:05 -0500 Subject: [PATCH 315/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index fa1608ed3..a93e801a7 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -7,7 +7,7 @@ def __len__(): return x005E def __str__(): - return ("*{00020430-0000-0000-C000-000000000046}#2.0#0#" + + return ("*\\G{00020430-0000-0000-C000-000000000046}#2.0#0#" + "C:\\Windows\\system32\\stdole2.tlb#OLE Automation") From 3c94a9702926397cd79abf9e85827a6163874315 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 21:46:28 -0500 Subject: [PATCH 316/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index a93e801a7..bae4dab7b 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -4,7 +4,7 @@ class MockLibid1: def __len__(): - return x005E + return 0x005E def __str__(): return ("*\\G{00020430-0000-0000-C000-000000000046}#2.0#0#" + From 922347b2d4977ca58013f6487273d89ad00e5d83 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 21:47:42 -0500 Subject: [PATCH 317/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index bae4dab7b..947bbb3c6 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -3,10 +3,10 @@ class MockLibid1: - def __len__(): + def __len__(self): return 0x005E - def __str__(): + def __str__(self): return ("*\\G{00020430-0000-0000-C000-000000000046}#2.0#0#" + "C:\\Windows\\system32\\stdole2.tlb#OLE Automation") From 78fdd7d402cca273808156aa75e79d7bac989e45 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 21:50:06 -0500 Subject: [PATCH 318/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index 947bbb3c6..7274cb5dc 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -13,7 +13,9 @@ def __str__(self): class MockLibid2: def unpack(self, data, endien): - self.data = data + lib = MockLibid2() + lib.data = data + return lib def test_constructor() -> None: From 5bfcebcfaa030c63bdf33013460a12e9888f50d4 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 21:50:43 -0500 Subject: [PATCH 319/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index 7274cb5dc..a7b399336 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -12,7 +12,9 @@ def __str__(self): class MockLibid2: - def unpack(self, data, endien): + + @staticmethod + def unpack(data, endien): lib = MockLibid2() lib.data = data return lib From 0ea876109d0af4c73b2a013079d37845a3bfe91d Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 21:51:02 -0500 Subject: [PATCH 320/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index a7b399336..1ce9b75b6 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -12,7 +12,6 @@ def __str__(self): class MockLibid2: - @staticmethod def unpack(data, endien): lib = MockLibid2() From 8db3bcad16bca06f8df031930864a0c9b807b884 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 21:52:11 -0500 Subject: [PATCH 321/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index 1ce9b75b6..e5fd4d2e5 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -13,7 +13,7 @@ def __str__(self): class MockLibid2: @staticmethod - def unpack(data, endien): + def unpack(data): lib = MockLibid2() lib.data = data return lib From 1d71234e025338cb9e0645458b80008b680a34bd Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 21:54:36 -0500 Subject: [PATCH 322/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index e5fd4d2e5..df40f840f 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -53,7 +53,7 @@ def test_unpack(): path = 'ms_ovba.Models.Entities.reference_registered.LibidReference' with mock.patch(path, MockLibid2): ref = ReferenceRegistered.unpack(data, "little") - assert ref.libid.data == (b'*{00020430-0000-0000-C000-000000000046}' + + assert ref.libid.data == (b'*\\G{00020430-0000-0000-C000-000000000046}' + b'#2.0#0#' + b'C:\\Windows\\system32\\stdole2.tlb#' + b'OLE Automation') From 2d48aee72307956b2163fbdd0b9bfd8295042af2 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 21:56:14 -0500 Subject: [PATCH 323/335] Update test_reference_registered.py --- tests/Unit/Models/Entities/test_reference_registered.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index df40f840f..1287e05e6 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -53,7 +53,7 @@ def test_unpack(): path = 'ms_ovba.Models.Entities.reference_registered.LibidReference' with mock.patch(path, MockLibid2): ref = ReferenceRegistered.unpack(data, "little") - assert ref.libid.data == (b'*\\G{00020430-0000-0000-C000-000000000046}' + - b'#2.0#0#' + + assert ref.libid.data == (b'*\\G{00020430-0000-0000-C000-' + + b'000000000046}#2.0#0#' + b'C:\\Windows\\system32\\stdole2.tlb#' + b'OLE Automation') From b5b0b7cd35848feed58b4a361c5acc722b077baa Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 22:07:34 -0500 Subject: [PATCH 324/335] Update test_reference_project.py --- tests/Unit/Models/Entities/test_reference_project.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/Unit/Models/Entities/test_reference_project.py b/tests/Unit/Models/Entities/test_reference_project.py index ee5c29d58..49bc341e4 100644 --- a/tests/Unit/Models/Entities/test_reference_project.py +++ b/tests/Unit/Models/Entities/test_reference_project.py @@ -1,5 +1,4 @@ from ms_ovba.Models.Entities.reference_project import ReferenceProject -from ms_ovba.Models.Fields.project_reference import ProjectReference def test_constructor() -> None: @@ -9,8 +8,16 @@ def test_constructor() -> None: assert isinstance(module, ReferenceProject) +class MockProjectReference: + def __len__(): + return 0x0030 + + def __str__(self): + return "*\\CC:\\Example Path\\Example-ReferencedProject.xls" + + def test_pack() -> None: - ref = ProjectReference("C:\\Example Path\\Example-ReferencedProject.xls") + ref = MockProjectReference() expected_hex = ("0E 00 5E 00 00 00 30 00 00 00 2A 5C 43 43 3A 5C", "45 78 61 6D 70 6C 65 20 50 61 74 68 5C 45 78 61", From e31b0b42b0767b3b523c69c3cbae027ee16258d3 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 22:09:31 -0500 Subject: [PATCH 325/335] Update test_reference_project.py --- tests/Unit/Models/Entities/test_reference_project.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/Unit/Models/Entities/test_reference_project.py b/tests/Unit/Models/Entities/test_reference_project.py index 49bc341e4..f72a833b8 100644 --- a/tests/Unit/Models/Entities/test_reference_project.py +++ b/tests/Unit/Models/Entities/test_reference_project.py @@ -2,9 +2,8 @@ def test_constructor() -> None: - ref = ProjectReference("C:\\Example Path\\Example-ReferencedProject.xls") + ref = MockProjectReference() module = ReferenceProject("cp1", ref) - assert isinstance(module, ReferenceProject) From f536df99d9af571e8f52ef0e7a75d6db48436a8e Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 22:12:26 -0500 Subject: [PATCH 326/335] Update test_reference_project.py --- tests/Unit/Models/Entities/test_reference_project.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/Unit/Models/Entities/test_reference_project.py b/tests/Unit/Models/Entities/test_reference_project.py index f72a833b8..4cf349040 100644 --- a/tests/Unit/Models/Entities/test_reference_project.py +++ b/tests/Unit/Models/Entities/test_reference_project.py @@ -14,6 +14,9 @@ def __len__(): def __str__(self): return "*\\CC:\\Example Path\\Example-ReferencedProject.xls" + def relative(self): + return "Example-ReferencedProject.xls" + def test_pack() -> None: ref = MockProjectReference() From e699b8de5eec8e643c424f371fb01ce16f07b8f5 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 22:14:48 -0500 Subject: [PATCH 327/335] Update test_reference_project.py --- tests/Unit/Models/Entities/test_reference_project.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_reference_project.py b/tests/Unit/Models/Entities/test_reference_project.py index 4cf349040..58a3402ad 100644 --- a/tests/Unit/Models/Entities/test_reference_project.py +++ b/tests/Unit/Models/Entities/test_reference_project.py @@ -7,6 +7,14 @@ def test_constructor() -> None: assert isinstance(module, ReferenceProject) +class MockProjectReference2: + def __len__(): + return 0x0020 + + def __str__(self): + return "Example-ReferencedProject.xls" + + class MockProjectReference: def __len__(): return 0x0030 @@ -15,7 +23,7 @@ def __str__(self): return "*\\CC:\\Example Path\\Example-ReferencedProject.xls" def relative(self): - return "Example-ReferencedProject.xls" + return MockProjectReference2() def test_pack() -> None: From c099bd3cbec7d74c37caf69b33bb863c0392cc5d Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 22:15:40 -0500 Subject: [PATCH 328/335] Update test_reference_project.py --- tests/Unit/Models/Entities/test_reference_project.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Models/Entities/test_reference_project.py b/tests/Unit/Models/Entities/test_reference_project.py index 58a3402ad..ba1416ba2 100644 --- a/tests/Unit/Models/Entities/test_reference_project.py +++ b/tests/Unit/Models/Entities/test_reference_project.py @@ -12,7 +12,7 @@ def __len__(): return 0x0020 def __str__(self): - return "Example-ReferencedProject.xls" + return "*\\CExample-ReferencedProject.xls" class MockProjectReference: From ad633bd17faf12fb141d65ee5ec76aa0e3569f30 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 22:16:48 -0500 Subject: [PATCH 329/335] Update test_reference_project.py --- tests/Unit/Models/Entities/test_reference_project.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Unit/Models/Entities/test_reference_project.py b/tests/Unit/Models/Entities/test_reference_project.py index ba1416ba2..c3008e028 100644 --- a/tests/Unit/Models/Entities/test_reference_project.py +++ b/tests/Unit/Models/Entities/test_reference_project.py @@ -8,7 +8,7 @@ def test_constructor() -> None: class MockProjectReference2: - def __len__(): + def __len__(self): return 0x0020 def __str__(self): @@ -16,7 +16,7 @@ def __str__(self): class MockProjectReference: - def __len__(): + def __len__(self): return 0x0030 def __str__(self): From ff8017fa76fb616091cc02b256cd2df7b7b347f7 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sat, 28 Feb 2026 23:17:14 -0500 Subject: [PATCH 330/335] Update test_libidReference.py (#121) * libid coverage --- .../Unit/Models/Fields/test_libidReference.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/Unit/Models/Fields/test_libidReference.py b/tests/Unit/Models/Fields/test_libidReference.py index 3b2afddf6..c812cac0f 100644 --- a/tests/Unit/Models/Fields/test_libidReference.py +++ b/tests/Unit/Models/Fields/test_libidReference.py @@ -1,4 +1,5 @@ import uuid +import pytest from ms_ovba.Models.Fields.libid_reference import LibidReference @@ -29,3 +30,21 @@ def test_posix() -> None: expected = ("*\\H{00020430-0000-0000-C000-000000000046}" "#2.0#0#//usr/bin/stdole2.tlb#OLE Automation") assert str(libid_ref) == expected + + +def test_unpack() -> None: + data = (b'*\\G{00020430-0000-0000-C000-000000000046}' + b'#2.0#0#C:\\Windows\\System32\\stdole2.tlb#OLE Automation') + lib = LibidReference.unpack(data) + assert lib._version == "2.0" + + +@pytest.mark.parametrize("data", [ + (b'*\\A{00020430-0000-0000-C000-000000000046}' + b'#2.0#0#C:\\Windows\\System32\\stdole2.tlb#OLE Automation'), + (b'+\\G{00020430-0000-0000-C000-000000000046}' + b'#2.0#0#C:\\Windows\\System32\\stdole2.tlb#OLE Automation'), +]) +def test_unpack_exception(data) -> None: + with pytest.raises(Exception): + LibidReference.unpack(data) From 37641d0745ab4f3fc5f106657867cb194fa9de43 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sun, 1 Mar 2026 17:10:58 -0500 Subject: [PATCH 331/335] Update project_ole_file.py (#122) * Add Mocks * Change Views to be Static --- src/ms_ovba/Views/dirStream.py | 32 +++++++-------- src/ms_ovba/Views/project_ole_file.py | 34 ++++++++-------- src/ms_ovba/__main__.py | 3 +- .../{test_dirObject.py => test_dirObject.pyt} | 0 tests/Unit/Models/Entities/test_reference.py | 40 ++++++++++++------- 5 files changed, 59 insertions(+), 50 deletions(-) rename tests/Functional/{test_dirObject.py => test_dirObject.pyt} (100%) diff --git a/src/ms_ovba/Views/dirStream.py b/src/ms_ovba/Views/dirStream.py index 657105d18..db22fb96f 100644 --- a/src/ms_ovba/Views/dirStream.py +++ b/src/ms_ovba/Views/dirStream.py @@ -6,7 +6,7 @@ DoubleEncodedString ) from ms_ovba.Models.Fields.packed_data import PackedData -from typing import TypeVar +from typing import List, TypeVar T = TypeVar('T', bound='DirStream') @@ -19,32 +19,29 @@ class DirStream(): def __init__(self: T, project: VbaProject) -> None: self.project = project - self.information = [] - self.references = [] - self.modules = [] self._include_compat = False def to_bytes(self: T) -> bytes: - self._load_information() + information = self._load_information() endien = self.project.endien codepage_name = self.project.get_codepage_name() pack_symbol = '<' if endien == 'little' else '>' # should be 0xFFFF cookie_value = self.project.get_project_cookie() self.project_cookie = IdSizeField(19, 2, cookie_value) - self.references = self.project.references - self.modules = self.project.modules + references = self.project.references + modules = self.project.modules output = b'' - for record in self.information: + for record in information: output += record.pack(codepage_name, endien) - for record in self.references: + for record in references: output += record.pack(codepage_name, endien) - modules_header = IdSizeField(0x000F, 2, len(self.modules)) + modules_header = IdSizeField(0x000F, 2, len(modules)) output += (modules_header.pack(codepage_name, endien) + self.project_cookie.pack(codepage_name, endien)) - for record in self.modules: + for record in modules: output += record.pack(codepage_name, endien) output += struct.pack(pack_symbol + "HI", 16, 0) return output @@ -59,14 +56,14 @@ def write_file(self: T) -> None: bin_f.write(compressed) bin_f.close() - def _load_information(self: T) -> None: - self.codepage = 0x04E4 + def _load_information(self: T) -> List: + codepage = 0x04E4 # 0=16bit, 1=32bit, 2=mac, 3=64bit syskind = IdSizeField(1, 4, 3) compat_version = IdSizeField(74, 4, 3) lcid = IdSizeField(2, 4, 0x0409) lcid_invoke = IdSizeField(20, 4, 0x0409) - codepage_record = IdSizeField(3, 2, self.codepage) + codepage_record = IdSizeField(3, 2, codepage) project_name = IdSizeField(4, 10, "VBAProject") docstring = DoubleEncodedString([5, 0x0040], "") helpfile = DoubleEncodedString([6, 0x003D], "") @@ -76,10 +73,10 @@ def _load_information(self: T) -> None: minor_version = PackedData("H", 17) constants = DoubleEncodedString([12, 0x003C], "") - self.information = [syskind] + information = [syskind] if self._include_compat: - self.information.append(compat_version) - self.information.extend([ + information.append(compat_version) + information.extend([ lcid, lcid_invoke, codepage_record, @@ -92,3 +89,4 @@ def _load_information(self: T) -> None: minor_version, constants ]) + return information diff --git a/src/ms_ovba/Views/project_ole_file.py b/src/ms_ovba/Views/project_ole_file.py index f7ac048f7..b88c52e26 100644 --- a/src/ms_ovba/Views/project_ole_file.py +++ b/src/ms_ovba/Views/project_ole_file.py @@ -15,10 +15,8 @@ class ProjectOleFile: - def __init__(self: T, project: VbaProject) -> None: - self._project = project - - def _build_ole_directory(self: T) -> RootDirectory: + @staticmethod + def _build_ole_directory(project: VbaProject) -> RootDirectory: """ Create all the custom views for the OLE file: dir @@ -29,44 +27,46 @@ def _build_ole_directory(self: T) -> RootDirectory: Organize the modules and views into the correct storage directories """ directory = RootDirectory() - directory.set_modified(self._project.default_date) + directory.set_modified(project.default_date) storage = StorageDirectory("VBA") - storage.set_created(self._project.default_date) - storage.set_modified(self._project.default_date) - for module in self._project.get_modules(): + storage.set_created(project.default_date) + storage.set_modified(project.default_date) + for module in project.get_modules(): module.write_file() dir = StreamDirectory(module.get_name(), module.get_bin_path()) storage.add_directory(dir) - module = DirStream(self._project) + module = DirStream(project) module.write_file() dir = StreamDirectory("dir", "dir.bin") storage.add_directory(dir) - module = ProjectView(self._project) + module = ProjectView(project) module.write_file() dir = StreamDirectory("_VBA_PROJECT", "vba_project.bin") storage.add_directory(dir) directory.add_directory(storage) - if self._project.get_include_projectwm(): - module = ProjectWm(self._project) + if project.get_include_projectwm(): + module = ProjectWm(project) module.write_file() stream = StreamDirectory("PROJECTwm", "projectwm.bin") directory.add_directory(stream) - module = Project(self._project) + module = Project(project) module.write_file() stream = StreamDirectory("PROJECT", "project.bin") directory.add_directory(stream) return directory - def _write_ole_file(self: T, root: RootDirectory) -> None: + @staticmethod + def _write_ole_file(root: RootDirectory) -> None: ole_file = OleFile() ole_file.root_directory = root ole_file.create_file("vbaProject.bin") - def write_file(self: T) -> None: - directory = self._build_ole_directory() - self._write_ole_file(directory) + @staticmethod + def write_file(project: VbaProject) -> None: + directory = ProjectOleFile._build_ole_directory(project) + ProjectOleFile._write_ole_file(directory) diff --git a/src/ms_ovba/__main__.py b/src/ms_ovba/__main__.py index 0f98616e4..f2be899c7 100644 --- a/src/ms_ovba/__main__.py +++ b/src/ms_ovba/__main__.py @@ -71,8 +71,7 @@ def main() -> None: office_reference = ReferenceRecord(codepage_name, "Office", libid_ref2) project.add_reference(ole_reference) project.add_reference(office_reference) - ole_file = ProjectOleFile(project) - ole_file.write_file() + ProjectOleFile.write_file(project) file = glob.glob('vbaProject.bin') diff --git a/tests/Functional/test_dirObject.py b/tests/Functional/test_dirObject.pyt similarity index 100% rename from tests/Functional/test_dirObject.py rename to tests/Functional/test_dirObject.pyt diff --git a/tests/Unit/Models/Entities/test_reference.py b/tests/Unit/Models/Entities/test_reference.py index 831c9466e..92b614392 100644 --- a/tests/Unit/Models/Entities/test_reference.py +++ b/tests/Unit/Models/Entities/test_reference.py @@ -1,28 +1,38 @@ from ms_ovba.Models.Entities.reference import Reference -from ms_ovba.Models.Entities.reference_project import ReferenceProject -from ms_ovba.Models.Fields.project_reference import ProjectReference +from unittest import mock + + +class MockDEString: + def __init__(self, foo, bar) -> None: + pass + + def pack(self, one, two) -> bytes: + return (b'\x16\x00\x0B\x00\x00\x00VBAProject1' + + b'\x3E\x00\x16\x00\x00\x00V\x00B\x00A\x00P\x00r' + + b'\x00o\x00j\x00e\x00c\x00t\x001\x00') + + +class MockRefProj: + def pack(self, foo, bar) -> bytes: + return (b'\x0e\x00^\x00\x00\x000\x00\x00\x00' + + b'*\\CC:\\Example Path\\Example-ReferencedProject.xls ' + + b'\x00\x00\x00*\\CExample-ReferencedProject.xls' + + b'W\x02\xbee\x17\x00') def test_constructor1() -> None: - path = "C:\\Example Path\\Example-ReferencedProject.xls" - proj_ref = ProjectReference(path) - ref_proj = ReferenceProject("cp1", proj_ref) + ref_proj = "" ref = Reference("cp1", ref_proj) assert isinstance(ref, Reference) def test_constructor2() -> None: - path = "C:\\Example Path\\Example-ReferencedProject.xls" - proj_ref = ProjectReference(path) - ref_proj = ReferenceProject("cp1", proj_ref) - ref = Reference("cp1", ref_proj, "VBAProject1") + ref = Reference("cp1", "", "VBAProject1") assert isinstance(ref, Reference) def test_pack() -> None: - path = "C:\\Example Path\\Example-ReferencedProject.xls" - proj_ref = ProjectReference(path) - ref_proj = ReferenceProject("cp1", proj_ref) + ref_proj = MockRefProj() ref = Reference("cp1", ref_proj, "VBAProject1") expected_hex = ("16 00 0B 00 00 00 56 42 41 50 72 6F 6A 65 63 74", @@ -38,5 +48,7 @@ def test_pack() -> None: expected = bytes.fromhex(" ".join(expected_hex)) codepage = 0x04E4 codepage_name = "cp" + str(codepage) - results = ref.pack(codepage_name, 'little') - assert results == expected + path = 'ms_ovba.Models.Entities.reference.DoubleEncodedString' + with mock.patch(path, MockDEString): + results = ref.pack(codepage_name, 'little') + assert results == expected From 931c97dc10ca7e57c330458d05ed058ff66446df Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sun, 1 Mar 2026 20:35:53 -0500 Subject: [PATCH 332/335] Rename test_doc_module.py to test_doc_module.py (#123) * standard module is now an honest UnitTest --- .../Models/Entities/test_doc_module.pyt} | 0 tests/Unit/Models/Entities/test_std_module.py | 14 +++++++------- 2 files changed, 7 insertions(+), 7 deletions(-) rename tests/{Unit/Models/Entities/test_doc_module.py => Functional/Models/Entities/test_doc_module.pyt} (100%) diff --git a/tests/Unit/Models/Entities/test_doc_module.py b/tests/Functional/Models/Entities/test_doc_module.pyt similarity index 100% rename from tests/Unit/Models/Entities/test_doc_module.py rename to tests/Functional/Models/Entities/test_doc_module.pyt diff --git a/tests/Unit/Models/Entities/test_std_module.py b/tests/Unit/Models/Entities/test_std_module.py index 2541d4b89..184031cc3 100644 --- a/tests/Unit/Models/Entities/test_std_module.py +++ b/tests/Unit/Models/Entities/test_std_module.py @@ -1,13 +1,13 @@ +from unittest import mock from ms_ovba.Models.Entities.std_module import StdModule -def test_set_get_cache() -> None: - module = StdModule("Module1") - cache = b'foo' - module.set_cache(cache) - assert module.get_cache() == cache +path = "ms_ovba.Models.Entities.std_module.ModuleBase.__init__" -def test_get_name() -> None: +@mock.patch(path, return_value=None) +def test_construct(mock_base_init) -> None: module = StdModule("Module1") - assert module.get_name() == "Module1" + mock_base_init.assert_called_once_with("Module1") + assert isinstance(module, StdModule) + assert module.type == "Module" From 3169be640f82da4c43a52f15b70ba5e623ad5a7b Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 13 Mar 2026 09:00:22 -0400 Subject: [PATCH 333/335] =?UTF-8?q?Rename=20tests/Unit/Models/test=5FvbaPr?= =?UTF-8?q?oject.py=20to=20tests/Unit/test=5FvbaPro=E2=80=A6=20(#124)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Rename tests/Unit/Models/test_vbaProject.py to tests/Unit/test_vbaProject.pyt * Update reference_registered.py * Update reference_registered.py * Update reference_registered.py * Update reference_project.py * Update reference_project.py * Update packed_data.py * Update reference.py * Update test_dirObject.pyt * Update test_reference.py * Update test_idSizeField.py * Update test_idSizeField.py * Update test_idSizeField.py * Update test_idSizeField.py * Update test_idSizeField.py * Update test_idSizeField.py * Update test_idSizeField.py * Update test_idSizeField.py * Update idSizeField.py * Update test_idSizeField.py * Update doubleEncodedString.py * Update idSizeField.py * Update packed_data.py * Update test_idSizeField.py * Update test_reference.py * Update reference.py * Update test_reference.py * Update reference_project.py * Update test_reference_project.py * Update reference_registered.py * Update test_reference_registered.py * Update test_reference.py * Update reference_registered.py * Update test_reference_project.py * Update test_project_reference.py * Update test_project_reference.py * Update doubleEncodedString.py * Create test_double_encoded_string.py * Update test_double_encoded_string.py * Update test_double_encoded_string.py * Update test_project_reference.py * Update test_project_reference.py * Update test_project_reference.py * Update test_project_reference.py * Update dirStream.py * Update and rename test_dirObject.pyt to test_dirObject.py * Update test_dirObject.py * Update idSizeField.py * Update packed_data.py * Update reference.py * Update reference.py * Update module_base.py * Update dirStream.py * Update and rename test_fullFile.pyt to test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Update test_fullFile.py * Setters and getters * Update and rename test_vbaProject.pyt to test_vbaProject.py * Update test_vbaProject.py * Update test_vbaProject.py * Update test_vbaProject.py * Update test_vbaProject.py * Update project_view.py * Update project_view.py * Update test_fullFile.py * Update test_reference_registered.py * Update test_reference_registered.py * Update test_reference_registered.py * Update test_reference_registered.py * Update test_dirObject.py * Update test_fullFile.py (#126) * full file functional test --- .github/workflows/python-package.yml | 1 + src/ms_ovba/Models/Entities/module_base.py | 64 ++-- src/ms_ovba/Models/Entities/reference.py | 11 +- .../Models/Entities/reference_project.py | 22 +- .../Models/Entities/reference_registered.py | 19 +- .../Models/Fields/doubleEncodedString.py | 16 +- src/ms_ovba/Models/Fields/idSizeField.py | 9 +- src/ms_ovba/Models/Fields/packed_data.py | 6 +- src/ms_ovba/Views/dirStream.py | 16 +- src/ms_ovba/Views/project.py | 14 +- src/ms_ovba/Views/project_ole_file.py | 4 +- src/ms_ovba/Views/project_view.py | 11 +- src/ms_ovba/vbaProject.py | 94 +++-- tests/Functional/test_dirObject.pyt | 109 ------ tests/Functional/test_fullFile.py | 355 ++++++++++++++++++ tests/Functional/test_fullFile.pyt | 285 -------------- tests/Unit/Models/Entities/test_reference.py | 10 +- .../Models/Entities/test_reference_project.py | 8 +- .../Entities/test_reference_registered.py | 32 +- .../Fields/test_double_encoded_string.py | 23 ++ tests/Unit/Models/Fields/test_idSizeField.py | 20 +- .../Models/Fields/test_project_reference.py | 23 +- tests/Unit/Models/test_vbaProject.py | 29 -- tests/Unit/Views/test_project.py | 20 +- tests/Unit/test_vbaProject.py | 78 ++++ 25 files changed, 702 insertions(+), 577 deletions(-) delete mode 100644 tests/Functional/test_dirObject.pyt create mode 100644 tests/Functional/test_fullFile.py delete mode 100644 tests/Functional/test_fullFile.pyt create mode 100644 tests/Unit/Models/Fields/test_double_encoded_string.py delete mode 100644 tests/Unit/Models/test_vbaProject.py create mode 100644 tests/Unit/test_vbaProject.py diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 00471a527..d31e50507 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -41,6 +41,7 @@ jobs: run: | pytest --cov=src coveralls --service=github + ls -al flake8: runs-on: ubuntu-latest diff --git a/src/ms_ovba/Models/Entities/module_base.py b/src/ms_ovba/Models/Entities/module_base.py index 4d2f0b399..d871c0002 100644 --- a/src/ms_ovba/Models/Entities/module_base.py +++ b/src/ms_ovba/Models/Entities/module_base.py @@ -19,7 +19,7 @@ def __init__(self: T, name: str) -> None: self.streamName = DoubleEncodedString([0x001A, 0x0032], name) self.docString = DoubleEncodedString([0x001C, 0x0048], "") self.helpContext = IdSizeField(0x001E, 4, 0) - self.cookie = IdSizeField(0x002C, 2, 0xFFFF) + self._cookie = IdSizeField(0x002C, 2, 0xFFFF) # self.readonly = SimpleRecord(0x001E, 4, helpContext) # self.private = SimpleRecord(0x001E, 4, helpContext) @@ -32,55 +32,69 @@ def __init__(self: T, name: str) -> None: self._size = 0 # GUIDs - self._guid = [] + self._guids = [] - def set_guid(self: T, guid: str) -> None: + @property + def guids(self: T) -> str: + return self._guids + + @guids.setter + def guids(self: T, guid: str) -> None: if isinstance(guid, list): - self._guid = guid + self._guids = guid else: - self._guid = [guid] + self._guids = [guid] def add_guid(self: T, guid: str) -> None: - self._guid += guid - - def set_cache(self: T, cache: bytes) -> None: - self._cache = cache + """ + Append a guid to the list + """ + self._guid += [guid] - def get_cache(self: T) -> bytes: + @property + def cache(self: T) -> bytes: return self._cache - def set_cookie(self: T, value: int) -> None: - self.cookie = IdSizeField(0x002C, 2, value) + @cache.setter + def cache(self: T, cache: bytes) -> None: + self._cache = cache + + @property + def cookie(self: T) -> int: + return self._cookie.value - def get_cookie(self: T) -> int: - return self.cookie.value + @cookie.setter + def cookie(self: T, value: int) -> None: + self._cookie = IdSizeField(0x002C, 2, value) - def get_name(self: T) -> str: + @property + def name(self: T) -> str: return self.modName.value - def get_bin_path(self: T) -> str: + @property + def bin_path(self: T) -> str: return self._file_path + ".bin" def add_workspace(self: T, val1: int, val2: int, val3: int, val4: int, val5: int) -> None: self.workspace = [val1, val2, val3, val4, val5] - def pack(self: T, codepage_name: str, endien: str) -> bytes: + def pack(self: T, endien: str, cp_name: str) -> bytes: """ Pack the metadata for use in the dir stream. """ typeid_value = 0x0022 if self.type == 'Document' else 0x0021 type_id = PackedData("HI", typeid_value, 0) self.offsetRec = IdSizeField(0x0031, 4, len(self._cache)) - output = (self.modName.pack(codepage_name, endien) - + self.streamName.pack(codepage_name, endien) - + self.docString.pack(codepage_name, endien) - + self.offsetRec.pack(codepage_name, endien) - + self.helpContext.pack(codepage_name, endien) - + self.cookie.pack(codepage_name, endien) - + type_id.pack(codepage_name, endien)) + output = (self.modName.pack(endien, cp_name) + + self.streamName.pack(endien, cp_name) + + self.docString.pack(endien, cp_name) + + self.offsetRec.pack(endien) + + self.helpContext.pack(endien, cp_name) + + self._cookie.pack(endien) + + type_id.pack(endien)) footer = PackedData("HI", 0x002B, 0) - output += footer.pack(codepage_name, endien) + output += footer.pack(endien) return output def to_project_module_string(self: T) -> str: diff --git a/src/ms_ovba/Models/Entities/reference.py b/src/ms_ovba/Models/Entities/reference.py index a78bc90eb..a9b9d8368 100644 --- a/src/ms_ovba/Models/Entities/reference.py +++ b/src/ms_ovba/Models/Entities/reference.py @@ -13,21 +13,18 @@ class Reference(): """ 2.3.4.2.2.1 REFERENCE Record """ - def __init__(self: T, codepage_name: str, - ref: ReferenceRecord, + def __init__(self: T, ref: ReferenceRecord, name: str = None) -> None: - # is self._codepage_name even needed? - self._codepage_name = codepage_name self._ref = ref self._refname = name - def pack(self: T, cp_name: str, endien: str) -> bytes: + def pack(self: T, endien: str, cp_name: str) -> bytes: name_pack = b'' if self._refname is not None: name_de = DoubleEncodedString([0x0016, 0x003E], self._refname) - name_pack = name_de.pack(cp_name, endien) + name_pack = name_de.pack(endien, cp_name) - return name_pack + self._ref.pack(cp_name, endien) + return name_pack + self._ref.pack(endien, cp_name) @staticmethod def unpack(data: bytes, endien: str) -> T: diff --git a/src/ms_ovba/Models/Entities/reference_project.py b/src/ms_ovba/Models/Entities/reference_project.py index c95aea2b7..202656fc8 100644 --- a/src/ms_ovba/Models/Entities/reference_project.py +++ b/src/ms_ovba/Models/Entities/reference_project.py @@ -1,6 +1,6 @@ +import struct from ms_ovba.Models.Entities.reference_record import ReferenceRecord from ms_ovba.Models.Fields.project_reference import ProjectReference -from ms_ovba.Models.Fields.packed_data import PackedData from typing import TypeVar @@ -9,23 +9,19 @@ class ReferenceProject(ReferenceRecord): - def __init__(self: T, codepage_name: str, - ref: ProjectReference) -> None: - # is self._codepage_name even needed? - self._codepage_name = codepage_name + def __init__(self: T, ref: ProjectReference) -> None: self._ref = ref - def pack(self: T, cp_name: str, endien: str) -> bytes: + def pack(self: T, endien: str, cp_name: str) -> bytes: + endien_symbol = '<' if endien == 'little' else '>' lib_rel = self._ref.relative() libid_abs_size = len(self._ref) libid_rel_size = len(lib_rel) - format = ("HII" + str(libid_abs_size) + "sI" + + format = (endien_symbol + "HII" + str(libid_abs_size) + "sI" + str(libid_rel_size) + "sIH") ref_str = str(self._ref).encode(cp_name) ref_str_rel = str(lib_rel).encode(cp_name) - ref_project = PackedData(format, 0x000E, - libid_abs_size + libid_rel_size + 14, - libid_abs_size, ref_str, libid_rel_size, - ref_str_rel, 0x65BE0257, 0x0017) - - return (ref_project.pack(cp_name, endien)) + return struct.pack(format, 0x000E, + libid_abs_size + libid_rel_size + 14, + libid_abs_size, ref_str, libid_rel_size, + ref_str_rel, 0x65BE0257, 0x0017) diff --git a/src/ms_ovba/Models/Entities/reference_registered.py b/src/ms_ovba/Models/Entities/reference_registered.py index 5b358a6dc..b72508303 100644 --- a/src/ms_ovba/Models/Entities/reference_registered.py +++ b/src/ms_ovba/Models/Entities/reference_registered.py @@ -1,7 +1,6 @@ import struct from ms_ovba.Models.Entities.reference_record import ReferenceRecord from ms_ovba.Models.Fields.libid_reference import LibidReference -from ms_ovba.Models.Fields.packed_data import PackedData from typing import TypeVar @@ -13,24 +12,20 @@ class ReferenceRegistered(ReferenceRecord): 2.3.4.2.2.5 Specifies a reference to an Automation type library. """ - def __init__(self: T, codepage_name: str, - libid_ref: LibidReference) -> None: - # is self._codepage_name even needed? - self._codepage_name = codepage_name + def __init__(self: T, libid_ref: LibidReference) -> None: self._libid_ref = libid_ref @property def libid(self: T) -> LibidReference: return self._libid_ref - def pack(self: T, cp_name: str, endien: str) -> bytes: + def pack(self: T, endien: str, cp_name: str) -> bytes: + endien_symbol = '<' if endien == 'little' else '>' strlen = len(self._libid_ref) - format = "HII" + str(strlen) + "sIH" + format = endien_symbol + "HII" + str(strlen) + "sIH" lib_str = str(self._libid_ref).encode(cp_name) - ref_registered = PackedData(format, 0x000D, strlen + 10, - strlen, lib_str, 0, 0) - - return ref_registered.pack(cp_name, endien) + return struct.pack(format, 0x000D, strlen + 10, + strlen, lib_str, 0, 0) @staticmethod def unpack(data: bytes, endien: str) -> T: @@ -66,4 +61,4 @@ def unpack(data: bytes, endien: str) -> T: pass libid_ref = LibidReference.unpack(libid_ref_bytes) - return ReferenceRegistered("", libid_ref) + return ReferenceRegistered(libid_ref) diff --git a/src/ms_ovba/Models/Fields/doubleEncodedString.py b/src/ms_ovba/Models/Fields/doubleEncodedString.py index 09c43166c..52332a4b1 100644 --- a/src/ms_ovba/Models/Fields/doubleEncodedString.py +++ b/src/ms_ovba/Models/Fields/doubleEncodedString.py @@ -12,13 +12,17 @@ class DoubleEncodedString(): """ def __init__(self: T, ids: list, text: str) -> None: self.ids = ids - self.value = text + self._value = text - def pack(self: T, codepage_name: str, endien: str) -> bytes: - encoded = self.value.encode(codepage_name) + @property + def value(self) -> str: + return self._value + + def pack(self: T, endien: str, cp_name: str) -> bytes: + encoded = self._value.encode(cp_name) self.mod_name1 = IdSizeField(self.ids[0], len(encoded), encoded) format = "utf_16_le" if endien == 'little' else "utf_16_be" - encoded = self.value.encode(format) + encoded = self._value.encode(format) self.mod_name2 = IdSizeField(self.ids[1], len(encoded), encoded) - return (self.mod_name1.pack(codepage_name, endien) - + self.mod_name2.pack(codepage_name, endien)) + return (self.mod_name1.pack(endien) + + self.mod_name2.pack(endien)) diff --git a/src/ms_ovba/Models/Fields/idSizeField.py b/src/ms_ovba/Models/Fields/idSizeField.py index cc6b5f061..6a1b5cae8 100644 --- a/src/ms_ovba/Models/Fields/idSizeField.py +++ b/src/ms_ovba/Models/Fields/idSizeField.py @@ -16,14 +16,17 @@ def __init__(self: T, id: int, size: int, value: Any) -> None: self._size = size self._value = value - def pack(self: T, codepage_name: str, endien: str) -> bytes: + @property + def value(self: T) -> Any: + return self._value + + def pack(self: T, endien: str, cp_name: str = None) -> bytes: endien_symbol = '<' if endien == 'little' else '>' format = endien_symbol + "HI" if isinstance(self._value, str): self.stringValue = self._value self._value = bytes(self._value, encoding="ascii") - format += str(self._size) + "s" - elif isinstance(self._value, bytes): + if isinstance(self._value, bytes): format += str(self._size) + "s" elif self._size == 2: format += "H" diff --git a/src/ms_ovba/Models/Fields/packed_data.py b/src/ms_ovba/Models/Fields/packed_data.py index 7ee87ae38..70e8430f8 100644 --- a/src/ms_ovba/Models/Fields/packed_data.py +++ b/src/ms_ovba/Models/Fields/packed_data.py @@ -7,12 +7,14 @@ class PackedData(): """ - Multivalue field with a packing format + Multivalue field with a packing format. + This class allows a user to define a data format, + and render it at a later time. """ def __init__(self: T, format: str, *values: Any) -> None: self.values = values self.format = format - def pack(self: T, codepage_name: str, endien: str) -> bytes: + def pack(self: T, endien: str, cp_name: str = None) -> bytes: endien_symbol = '<' if endien == 'little' else '>' return struct.pack(endien_symbol + self.format, *self.values) diff --git a/src/ms_ovba/Views/dirStream.py b/src/ms_ovba/Views/dirStream.py index db22fb96f..f0cf29191 100644 --- a/src/ms_ovba/Views/dirStream.py +++ b/src/ms_ovba/Views/dirStream.py @@ -19,30 +19,30 @@ class DirStream(): def __init__(self: T, project: VbaProject) -> None: self.project = project - self._include_compat = False + self._include_compat = project.compat def to_bytes(self: T) -> bytes: information = self._load_information() endien = self.project.endien - codepage_name = self.project.get_codepage_name() + cp_name = self.project.codepage_name pack_symbol = '<' if endien == 'little' else '>' # should be 0xFFFF - cookie_value = self.project.get_project_cookie() + cookie_value = self.project.project_cookie self.project_cookie = IdSizeField(19, 2, cookie_value) references = self.project.references modules = self.project.modules output = b'' for record in information: - output += record.pack(codepage_name, endien) + output += record.pack(endien, cp_name) for record in references: - output += record.pack(codepage_name, endien) + output += record.pack(endien, cp_name) modules_header = IdSizeField(0x000F, 2, len(modules)) - output += (modules_header.pack(codepage_name, endien) - + self.project_cookie.pack(codepage_name, endien)) + output += (modules_header.pack(endien) + + self.project_cookie.pack(endien)) for record in modules: - output += record.pack(codepage_name, endien) + output += record.pack(endien, cp_name) output += struct.pack(pack_symbol + "HI", 16, 0) return output diff --git a/src/ms_ovba/Views/project.py b/src/ms_ovba/Views/project.py index 5f6eff9de..6c03fe844 100644 --- a/src/ms_ovba/Views/project.py +++ b/src/ms_ovba/Views/project.py @@ -16,7 +16,7 @@ def __init__(self: T, project: VbaProject) -> None: # Attributes # A list of attributes and values - self.attributes = {} + self.attributes = project.attributes # The HostExtenderInfo string guid = "{3832D640-CF90-11CF-8E43-00A0C911005A}" @@ -27,10 +27,10 @@ def add_attribute(self: T, name: str, value: str) -> None: def to_bytes(self: T) -> bytes: project = self.project - codepage_name = project.get_codepage_name() + codepage_name = project.codepage_name # Use \x0D0A line endings...however python encodes that. eol = b'\x0D\x0A' - project_id = project.get_project_id() + project_id = project.project_id id = bytearray(project_id, codepage_name) result = b'ID="' + id + b'"' + eol modules = project.modules @@ -42,10 +42,10 @@ def to_bytes(self: T) -> bytes: result += self._attr(key, self.attributes[key]) cmg = ms_ovba_crypto.encrypt( project_id, - project.get_protection_state() + project.protection_state ) - dpb = ms_ovba_crypto.encrypt(project_id, project.get_password()) - gc = ms_ovba_crypto.encrypt(project_id, project.get_visibility_state()) + dpb = ms_ovba_crypto.encrypt(project_id, project.password) + gc = ms_ovba_crypto.encrypt(project_id, project.visibility_state) result += (bytes('CMG="', codepage_name) + binascii.hexlify(cmg).upper() + b'\x22\x0D\x0A') @@ -74,7 +74,7 @@ def write_file(self: T) -> None: bin_f.close() def _attr(self: T, name: str, value: str) -> str: - codepage_name = self.project.get_codepage_name() + codepage_name = self.project.codepage_name eol = b'\x0D\x0A' b_name = bytes(name, codepage_name) b_value = bytes(value, codepage_name) diff --git a/src/ms_ovba/Views/project_ole_file.py b/src/ms_ovba/Views/project_ole_file.py index b88c52e26..86c07fc5b 100644 --- a/src/ms_ovba/Views/project_ole_file.py +++ b/src/ms_ovba/Views/project_ole_file.py @@ -33,7 +33,7 @@ def _build_ole_directory(project: VbaProject) -> RootDirectory: storage.set_modified(project.default_date) for module in project.get_modules(): module.write_file() - dir = StreamDirectory(module.get_name(), module.get_bin_path()) + dir = StreamDirectory(module.name, module.bin_path) storage.add_directory(dir) module = DirStream(project) @@ -48,7 +48,7 @@ def _build_ole_directory(project: VbaProject) -> RootDirectory: directory.add_directory(storage) - if project.get_include_projectwm(): + if project.projectwm: module = ProjectWm(project) module.write_file() stream = StreamDirectory("PROJECTwm", "projectwm.bin") diff --git a/src/ms_ovba/Views/project_view.py b/src/ms_ovba/Views/project_view.py index 865d0d596..b030a1287 100644 --- a/src/ms_ovba/Views/project_view.py +++ b/src/ms_ovba/Views/project_view.py @@ -10,12 +10,9 @@ class ProjectView: """ The _VBA_PROJECT data view for the vbaProject """ - def __init__(self: T, project: VbaProject) -> None: + def __init__(self: T, project: VbaProject, reserved: int = 3) -> None: self.project = project - self._reserved3 = 0x0003 - - def set_reserved3(self: T, value: int) -> None: - self._reserved3 = value + self._reserved3 = reserved def to_bytes(self: T) -> bytes: endien_symbol = '<' if self.project.endien == 'little' else '>' @@ -23,11 +20,11 @@ def to_bytes(self: T) -> bytes: output = b'' reserved1 = 0x61CC reserved2 = 0x00 - cache_version = self.project.get_performance_cache_version() + cache_version = self.project.performance_cache_version output += struct.pack(format, reserved1, cache_version, reserved2, self._reserved3) - return output + self.project.get_performance_cache() + return output + self.project.performance_cache def write_file(self: T) -> None: bin_f = open("vba_project.bin", "wb") diff --git a/src/ms_ovba/vbaProject.py b/src/ms_ovba/vbaProject.py index a610f4f5b..bad5457f3 100644 --- a/src/ms_ovba/vbaProject.py +++ b/src/ms_ovba/vbaProject.py @@ -29,9 +29,13 @@ def __init__(self: T) -> None: self.references = [] self.modules = [] + # A list of attributes and values + self.attributes = {} + self._project_cookie = 0xFFFF self._project_wm = False + self._compat = False self._default_date = Filetime.from_msfiletime(0x0000000000000000) # Getters and Setters @@ -43,19 +47,28 @@ def default_date(self: T) -> Filetime: def default_date(self: T, date: Filetime) -> None: self._default_date = date - def set_project_id(self: T, id: str) -> None: + @property + def project_id(self: T) -> str: + return self._project_id + + @project_id.setter + def project_id(self: T, id: str) -> None: self._project_id = id - def get_project_id(self: T) -> str: - return self._project_id + @property + def protection_state(self: T) -> int: + return self._protection_state - def set_protection_state(self: T, state: int) -> None: + @protection_state.setter + def protection_state(self: T, state: int) -> None: self._protection_state = state - def get_protection_state(self: T) -> int: - return self._protection_state + @property + def visibility_state(self: T) -> bytes: + return self._visibility_state - def set_visibility_state(self: T, state: int) -> None: + @visibility_state.setter + def visibility_state(self: T, state: int) -> None: """ 0 = not visible 255 = visible @@ -64,48 +77,75 @@ def set_visibility_state(self: T, state: int) -> None: raise Exception("Bad visibility value.") self._visibility_state = state - def get_visibility_state(self: T) -> bytes: - return self._visibility_state + @property + def password(self: T) -> bytes: + return self._password - def set_password(self: T, value: bytes) -> None: + @password.setter + def password(self: T, value: bytes) -> None: self._password = value - def get_password(self: T) -> bytes: - return self._password + @property + def performance_cache(self: T) -> bytes: + return self._performance_cache - def set_performance_cache(self: T, cache: bytes) -> None: + @performance_cache.setter + def performance_cache(self: T, cache: bytes) -> None: self._performance_cache = cache - def get_performance_cache(self: T) -> None: - return self._performance_cache + @property + def performance_cache_version(self: T) -> int: + return self._performance_cache_version - def set_performance_cache_version(self: T, version: int) -> None: + @performance_cache_version.setter + def performance_cache_version(self: T, version: int) -> None: self._performance_cache_version = version - def get_performance_cache_version(self: T) -> int: - return self._performance_cache_version - - def get_codepage_name(self: T) -> str: + @property + def codepage_name(self: T) -> str: return self._codepage_name - def set_project_cookie(self: T, value: int) -> None: - self._project_cookie = value + @codepage_name.setter + def codepage_name(self: T, name: str) -> None: + self._codepage_name = name - def get_project_cookie(self: T) -> int: + @property + def project_cookie(self: T) -> int: return self._project_cookie + @project_cookie.setter + def project_cookie(self: T, value: int) -> None: + self._project_cookie = value + def get_modules(self: T) -> list: return self.modules - def set_include_projectwm(self: T, value: bool) -> None: - self._project_wm = value - - def get_include_projectwm(self: T) -> bool: + @property + def projectwm(self: T) -> bool: return self._project_wm + def include_projectwm(self: T) -> bool: + self._project_wm = True + + def exclude_projectwm(self: T) -> bool: + self._project_wm = False + + @property + def compat(self: T) -> bool: + return self._compat + + def include_compat(self: T) -> None: + self._compat = True + + def exclude_compat(self: T) -> None: + self._compat = False + # Appenders def add_module(self: T, mod: ModuleBase) -> None: self.modules.append(mod) def add_reference(self: T, ref: ReferenceRegistered) -> None: self.references.append(ref) + + def add_attribute(self: T, name: str, value: str) -> None: + self.attributes[name] = value diff --git a/tests/Functional/test_dirObject.pyt b/tests/Functional/test_dirObject.pyt deleted file mode 100644 index 7a86f26a2..000000000 --- a/tests/Functional/test_dirObject.pyt +++ /dev/null @@ -1,109 +0,0 @@ -import struct -import uuid -from ms_ovba_compression.ms_ovba import MsOvba -from ms_pcode_assembler.module_cache import ModuleCache -from ms_ovba.vbaProject import VbaProject -from ms_ovba.Views.dirStream import DirStream -from ms_ovba.Models.Fields.libid_reference import LibidReference -from ms_ovba.Models.Entities.doc_module import DocModule -from ms_ovba.Models.Entities.std_module import StdModule -from ms_ovba.Models.Entities.reference import ( - Reference -) -from ms_ovba.Models.Entities.reference_registered import ( - ReferenceRegistered -) - - -def test_dirstream() -> None: - ''' - The cache is not yet tested. - ''' - module_cache = ModuleCache(0xB5, 0x08F3, signature=3) - # Read the data from the demo file and decompress it. - f = open('tests/blank/vbaProject.bin', 'rb') - offset = 0x1EC0 - length = 0x0232 - f.seek(offset) - container = f.read(length) - ms_ovba = MsOvba() - decompressed_stream = ms_ovba.decompress(container) - - # Create a project with the same attributes - project = VbaProject() - stream = DirStream(project) - stream.include_compat() - codepage = 0x04E4 - codepage_name = "cp" + str(codepage) - guid = uuid.UUID('0002043000000000C000000000000046') - libid_ref = ReferenceRegistered(codepage_name, LibidReference( - guid, - "2.0", - "0", - "C:\\Windows\\System32\\stdole2.tlb", - "OLE Automation" - )) - ole_reference = Reference(codepage_name, libid_ref, "stdole") - guid = uuid.UUID('2DF8D04C5BFA101BBDE500AA0044DE52') - libid_ref2 = ReferenceRegistered(codepage_name, LibidReference( - guid, - "2.0", - "0", - "C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE16\\MSO.DLL", - "Microsoft Office 16.0 Object Library" - )) - office_reference = Reference(codepage_name, libid_ref2, "Office") - project.add_reference(ole_reference) - project.add_reference(office_reference) - project.set_project_cookie(0x08F3) - - indirect_table = ("02 80 FE FF FF FF FF FF 20 00 00 00 FF FF FF FF", - "30 00 00 00 02 01 FF FF 00 00 00 00 00 00 00 00", - "FF FF FF FF FF FF FF FF 00 00 00 00 2E 00 43 00", - "1D 00 00 00 25 00 00 00 FF FF FF FF 40 00 00 00") - module_cache.indirect_table = bytes.fromhex(" ".join(indirect_table)) - object_table = ("02 00 53 4C FF FF FF FF 00 00 01 00 53 10 FF FF", - "FF FF 00 00 01 00 53 94 FF FF FF FF 00 00 00 00", - "02 3C FF FF FF FF 00 00") - module_cache.object_table = bytes.fromhex(" ".join(object_table)) - module_cache.misc = [[-1, 0x18], 0xFF, 0, [1, "00000000"]] - module_cache.header.data2 = 0x0123 - module_cache.header.data3 = 0x88 - module_cache.header.sata4 = 8 - this_workbook = DocModule("ThisWorkbook") - this_workbook.set_cookie(0xB81C) - module_cache.cookie = 0xB81C - guid = uuid.UUID('0002081900000000C000000000000046') - this_workbook.set_guid(guid) - module_cache.guid = [guid] - this_workbook.set_cache(module_cache.to_bytes()) - - sheet1 = DocModule("Sheet1") - sheet1.set_cookie(0x9B9A) - module_cache.cookie = 0x9B9A - guid = uuid.UUID('0002082000000000C000000000000046') - module_cache.guid = [guid] - sheet1.set_guid(guid) - sheet1.set_cache(module_cache.to_bytes()) - - module1 = StdModule("Module1") - module1.set_cookie(0xB241) - module_cache.clear_variables() - module_cache.cookie = 0xB241 - module_cache.misc = [[-1, 2], 0xFFFF, 0, [0, "FFFFFFFF"]] - module_cache.header.data2 = 3 - module_cache.header.data3 = 0 - module_cache.header.sata4 = 7 - module_cache.indirect_table = struct.pack(" None: + cls._rand = seeds + + @classmethod + def randint(cls: Type[T], param1: int, param2: int) -> int: + return cls._rand.pop(0) + + +@pytest.fixture(autouse=True) +def run_around_tests() -> None: + # Code that will run before your test, for example: + + # A test function will be run at this point + yield + # Code that will run after your test + root = "src/ms_ovba/blank_files/" + root2 = "tests/blank/" + names = [root + "ThisWorkbook.cls", root + "Sheet1.cls", + root2 + "Module1.bas"] + remove_module(names) + names = ["dir.bin", "projectwm.bin", "project.bin", "vba_project.bin"] + map(os.remove, names) + + +def remove_module(names: str) -> None: + for name in names: + os.remove(name + ".new") + os.remove(name + ".bin") + + +def assert_module_matches_bin(module_path: str, + cache_size: int, + bin_path: str, + bin_offset: int, + bin_length: int) -> bool: + m = open(module_path, "rb") + b = open(bin_path, "rb") + b.seek(bin_offset) + assert m.read(cache_size) == b.read(cache_size) + ms_ovba = MsOvba() + m_uncompressed = ms_ovba.decompress(m.read()) + b_uncompressed = ms_ovba.decompress(b.read(bin_length - cache_size)) + assert m_uncompressed == b_uncompressed + + +stdole_lib = LibidReference( + uuid.UUID("00020430-0000-0000-C000-000000000046"), + "2.0", + "0", + "C:\\Windows\\System32\\stdole2.tlb", + "OLE Automation" + ) + + +@unittest.mock.patch('random.randint', NotSoRandom.randint) +def test_full_file() -> None: + """ + Create an exact reproduction of a complete "empty" vba excel addin. + """ + rand = [0x41, 0xBC, 0x7B, 0x7B, 0x37, 0x7B, 0x7B, 0x7B] + NotSoRandom.set_seed(rand) + project = VbaProject() + project.default_date = Filetime.from_msfiletime(0x01D92433C2B823C0) + project.include_projectwm() + libid_ref = ReferenceRegistered(stdole_lib) + ole_reference = Reference(libid_ref, "stdole") + libid_ref2 = ReferenceRegistered(LibidReference( + uuid.UUID("2DF8D04C5BFA101BBDE500AA0044DE52"), + "2.0", + "0", + "C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE16\\MSO.DLL", + "Microsoft Office 16.0 Object Library" + )) + office_reference = Reference(libid_ref2, "Office") + project.add_reference(ole_reference) + project.add_reference(office_reference) + proj_cookie = 0x08F3 + project.project_cookie = proj_cookie + project.project_id = '{9E394C0B-697E-4AEE-9FA6-446F51FB30DC}' + project.performance_cache_version = 0x00B5 + + base_path = "src/ms_ovba/blank_files/" + # Add Modules + this_workbook = create_doc_module(project, "ThisWorkbook", 0xB81C, + "0002081900000000C000000000000046", + base_path + "ThisWorkbook.cls") + + sheet1 = create_doc_module(project, "Sheet1", 0x9B9A, + "0002082000000000C000000000000046", + base_path + "Sheet1.cls") + + module1 = StdModule("Module1") + cookie = 0xB241 + module1.cookie = cookie + module_cache = ModuleCache(0xB5, proj_cookie, signature=3) + module_cache.misc = [[-1, 2], 0xFFFF, 0, [0, "FFFFFFFF"]] + module_cache.header.data2 = 0 + module_cache.header.data3 = 3 + module_cache.header.data4 = 0 + module_cache.indirect_table = struct.pack(" bytes: + cache = ProjectCache(0x04E4, proj_cookie, 0x65BE0257) + cache._hex = 0x65BE0257 + module_array = [] + i = 0 + id = [0x227, 0x22B, 0x22C] + for module in modules: + hex = 0x65BE0263 if i == 2 else cache._hex + module_array.append( + (module.name, 50, 70 + i, hex, id[i], + module.cookie, len(module.cache), [], -1) + ) + i += 1 + + cache._modules = module_array + + cache.add_library(str(LibidReference( + uuid.UUID("000204EF-0000-0000-C000-000000000046"), + "4.2", + "9", + "C:\\Program Files\\Common Files\\Microsoft Shared\\VBA" + "\\VBA7.1\\VBE7.DLL", + "Visual Basic For Applications" + ))) + cache.add_library(str(LibidReference( + uuid.UUID("00020813-0000-0000-C000-000000000046"), + "1.9", + "0", + "C:\\Program Files\\Microsoft Office\\root\\Office16\\EXCEL.EXE", + "Microsoft Excel 16.0 Object Library" + ))) + cache.add_library(str(stdole_lib)) + cache.add_library(str(LibidReference( + uuid.UUID("2DF8D04C-5BFA-101B-BDE5-00AA0044DE52"), + "2.8", + "0", + "C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE16\\MSO.DLL", + "Microsoft Office 16.0 Object Library" + ))) + + # User Class + cache._user = [2, 2, 1] + + # Compile Time Data + cache._compile = [0x0212, 0x010214, 0x010216, + 0x0218, 0x01021a, 0x01021c] + + # Data + cache._data = [0x222, 0xffff, 17, -1, -1, -1, -1, 1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 2, -1, -1, -1, -1, -1] + + # Footer? + cache._post_f_data = [(13, 0x230), (14, 0x218), (43, 0x200)] + cache._post_data = [ + b'\xf1q\x9a\xee\xc0\xe0\xc4F\xa2\xf8l|\xf9{s\x06', + b'vS\x9e\xe1B\x85\xfeF\xa1\x8b0E\x08tCU', + b'"\x93\xba>\xc3\x82\xfcD\x88\xcav\x96\xe5\x061"' + ] + cache._post_footer = 0x30 + cache._w0 = 0x117 + cache._w2 = 0x2ba0 + cache._identifiers = [ + (b"Excel", 4, 0x2b80), (b"VBA", 4, 0xe2f7), (b"Win16", 4, 0x7ec1), + (b"Win32", 4, 0x7f07), (b"Win64", 4, 0x7f78), (b"Mac", 4, 0xb2b3), + (b"VBA6", 4, 0x23ad), (b"VBA7", 4, 0x23ae), + (b"Project1", 4, 0x170a), + (b"stdole", 4, 0x6093), (b"VBAProject", 4, 0xbfbe), + (b"Office", 4, 0x7515), (b"ThisWorkbook", 4, 0xe37c), + (b"_Evaluate", 128, 0xd918, 0, 0x103, -1), + (b"Sheet1", 4, 0x1ae8), (b"Module1", 4, 0x1162), + (b"Workbook", 4, 0x186b) + ] + + hex = ("20 02 02 00 FF FF 22 02 FF FF FF FF 24 02 03 00", + "FF FF 27 02 00 00 03 00 FF FF FF FF FF FF 2B 02", + "01 00 03 00 2D 02 02 00 05 00 0E 02 01 00 FF FF", + "10 02 00 00 FF FF FF FF FF FF FF FF FF FF FF FF", + "FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF", + "FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF") + + hex2 = ("06 00 10 00 00 00 01 00 36 00 00 00 00 00 00 00", + "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", + "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", + "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", + "00 00") + + cache._footer = [ + bytes.fromhex(" ".join(hex)), + bytes.fromhex(" ".join(hex2)) + ] + return cache.to_bytes() + + +def create_doc_module(project: VbaProject, name: str, + cookie: int, guid_s: str, path: str) -> DocModule: + mod = DocModule(name) + mod.cookie = cookie + guid = uuid.UUID(guid_s) + mod.add_guid(guid) + module_path = path + mod.add_file(module_path) + mod.normalize_file() + + cache_ver = project.performance_cache_version + proj_cookie = project.project_cookie + module_cache = ModuleCache(cache_ver, proj_cookie, signature=3) + module_cache.header.data2 = 0 + module_cache.header.data3 = 0x123 + module_cache.header.data4 = 0x88 + module_cache.misc = [[-1, 8], 0x18, 0, [1, "00000000"]] + indirect_table = ("02 80 FE FF FF FF FF FF 20 00 00 00 FF FF FF FF", + "30 00 00 00 02 01 FF FF 00 00 00 00 00 00 00 00", + "FF FF FF FF FF FF FF FF 00 00 00 00 2E 00 43 00", + "1D 00 00 00 25 00 00 00 FF FF FF FF 40 00 00 00") + module_cache.indirect_table = bytes.fromhex(" ".join(indirect_table)) + + object_table = [[2, 0x4C53], [1, 0x1053], [1, 0x9453], [0, 0x3C02]] + object_table_bytes = b'' + for entry in object_table: + object_table_bytes += struct.pack(" None: - cls._rand = seeds - - @classmethod - def randint(cls: Type[T], param1: int, param2: int) -> int: - return cls._rand.pop(0) - - -@pytest.fixture(autouse=True) -def run_around_tests() -> None: - # Code that will run before your test, for example: - - # A test function will be run at this point - yield - # Code that will run after your test - root = "src/ms_ovba/blank_files/" - root2 = "tests/blank/" - names = [root + "ThisWorkbook.cls", root + "Sheet1.cls", - root2 + "Module1.bas"] - remove_module(names) - names = ["dir.bin", "projectWm.bin", "project.bin", "vba_project.bin"] - map(os.remove, names) - - -def remove_module(names: str) -> None: - for name in names: - os.remove(name + ".new") - os.remove(name + ".bin") - - -def module_matches_bin(module_path: str, - cache_size: int, - bin_path: str, - bin_offset: int, - bin_length: int) -> bool: - m = open(module_path, "rb") - b = open(bin_path, "rb") - b.seek(bin_offset) - if m.read(cache_size) != b.read(cache_size): - return False - ms_ovba = MsOvba() - m_uncompressed = ms_ovba.decompress(m.read()) - b_uncompressed = ms_ovba.decompress(b.read(bin_length)) - return m_uncompressed == b_uncompressed - - -@unittest.mock.patch('random.randint', NotSoRandom.randint) -def test_full_file() -> None: - rand = [0x41, 0xBC, 0x7B, 0x7B, 0x37, 0x7B, 0x7B, 0x7B] - NotSoRandom.set_seed(rand) - project = VbaProject() - project.default_date = Filetime.from_msfiletime(0x01D92433C2B823C0) - project.set_include_projectwm(True) - codepage = 0x04E4 - codepage_name = "cp" + str(codepage) - libid_ref = ReferenceRegistered(codepage_name, LibidReference( - uuid.UUID("0002043000000000C000000000000046"), - "2.0", - "0", - "C:\\Windows\\System32\\stdole2.tlb", - "OLE Automation" - )) - ole_reference = Reference(codepage_name, libid_ref, "stdole") - libid_ref2 = ReferenceRegistered(codepage_name, LibidReference( - uuid.UUID("2DF8D04C5BFA101BBDE500AA0044DE52"), - "2.0", - "0", - "C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE16\\MSO.DLL", - "Microsoft Office 16.0 Object Library" - )) - office_reference = Reference(codepage_name, libid_ref2, "Office") - project.add_reference(ole_reference) - project.add_reference(office_reference) - proj_cookie = 0x08F3 - project.set_project_cookie(proj_cookie) - project.set_project_id('{9E394C0B-697E-4AEE-9FA6-446F51FB30DC}') - project.set_performance_cache(create_cache()) - project.set_performance_cache_version(0x00B5) - - base_path = "src/ms_ovba/blank_files/" - # Add Modules - this_workbook = create_doc_module(project, "ThisWorkbook", 0xB81C, - "0002081900000000C000000000000046", - base_path + "ThisWorkbook.cls") - - sheet1 = create_doc_module(project, "Sheet1", 0x9B9A, - "0002082000000000C000000000000046", - base_path + "Sheet1.cls") - - module1 = StdModule("Module1") - cookie = 0xB241 - module1.set_cookie(cookie) - module_cache = ModuleCache(0xB5, proj_cookie, signature=3) - module_cache.header.data2 = 3 - module_cache.header.data4 = 2 - module_cache.misc = [[-1, 0], 0xFFFF, 0, [0, "FFFFFFFF"]] - module_cache.indirect_table = struct.pack(" bytes: - modules = [] - this_workbook = DocModule("ThisWorkbook") - this_workbook.cookie.value = 0xB81C - modules.append(this_workbook) - sheet1 = DocModule("Sheet1") - sheet1.cookie.value = 0x9B9A - modules.append(sheet1) - module1 = StdModule("Module1") - module1.cookie.value = 0xB241 - modules.append(module1) - - libraries = [] - libraries.append(LibidReference( - uuid.UUID("000204EF-0000-0000-C000-000000000046"), - "4.2", - "9", - "C:\\Program Files\\Common Files\\Microsoft Shared\\VBA" - "\\VBA7.1\\VBE7.DLL", - "Visual Basic For Applications" - )) - libraries.append(LibidReference( - uuid.UUID("00020813-0000-0000-C000-000000000046"), - "1.9", - "0", - "C:\\Program Files\\Microsoft Office\\root\\Office16\\EXCEL.EXE", - "Microsoft Excel 16.0 Object Library" - )) - libraries.append(LibidReference( - uuid.UUID("00020430-0000-0000-C000-000000000046"), - "2.0", - "0", - "C:\\Windows\\System32\\stdole2.tlb", - "OLE Automation" - )) - libraries.append(LibidReference( - uuid.UUID("2DF8D04C-5BFA-101B-BDE5-00AA0044DE52"), - "2.8", - "0", - "C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE16\\MSO.DLL", - "Microsoft Office 16.0 Object Library" - )) - ca = (b'' - + b'\xFF\x09\x04\x00\x00\x09\x04\x00\x00\xE4\x04\x03\x00\x00\x00\x00' - + b'\x00\x00\x00\x00\x00\x01\x00\x04\x00\x02\x00') - i = 0 - for lib in libraries: - lib_str = bytearray(str(lib), "utf_16_le") - ca += struct.pack(" DocModule: - mod = DocModule(name) - mod.set_cookie(cookie) - guid = uuid.UUID(guid_s) - mod.set_guid(guid) - module_path = path - mod.add_file(module_path) - mod.normalize_file() - - cache_ver = project.get_performance_cache_version() - proj_cookie = project.get_project_cookie() - module_cache = ModuleCache(cache_ver, proj_cookie, signature=3) - module_cache.header.data3 = 0x88 - module_cache.header.data4 = 8 - module_cache.misc = [[-1, 0x18], 0x18, 0, [1, "00000000"]] - indirect_table = ("02 80 FE FF FF FF FF FF 20 00 00 00 FF FF FF FF", - "30 00 00 00 02 01 FF FF 00 00 00 00 00 00 00 00", - "FF FF FF FF FF FF FF FF 00 00 00 00 2E 00 43 00", - "1D 00 00 00 25 00 00 00 FF FF FF FF 40 00 00 00") - module_cache.indirect_table = bytes.fromhex(" ".join(indirect_table)) - - object_table = [[2, 0x4C53], [1, 0x1053], [1, 0x9453], [0, 0x3C02]] - object_table_bytes = b'' - for entry in object_table: - object_table_bytes += struct.pack(" bytes: def test_constructor1() -> None: ref_proj = "" - ref = Reference("cp1", ref_proj) + ref = Reference(ref_proj) assert isinstance(ref, Reference) def test_constructor2() -> None: - ref = Reference("cp1", "", "VBAProject1") + ref = Reference("", "VBAProject1") assert isinstance(ref, Reference) def test_pack() -> None: ref_proj = MockRefProj() - ref = Reference("cp1", ref_proj, "VBAProject1") + ref = Reference(ref_proj, "VBAProject1") expected_hex = ("16 00 0B 00 00 00 56 42 41 50 72 6F 6A 65 63 74", "31 3E 00 16 00 00 00 56 00 42 00 41 00 50 00 72", @@ -47,8 +47,8 @@ def test_pack() -> None: "00") expected = bytes.fromhex(" ".join(expected_hex)) codepage = 0x04E4 - codepage_name = "cp" + str(codepage) + cp_name = "cp" + str(codepage) path = 'ms_ovba.Models.Entities.reference.DoubleEncodedString' with mock.patch(path, MockDEString): - results = ref.pack(codepage_name, 'little') + results = ref.pack('little', cp_name) assert results == expected diff --git a/tests/Unit/Models/Entities/test_reference_project.py b/tests/Unit/Models/Entities/test_reference_project.py index c3008e028..1026fa175 100644 --- a/tests/Unit/Models/Entities/test_reference_project.py +++ b/tests/Unit/Models/Entities/test_reference_project.py @@ -3,7 +3,7 @@ def test_constructor() -> None: ref = MockProjectReference() - module = ReferenceProject("cp1", ref) + module = ReferenceProject(ref) assert isinstance(module, ReferenceProject) @@ -38,7 +38,7 @@ def test_pack() -> None: "BE 65 17 00") expected = bytes.fromhex(" ".join(expected_hex)) codepage = 0x04E4 - codepage_name = "cp" + str(codepage) - ref_proj = ReferenceProject(codepage_name, ref) - results = ref_proj.pack(codepage_name, 'little') + cp_name = "cp" + str(codepage) + ref_proj = ReferenceProject(ref) + results = ref_proj.pack('little', cp_name) assert results == expected diff --git a/tests/Unit/Models/Entities/test_reference_registered.py b/tests/Unit/Models/Entities/test_reference_registered.py index 1287e05e6..92fd7f370 100644 --- a/tests/Unit/Models/Entities/test_reference_registered.py +++ b/tests/Unit/Models/Entities/test_reference_registered.py @@ -1,3 +1,4 @@ +import pytest from unittest import mock from ms_ovba.Models.Entities.reference_registered import ReferenceRegistered @@ -21,7 +22,7 @@ def unpack(data): def test_constructor() -> None: ref = MockLibid1() - module = ReferenceRegistered("cp1", ref) + module = ReferenceRegistered(ref) assert isinstance(module, ReferenceRegistered) @@ -35,9 +36,9 @@ def test_pack() -> None: "74 6F 6D 61 74 69 6F 6E 00 00 00 00 00 00") expected = bytes.fromhex(" ".join(expected_hex)) codepage = 0x04E4 - codepage_name = "cp" + str(codepage) - ref_reg = ReferenceRegistered(codepage_name, MockLibid1()) - results = ref_reg.pack(codepage_name, 'little') + cp_name = "cp" + str(codepage) + ref_reg = ReferenceRegistered(MockLibid1()) + results = ref_reg.pack('little', cp_name) assert results == expected @@ -53,7 +54,22 @@ def test_unpack(): path = 'ms_ovba.Models.Entities.reference_registered.LibidReference' with mock.patch(path, MockLibid2): ref = ReferenceRegistered.unpack(data, "little") - assert ref.libid.data == (b'*\\G{00020430-0000-0000-C000-' + - b'000000000046}#2.0#0#' + - b'C:\\Windows\\system32\\stdole2.tlb#' + - b'OLE Automation') + assert ref.libid.data == ( + b'*\\G{00020430-0000-0000-C000-000000000046}#2.0#0#' + + b'C:\\Windows\\system32\\stdole2.tlb#OLE Automation' + ) + + +def test_bad_id(): + hex = ("0C 00 68 00 00 00 5E 00 00 00 2A 5C 47 7B 30 30", + "30 32 30 34 33 30 2D 30 30 30 30 2D 30 30 30 30", + "2D 43 30 30 30 2D 30 30 30 30 30 30 30 30 30 30", + "34 36 7D 23 32 2E 30 23 30 23 43 3A 5C 57 69 6E", + "64 6F 77 73 5C 73 79 73 74 65 6D 33 32 5C 73 74", + "64 6F 6C 65 32 2E 74 6C 62 23 4F 4C 45 20 41 75", + "74 6F 6D 61 74 69 6F 6E 00 00 00 00 00 00") + data = bytes.fromhex(" ".join(hex)) + path = 'ms_ovba.Models.Entities.reference_registered.LibidReference' + with mock.patch(path, MockLibid2): + with pytest.raises(Exception): + ReferenceRegistered.unpack(data, "little") diff --git a/tests/Unit/Models/Fields/test_double_encoded_string.py b/tests/Unit/Models/Fields/test_double_encoded_string.py new file mode 100644 index 000000000..94377392d --- /dev/null +++ b/tests/Unit/Models/Fields/test_double_encoded_string.py @@ -0,0 +1,23 @@ +from ms_ovba.Models.Fields.doubleEncodedString import ( + DoubleEncodedString +) + + +def test_constructor() -> None: + de_string = DoubleEncodedString([0x01, 0x02], "Foo") + assert isinstance(de_string, DoubleEncodedString) + + +def test_value_property() -> None: + expected = "Foo" + de_string = DoubleEncodedString([0x01, 0x02], expected) + assert de_string.value == expected + + +def test_pack() -> None: + codepage = 0x04E4 + cp_name = "cp" + str(codepage) + de_string = DoubleEncodedString([0x01, 0x02], "Foo") + expected = (b'\x01\x00\x03\x00\x00\x00Foo' + + b'\x02\x00\x06\x00\x00\x00F\x00o\x00o\x00') + assert de_string.pack("little", cp_name) == expected diff --git a/tests/Unit/Models/Fields/test_idSizeField.py b/tests/Unit/Models/Fields/test_idSizeField.py index 033ce3be9..d345bb00a 100644 --- a/tests/Unit/Models/Fields/test_idSizeField.py +++ b/tests/Unit/Models/Fields/test_idSizeField.py @@ -2,7 +2,25 @@ from ms_ovba.Models.Fields.idSizeField import IdSizeField +def test_string() -> None: + field = IdSizeField(1, 2, "Hi") + expected = b'\x01\x00\x02\x00\x00\x00Hi' + assert field.pack("little") == expected + + +def test_H(): + field = IdSizeField(1, 2, 3) + expected = b'\x01\x00\x02\x00\x00\x00\x03\x00' + assert field.pack("little") == expected + + +def test_I(): + field = IdSizeField(1, 4, 3) + expected = b'\x01\x00\x04\x00\x00\x00\x03\x00\x00\x00' + assert field.pack("little") == expected + + def test_bad_value() -> None: field = IdSizeField(2, 3, 6) with pytest.raises(Exception): - field.pack(1234, "little") + field.pack("little") diff --git a/tests/Unit/Models/Fields/test_project_reference.py b/tests/Unit/Models/Fields/test_project_reference.py index 578ba5ade..9c8b12dc7 100644 --- a/tests/Unit/Models/Fields/test_project_reference.py +++ b/tests/Unit/Models/Fields/test_project_reference.py @@ -1,3 +1,4 @@ +import pytest from ms_ovba.Models.Fields.project_reference import ProjectReference @@ -17,6 +18,24 @@ def test_len() -> None: assert len(ref) == 48 -def test_str() -> None: +@pytest.mark.parametrize("data, embedded, expected", [ + ( + "C:\\Example Path\\Example-ReferencedProject.xls", + True, + "*\\CC:\\Example Path\\Example-ReferencedProject.xls" + ), + ( + "/Example Path/Example-ReferencedProject.xls", + False, + "*\\B/Example Path/Example-ReferencedProject.xls" + ) +]) +def test_str(data, embedded, expected) -> None: + ref = ProjectReference(data, embedded) + assert str(ref) == expected + + +def test_relative() -> None: ref = ProjectReference("C:\\Example Path\\Example-ReferencedProject.xls") - assert str(ref) == "*\\CC:\\Example Path\\Example-ReferencedProject.xls" + rel = ref.relative() + assert str(rel) == "*\\CExample-ReferencedProject.xls" diff --git a/tests/Unit/Models/test_vbaProject.py b/tests/Unit/Models/test_vbaProject.py deleted file mode 100644 index dfe9ae557..000000000 --- a/tests/Unit/Models/test_vbaProject.py +++ /dev/null @@ -1,29 +0,0 @@ -import pytest -from ms_ovba.vbaProject import VbaProject - - -def test_set_get_visibility() -> None: - project = VbaProject() - project.set_visibility_state(0) - assert project.get_visibility_state() == 0 - - -def test_set_get_protection() -> None: - project = VbaProject() - project.set_protection_state(0) - assert project.get_protection_state() == 0 - - -def test_set_get_password() -> None: - project = VbaProject() - project.set_password(0) - assert project.get_password() == 0 - - -def test_bad_visibility() -> None: - """ - Visibility must be zero or 0xFF - """ - project = VbaProject() - with pytest.raises(Exception): - project.set_visibility_state(1) diff --git a/tests/Unit/Views/test_project.py b/tests/Unit/Views/test_project.py index 6fae080d0..659cc1c94 100644 --- a/tests/Unit/Views/test_project.py +++ b/tests/Unit/Views/test_project.py @@ -47,21 +47,11 @@ def __init__(self) -> None: self.modules = [Mod("ThisWorkbook"), Mod("Sheet1"), mod1] self.project_id = '{9E394C0B-697E-4AEE-9FA6-446F51FB30DC}' - - def get_codepage_name(self): - return 'cp1252' - - def get_project_id(self): - return self.project_id - - def get_protection_state(self): - return b'\x00\x00\x00\x00' - - def get_password(self): - return b'\x00' - - def get_visibility_state(self): - return b'\xFF' + self.codepage_name = 'cp1252' + self.protection_state = b'\x00\x00\x00\x00' + self.password = b'\x00' + self.visibility_state = b'\xFF' + self.attributes = {} @unittest.mock.patch('random.randint', NotSoRandom.randint) diff --git a/tests/Unit/test_vbaProject.py b/tests/Unit/test_vbaProject.py new file mode 100644 index 000000000..1ca43dcc6 --- /dev/null +++ b/tests/Unit/test_vbaProject.py @@ -0,0 +1,78 @@ +import pytest +from ms_ovba.vbaProject import VbaProject + + +def test_set_get_default_date() -> None: + project = VbaProject() + date = project.default_date + project.default_date = date + assert project.default_date == date + + +def test_set_get_project_id() -> None: + project = VbaProject() + project.project_id = '{test}' + assert project.project_id == '{test}' + + +def test_set_get_visibility() -> None: + project = VbaProject() + project.visibility_state = 0 + assert project.visibility_state == 0 + + +def test_set_get_protection() -> None: + project = VbaProject() + project.protection_state = 0 + assert project.protection_state == 0 + + +def test_set_get_password() -> None: + project = VbaProject() + project.password = 0 + assert project.password == 0 + + +def test_set_get_cache() -> None: + project = VbaProject() + project.performance_cache = b'0' + assert project.performance_cache == b'0' + + +def test_set_get_cache_version() -> None: + project = VbaProject() + project.performance_cache_version = 0x01 + assert project.performance_cache_version == 1 + + +def test_set_get_codepage() -> None: + project = VbaProject() + project.codepage_name = 'cp1253' + assert project.codepage_name == 'cp1253' + + +def test_set_get_cookie() -> None: + project = VbaProject() + project.project_cookie = 0x02 + assert project.project_cookie == 2 + + +def test_include_projectwm() -> None: + project = VbaProject() + project.include_projectwm() + assert project.projectwm + + +def test_exclude_projectwm() -> None: + project = VbaProject() + project.exclude_projectwm() + assert not project.projectwm + + +def test_bad_visibility() -> None: + """ + Visibility must be zero or 0xFF + """ + project = VbaProject() + with pytest.raises(Exception): + project.visibility_state = 1 From 8f9d35e8bba4bb16678585f1e3ccab6a09678e43 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Fri, 13 Mar 2026 10:01:23 -0400 Subject: [PATCH 334/335] Create project_lk.py --- src/ms_ovba/Views/project_lk.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/ms_ovba/Views/project_lk.py diff --git a/src/ms_ovba/Views/project_lk.py b/src/ms_ovba/Views/project_lk.py new file mode 100644 index 000000000..08563ae9e --- /dev/null +++ b/src/ms_ovba/Views/project_lk.py @@ -0,0 +1,29 @@ +import struct +from ms_ovba.vbaProject import VbaProject +from typing import TypeVar + + +T = TypeVar('T', bound='ProjectLk') + + +class ProjectLk: + """ + The ProjectLK data view for the vbaProject + """ + def __init__(self: T, project: VbaProject) -> None: + self.project = project + self._license_records = [] + + def to_bytes(self: T) -> bytes: + output = struct.pack(" None: + bin_f = open("projectlk.bin", "wb") + bin_f.write(self.to_bytes()) + bin_f.close() From 43f6ba0e86d76f1b0b531e9a62549c953055b416 Mon Sep 17 00:00:00 2001 From: Kevin Nowaczyk Date: Sun, 15 Mar 2026 18:56:46 -0400 Subject: [PATCH 335/335] Project lk (#132) --- src/ms_ovba/Models/Entities/license_info.py | 24 ++++++++++++++ .../Views/{project_lk.py => projectLk.py} | 11 +++---- src/ms_ovba/vbaProject.py | 5 +-- .../Unit/Models/Entities/test_license_info.py | 20 ++++++++++++ tests/Unit/Views/test_projectLk.py | 31 +++++++++++++++++++ 5 files changed, 82 insertions(+), 9 deletions(-) create mode 100644 src/ms_ovba/Models/Entities/license_info.py rename src/ms_ovba/Views/{project_lk.py => projectLk.py} (60%) create mode 100644 tests/Unit/Models/Entities/test_license_info.py create mode 100644 tests/Unit/Views/test_projectLk.py diff --git a/src/ms_ovba/Models/Entities/license_info.py b/src/ms_ovba/Models/Entities/license_info.py new file mode 100644 index 000000000..6208eaef2 --- /dev/null +++ b/src/ms_ovba/Models/Entities/license_info.py @@ -0,0 +1,24 @@ +import struct +import uuid +from typing import TypeVar + + +T = TypeVar('T', bound='LicenseInfo') + + +class LicenseInfo: + def __init__(self: T, guid: uuid.UUID, key: bytes) -> None: + self._guid = guid + self._key = key + self._required = len(key) > 0 + + def not_required(self: T) -> None: + self._required = False + + def to_bytes(self: T) -> bytes: + return ( + self._guid.bytes + + struct.pack(" None: self.project = project - self._license_records = [] def to_bytes(self: T) -> bytes: - output = struct.pack(" None: diff --git a/src/ms_ovba/vbaProject.py b/src/ms_ovba/vbaProject.py index bad5457f3..6feb76806 100644 --- a/src/ms_ovba/vbaProject.py +++ b/src/ms_ovba/vbaProject.py @@ -24,12 +24,13 @@ def __init__(self: T) -> None: self._performance_cache = b'' self._performance_cache_version = 0xFFFF - # A list of directories + # Lists self.directories = [] self.references = [] self.modules = [] + self._license_records = [] - # A list of attributes and values + # Attributes and values self.attributes = {} self._project_cookie = 0xFFFF diff --git a/tests/Unit/Models/Entities/test_license_info.py b/tests/Unit/Models/Entities/test_license_info.py new file mode 100644 index 000000000..8ac76dee8 --- /dev/null +++ b/tests/Unit/Models/Entities/test_license_info.py @@ -0,0 +1,20 @@ +import uuid +from ms_ovba.Models.Entities.license_info import LicenseInfo + + +guid = uuid.UUID("2DF8D04C5BFA101BBDE500AA0044DE52") +key = b'Key' +out = LicenseInfo(guid, key) + + +def test_to_bytes() -> None: + expected = (b'-\xF8\xD0L[\xFA\x10\x1B\xBD\xE5\x00\xAA\x00D\xDER' + + b'\x03\x00\x00\x00Key\x01\x00\x00\x00') + assert out.to_bytes() == expected + + +def test_not_required() -> None: + expected = (b'-\xF8\xD0L[\xFA\x10\x1B\xBD\xE5\x00\xAA\x00D\xDER' + + b'\x03\x00\x00\x00Key\x00\x00\x00\x00') + out.not_required() + assert out.to_bytes() == expected diff --git a/tests/Unit/Views/test_projectLk.py b/tests/Unit/Views/test_projectLk.py new file mode 100644 index 000000000..cfed0a7e8 --- /dev/null +++ b/tests/Unit/Views/test_projectLk.py @@ -0,0 +1,31 @@ +from ms_ovba.Views.projectLk import ProjectLk + + +class MockVbaProject: + def __init__(self) -> None: + self._license_records = [] + + +class MockLicense: + def to_bytes(self) -> bytes: + return b'Test' + + +def test_project_lk_empty() -> None: + vba_project = MockVbaProject() + project_lk = ProjectLk(vba_project) + + expected = (b'\x01\x00\x00\x00\x00\x00') + result = project_lk.to_bytes() + assert result == expected + + +def test_project_lk() -> None: + vba_project = MockVbaProject() + mock_license = MockLicense() + vba_project._license_records = [mock_license] + project_lk = ProjectLk(vba_project) + + expected = (b'\x01\x00\x01\x00\x00\x00Test') + result = project_lk.to_bytes() + assert result == expected