extract-msg 0.56.0__tar.gz → 0.57.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. {extract_msg-0.56.0 → extract_msg-0.57.0}/CHANGELOG.md +20 -0
  2. {extract_msg-0.56.0 → extract_msg-0.57.0}/PKG-INFO +64 -51
  3. {extract_msg-0.56.0 → extract_msg-0.57.0}/README.rst +62 -50
  4. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/__init__.py +3 -3
  5. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/__main__.py +3 -1
  6. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/attachments/custom_att_handler/lnk_obj_att.py +2 -2
  7. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/attachments/web_att.py +1 -1
  8. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/constants/__init__.py +1 -1
  9. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/constants/ps.py +1 -1
  10. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/constants/re.py +4 -0
  11. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/constants/st.py +2 -2
  12. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/encoding/utils.py +24 -20
  13. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/message_base.py +83 -6
  14. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/msg.py +68 -19
  15. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/ole_writer.py +2 -2
  16. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/utils.py +12 -1
  17. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg.egg-info/PKG-INFO +64 -51
  18. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg.egg-info/requires.txt +3 -0
  19. {extract_msg-0.56.0 → extract_msg-0.57.0}/setup.cfg +2 -0
  20. {extract_msg-0.56.0 → extract_msg-0.57.0}/LICENSE.txt +0 -0
  21. {extract_msg-0.56.0 → extract_msg-0.57.0}/MANIFEST.in +0 -0
  22. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/_rtf/__init__.py +0 -0
  23. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/_rtf/create_doc.py +0 -0
  24. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/_rtf/inject_rtf.py +0 -0
  25. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/_rtf/token.py +0 -0
  26. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/_rtf/tokenize_rtf.py +0 -0
  27. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/attachments/__init__.py +0 -0
  28. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/attachments/attachment.py +0 -0
  29. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/attachments/attachment_base.py +0 -0
  30. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/attachments/broken_att.py +0 -0
  31. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/attachments/custom_att.py +0 -0
  32. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/attachments/custom_att_handler/__init__.py +0 -0
  33. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/attachments/custom_att_handler/custom_handler.py +0 -0
  34. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/attachments/custom_att_handler/outlook_image_dib.py +0 -0
  35. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/attachments/custom_att_handler/outlook_image_meta.py +0 -0
  36. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/attachments/emb_msg_att.py +0 -0
  37. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/attachments/signed_att.py +0 -0
  38. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/attachments/unsupported_att.py +0 -0
  39. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/data/logging-config/logging-nt.json +0 -0
  40. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/data/logging-config/logging-posix.json +0 -0
  41. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/encoding/__init__.py +0 -0
  42. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/encoding/_dt/__init__.py +0 -0
  43. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/encoding/_dt/_mac_ce.py +0 -0
  44. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/encoding/_dt/_mac_cyrillic.py +0 -0
  45. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/encoding/_dt/_mac_greek.py +0 -0
  46. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/encoding/_dt/_mac_iceland.py +0 -0
  47. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/encoding/_dt/_mac_turkish.py +0 -0
  48. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/encoding/_dt/_win874_dec.py +0 -0
  49. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/encoding/_dt/_win950_dec.py +0 -0
  50. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/enums.py +0 -0
  51. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/exceptions.py +0 -0
  52. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/__init__.py +0 -0
  53. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/appointment.py +0 -0
  54. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/calendar.py +0 -0
  55. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/calendar_base.py +0 -0
  56. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/contact.py +0 -0
  57. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/journal.py +0 -0
  58. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/meeting_cancellation.py +0 -0
  59. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/meeting_exception.py +0 -0
  60. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/meeting_forward.py +0 -0
  61. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/meeting_related.py +0 -0
  62. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/meeting_request.py +0 -0
  63. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/meeting_response.py +0 -0
  64. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/message.py +0 -0
  65. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/message_signed.py +0 -0
  66. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/message_signed_base.py +0 -0
  67. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/post.py +0 -0
  68. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/sticky_note.py +0 -0
  69. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/task.py +0 -0
  70. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/msg_classes/task_request.py +0 -0
  71. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/null_date.py +0 -0
  72. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/open_msg.py +0 -0
  73. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/properties/__init__.py +0 -0
  74. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/properties/named.py +0 -0
  75. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/properties/prop.py +0 -0
  76. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/properties/properties_store.py +0 -0
  77. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/py.typed +0 -0
  78. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/recipient.py +0 -0
  79. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/__init__.py +0 -0
  80. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/_helpers.py +0 -0
  81. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/business_card.py +0 -0
  82. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/cfoas.py +0 -0
  83. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/contact_link_entry.py +0 -0
  84. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/dev_mode_a.py +0 -0
  85. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/dv_target_device.py +0 -0
  86. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/entry_id.py +0 -0
  87. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/misc_id.py +0 -0
  88. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/mon_stream.py +0 -0
  89. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/odt.py +0 -0
  90. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/ole_pres.py +0 -0
  91. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/ole_stream_struct.py +0 -0
  92. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/recurrence_pattern.py +0 -0
  93. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/report_tag.py +0 -0
  94. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/system_time.py +0 -0
  95. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/time_zone_definition.py +0 -0
  96. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/time_zone_struct.py +0 -0
  97. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/toc_entry.py +0 -0
  98. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg/structures/tz_rule.py +0 -0
  99. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg.egg-info/SOURCES.txt +0 -0
  100. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg.egg-info/dependency_links.txt +0 -0
  101. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg.egg-info/entry_points.txt +0 -0
  102. {extract_msg-0.56.0 → extract_msg-0.57.0}/extract_msg.egg-info/top_level.txt +0 -0
  103. {extract_msg-0.56.0 → extract_msg-0.57.0}/requirements.txt +0 -0
  104. {extract_msg-0.56.0 → extract_msg-0.57.0}/setup.py +0 -0
@@ -1,3 +1,23 @@
1
+ **v0.57.0**
2
+ * [[Advisory GHSA-cxpg-prmv-g4pp](https://github.com/TeamMsgExtractor/msg-extractor/security/advisories/GHSA-cxpg-prmv-g4pp)] Fixed a vulnerability related to unchecked input passed out to wkhtmltopdf when converting the MSG file to PDF. Javascript is now strongly blocked from being enabled and will be stripped from the HTML where appropriate before reaching wkhtmltopdf. Additionally, the option `--wk-allow-external-files` on the command line (or `wkAllowExternalFiles` to `MessageBase.save()`) will be required for external files to be loaded into the HTML to convert. Without these, they will be stripped before reaching wkhtmltopdf for security.
3
+ * [[Advisory GHSA-mqxr-j8rh-p4q4](https://github.com/TeamMsgExtractor/msg-extractor/security/advisories/GHSA-mqxr-j8rh-p4q4)] Fixed an issue where an attacker controlled MSG file could take advantage of a poorly written section of code in the RTF deencapsulation function on the `extract-msg` side to waste massive amounts of time and memory resources.
4
+ * [[Advisory GHSA-rgjf-vmqv-8pv9](https://github.com/TeamMsgExtractor/msg-extractor/security/advisories/GHSA-rgjf-vmqv-8pv9)] Change the way multiple type properties are accessed for binary and string. This includes modifications to `MSGFile.getMultipleBinary()`, `MSGFile.getMultipleString()`, and `MSGFile.exists()` to significantly reduce wasted times for malicious files. Malicious files previously could cause extract-msg to do unnecessarily large numbers of calls to `MSGFile.exists()` which previously did not use caching to speed up its search.
5
+ * Changed `MSGFile.listDir()` to return a tuple of tuples to prevent it's cache results from being tampered with.
6
+ * Fixed an issue with `MSGFile.listDir()` that caused it to not cache in certain circumstances when it should always cache.
7
+ * Fixed a check in `MSGFile.getMultipleBinary()` that executed wrong and did not properly check for bad data.
8
+ * Fixed `MSGFile._getTypedSteam()` to correctly parse binary and string streams when an entry is missing.
9
+ * Fixed `StandardViolationError` being raised without checking error behavior in `MSGFile.getMultipleBinary()` and `MSGFile.getMultipleString()`.
10
+ * Added check for standard violation in `MSGFile.getMultipleString()` that is raised (or logged, depending on error behavior) if a string stream is missing a null byte. This also doesn't strip the last character in the stream if it is not null.
11
+ * Added length check log to `MSGFile.getMultipleBinary()` and `MSGFile.getMultipleString()` that checks to see if the expected length for each stream matches what the length stream says. If not, it logs a warning about the mismatch, but does not consider this a gross violation of the standard.
12
+ * Changed how `MessageBase.deencapsulatedRtf` handles RTF data without a closing brace.
13
+ * Fixed wrong return being used in `extract_msg.encoding.utils.singleByteEncode()` and `extract_msg.encoding.utils.variableByteEncode()`.
14
+ * Fixed missing return in `extract_msg.encoding.utils.singleByteEncode()`.
15
+ * Fixed wrong parameter names for codec types made in `extract_msg.encoding.utils.createSBEncoding()` and `extract_msg.encoding.utils.createVBEncoding()`.
16
+ * Fix some values being incorrectly returned from encode/decode functions in `extract_msg.encoding.utils`.
17
+
18
+ **v0.56.1**
19
+ * [[TeamMsgExtractor #484](https://github.com/TeamMsgExtractor/msg-extractor/issues/484)] Corrected the way the HTML body is decoded in `MessageBase.asEmailMessage()` to prevent encoding errors.
20
+
1
21
  **v0.56.0**
2
22
  * [[TeamMsgExtractor #478](https://github.com/TeamMsgExtractor/msg-extractor/issues/478)] Expand allowable versions of `ebcdic` to include `2.x`. The 2.0 release is a pure technical release with no functional changes; it only drops support for Python 2 and 3.8. The lower bound is unchanged so installs on Python 3.8 will continue to resolve to `ebcdic 1.1.1`.
3
23
  * [[TeamMsgExtractor #469](https://github.com/TeamMsgExtractor/msg-extractor/issues/469)] Expanded `beautifulsoup` to allow for versions up to `5.*.*`. I was previously hesitant to do so because they sometimes do what seems like non backwards compatible changes in minor versions, but it looks like this should be fine.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: extract_msg
3
- Version: 0.56.0
3
+ Version: 0.57.0
4
4
  Summary: Extracts emails and attachments saved in Microsoft Outlook's .msg files
5
5
  Home-page: https://github.com/TeamMsgExtractor/msg-extractor
6
6
  Download-URL: https://github.com/TeamMsgExtractor/msg-extractor/archives/master
@@ -14,9 +14,10 @@ Provides-Extra: mime
14
14
  Provides-Extra: image
15
15
  Provides-Extra: encoding
16
16
  Provides-Extra: readthedocs
17
+ Provides-Extra: test
17
18
  License-File: LICENSE.txt
18
19
 
19
- |License: GPL v3| |PyPI3| |PyPI2| |Read the Docs|
20
+ |License: GPL v3| |PyPI3| |PyPI2| |Downloads| |Read the Docs|
20
21
 
21
22
  extract-msg
22
23
  =============
@@ -32,7 +33,7 @@ Documentation can be found in the code, on the `wiki`_, and on the
32
33
  NOTICE
33
34
  ======
34
35
  0.29.* is the branch that supports both Python 2 and Python 3. It is now only
35
- receiving bug fixes and will not be receiving feature updates.
36
+ receiving security fixes and will not be receiving feature updates.
36
37
 
37
38
  0.39.* is the last versions that supported Python 3.6 and 3.7. Support for those
38
39
  was dropped to allow the use of new features from 3.8 and because the life spans
@@ -77,55 +78,59 @@ Currently, the README is in the process of being redone. For now, please
77
78
  refer to the usage information provided from the program's help dialog:
78
79
  ::
79
80
 
80
- usage: extract_msg [-h] [--use-content-id] [--json] [--file-logging] [-v] [--log LOG] [--config CONFIGPATH] [--out OUTPATH] [--use-filename] [--dump-stdout] [--html] [--pdf] [--wk-path WKPATH] [--wk-options [WKOPTIONS ...]]
81
- [--prepared-html] [--charset CHARSET] [--raw] [--rtf] [--allow-fallback] [--skip-body-not-found] [--zip ZIP] [--save-header] [--attachments-only] [--skip-hidden] [--no-folders] [--skip-embedded] [--extract-embedded]
82
- [--overwrite-existing] [--skip-not-implemented] [--out-name OUTNAME | --glob] [--ignore-rtfde] [--progress] [-s]
83
- msg [msg ...]
81
+ usage: extract_msg [-h] [--use-content-id] [--json] [--file-logging] [-v] [--log LOG] [--config CONFIGPATH] [--out OUTPATH] [--use-filename] [--dump-stdout] [--html]
82
+ [--pdf] [--wk-path WKPATH] [--wk-options [WKOPTIONS ...]] [--wk-allow-external-files] [--prepared-html] [--charset CHARSET] [--raw] [--rtf]
83
+ [--allow-fallback] [--skip-body-not-found] [--zip ZIP] [--save-header] [--attachments-only] [--skip-hidden] [--no-folders] [--skip-embedded]
84
+ [--extract-embedded] [--overwrite-existing] [--skip-not-implemented] [--out-name OUTNAME | --glob] [--ignore-rtfde] [--progress] [-s]
85
+ [msg ...]
84
86
 
85
87
  extract_msg: Extracts emails and attachments saved in Microsoft Outlook's .msg files. https://github.com/TeamMsgExtractor/msg-extractor
86
88
 
87
89
  positional arguments:
88
- msg An MSG file to be parsed.
90
+ msg An MSG file to be parsed.
89
91
 
90
92
  options:
91
- -h, --help show this help message and exit
92
- --use-content-id, --cid
93
- Save attachments by their Content ID, if they have one. Useful when working with the HTML body.
94
- --json Changes to write output files as json.
95
- --file-logging Enables file logging. Implies --verbose level 1.
96
- -v, --verbose Turns on console logging. Specify more than once for higher verbosity.
97
- --log LOG Set the path to write the file log to.
98
- --config CONFIGPATH Set the path to load the logging config from.
99
- --out OUTPATH Set the folder to use for the program output. (Default: Current directory)
100
- --use-filename Sets whether the name of each output is based on the msg filename.
101
- --dump-stdout Tells the program to dump the message body (plain text) to stdout. Overrides saving arguments.
102
- --html Sets whether the output should be HTML. If this is not possible, will error.
103
- --pdf Saves the body as a PDF. If this is not possible, will error.
104
- --wk-path WKPATH Overrides the path for finding wkhtmltopdf.
105
- --wk-options [WKOPTIONS ...]
106
- Sets additional options to be used in wkhtmltopdf. Should be a series of options and values, replacing the - or -- in the beginning with + or ++, respectively. For example: --wk-options "+O Landscape"
107
- --prepared-html When used in conjunction with --html, sets whether the HTML output should be prepared for embedded attachments.
108
- --charset CHARSET Character set to use for the prepared HTML in the added tag. (Default: utf-8)
109
- --raw Sets whether the output should be raw. If this is not possible, will error.
110
- --rtf Sets whether the output should be RTF. If this is not possible, will error.
111
- --allow-fallback Tells the program to fallback to a different save type if the selected one is not possible.
112
- --skip-body-not-found
113
- Skips saving the body if the body cannot be found, rather than throwing an error.
114
- --zip ZIP Path to use for saving to a zip file.
115
- --save-header Store the header in a separate file.
116
- --attachments-only Specify to only save attachments from an msg file.
117
- --skip-hidden Skips any attachment marked as hidden (usually ones embedded in the body).
118
- --no-folders Stores everything in the location specified by --out. Requires --attachments-only and is incompatible with --out-name.
119
- --skip-embedded Skips all embedded MSG files when saving attachments.
120
- --extract-embedded Extracts the embedded MSG files as MSG files instead of running their save functions.
121
- --overwrite-existing Disables filename conflict resolution code for attachments when saving a file, causing files to be overwriten if two attachments with the same filename are on an MSG file.
122
- --skip-not-implemented, --skip-ni
123
- Skips any attachments that are not implemented, allowing saving of the rest of the message.
124
- --out-name OUTNAME Name to be used with saving the file output. Cannot be used if you are saving more than one file.
125
- --glob, --wildcard Interpret all paths as having wildcards. Incompatible with --out-name.
126
- --ignore-rtfde Ignores all errors thrown from RTFDE when trying to save. Useful for allowing fallback to continue when an exception happens.
127
- --progress Shows what file the program is currently working on during it's progress.
128
- -s, --stdin Read file from stdin (only works with one file at a time).
93
+ -h, --help show this help message and exit
94
+ --use-content-id, --cid
95
+ Save attachments by their Content ID, if they have one. Useful when working with the HTML body.
96
+ --json Changes to write output files as json.
97
+ --file-logging Enables file logging. Implies --verbose level 1.
98
+ -v, --verbose Turns on console logging. Specify more than once for higher verbosity.
99
+ --log LOG Set the path to write the file log to.
100
+ --config CONFIGPATH Set the path to load the logging config from.
101
+ --out OUTPATH Set the folder to use for the program output. (Default: Current directory)
102
+ --use-filename Sets whether the name of each output is based on the MSG filename.
103
+ --dump-stdout Tells the program to dump the message body (plain text) to stdout. Overrides saving arguments.
104
+ --html Sets whether the output should be HTML. If this is not possible, will error.
105
+ --pdf Saves the body as a PDF. If this is not possible, will error.
106
+ --wk-path WKPATH Overrides the path for finding wkhtmltopdf.
107
+ --wk-options [WKOPTIONS ...]
108
+ Sets additional options to be used in wkhtmltopdf. Should be a series of options and values, replacing the - or -- in the beginning with + or ++ respectively. For example: --wk-options "+O Landscape"
109
+ --wk-allow-external-files
110
+ Enables external files to appear in the PDF output. WARNING: This allows wkpdftohtml to make url requests that are unchecked, and as such may be a security vulnerability in untrusted emails. Only use this option if you trust the source of the MSG file.
111
+ --prepared-html When used in conjunction with --html, sets whether the HTML output should be prepared for embedded attachments.
112
+ --charset CHARSET Character set to use for the prepared HTML in the added tag. (Default: utf-8)
113
+ --raw Sets whether the output should be raw. If this is not possible, will error.
114
+ --rtf Sets whether the output should be RTF. If this is not possible, will error.
115
+ --allow-fallback Tells the program to fallback to a different save type if the selected one is not possible.
116
+ --skip-body-not-found
117
+ Skips saving the body if the body cannot be found, rather than throwing an error.
118
+ --zip ZIP Path to use for saving to a zip file.
119
+ --save-header Store the header in a separate file.
120
+ --attachments-only Specify to only save attachments from an MSG file.
121
+ --skip-hidden Skips any attachment marked as hidden (usually ones embedded in the body).
122
+ --no-folders Stores everything in the location specified by --out. Requires --attachments-only and is incompatible with --out-name.
123
+ --skip-embedded Skips all embedded MSG files when saving attachments.
124
+ --extract-embedded Extracts the embedded MSG files as MSG files instead of running their save functions.
125
+ --overwrite-existing Disables filename conflict resolution code for attachments when saving a file, causing files to be overwritten if two attachments with the same
126
+ filename are on an MSG file.
127
+ --skip-not-implemented, --skip-ni
128
+ Skips any attachments that are not implemented, allowing saving of the rest of the message.
129
+ --out-name OUTNAME Name to be used with saving the file output. Cannot be used if you are saving more than one file.
130
+ --glob, --wildcard Interpret all paths as having wildcards. Incompatible with --out-name.
131
+ --ignore-rtfde Ignores all errors thrown from RTFDE when trying to save. Useful for allowing fallback to continue when an exception happens.
132
+ --progress Shows what file the program is currently working on during it's progress.
133
+ -s, --stdin Read file from stdin (only works with one file at a time).
129
134
 
130
135
  **To use this in your own script**, start by using:
131
136
 
@@ -140,7 +145,7 @@ From there, open the MSG file:
140
145
  msg = extract_msg.openMsg("path/to/msg/file.msg")
141
146
 
142
147
  Alternatively, if you wish to send a msg binary string instead of a file
143
- to the ``extract_msg.openMsg`` Method:
148
+ to the ``extract_msg.openMsg()`` Method:
144
149
 
145
150
  ::
146
151
 
@@ -256,14 +261,18 @@ Credits
256
261
 
257
262
  `Philippe Lagadec`_ - Python OleFile module developer.
258
263
 
264
+ `Seamus Tuohy`_ - Developer of the Python RTFDE module. Gave first examples of how to use the module and has worked with Destiny to ensure functionality.
265
+
266
+ `Kadhiraven EG`_ - Discovery of and assistance with vulnerability in PDF conversion, including assistance with updating security policies and notifying the public about the vulnerability.
267
+
259
268
  `Joel Kaufman`_ - First implementations of the json and filename flags.
260
269
 
261
270
  `Dean Malmgren`_ - First implementation of the setup.py script.
262
271
 
263
- `Seamus Tuohy`_ - Developer of the Python RTFDE module. Gave first examples of how to use the module and has worked with Destiny to ensure functionality.
264
-
265
272
  `Liam`_ - Significant reorganization and transfer of data.
266
273
 
274
+
275
+
267
276
  And thank you to everyone who has opened an issue and helped us track down those pesky bugs.
268
277
 
269
278
  Extra
@@ -278,12 +287,15 @@ your access to the newest major version of extract-msg.
278
287
  .. |License: GPL v3| image:: https://img.shields.io/badge/License-GPLv3-blue.svg
279
288
  :target: LICENSE.txt
280
289
 
281
- .. |PyPI3| image:: https://img.shields.io/badge/pypi-0.56.0-blue.svg
282
- :target: https://pypi.org/project/extract-msg/0.56.0/
290
+ .. |PyPI3| image:: https://img.shields.io/badge/pypi-0.57.0-blue.svg
291
+ :target: https://pypi.org/project/extract-msg/0.57.0/
283
292
 
284
293
  .. |PyPI2| image:: https://img.shields.io/badge/python-3.8+-brightgreen.svg
285
294
  :target: https://www.python.org/downloads/release/python-3810/
286
295
 
296
+ .. |Downloads| image:: https://img.shields.io/pypi/dm/extract-msg.svg
297
+ :target: https://pypistats.org/packages/extract-msg
298
+
287
299
  .. |Read the Docs| image:: https://readthedocs.org/projects/msg-extractor/badge/?version=latest
288
300
  :target: https://msg-extractor.readthedocs.io/en/stable/?badge=latest
289
301
  :alt: Documentation Status
@@ -295,6 +307,7 @@ your access to the newest major version of extract-msg.
295
307
  .. _Dean Malmgren: https://github.com/deanmalmgren
296
308
  .. _Joel Kaufman: https://github.com/joelkaufman
297
309
  .. _Liam: https://github.com/LiamPM5
310
+ .. _Kadhiraven EG: https://github.com/JOKER-53
298
311
  .. _Seamus Tuohy: https://github.com/seamustuohy
299
312
  .. _Discord: https://discord.com/invite/B77McRmzdc
300
313
  .. _Buy Me a Coffee: https://www.buymeacoffee.com/DestructionE
@@ -1,4 +1,4 @@
1
- |License: GPL v3| |PyPI3| |PyPI2| |Read the Docs|
1
+ |License: GPL v3| |PyPI3| |PyPI2| |Downloads| |Read the Docs|
2
2
 
3
3
  extract-msg
4
4
  =============
@@ -14,7 +14,7 @@ Documentation can be found in the code, on the `wiki`_, and on the
14
14
  NOTICE
15
15
  ======
16
16
  0.29.* is the branch that supports both Python 2 and Python 3. It is now only
17
- receiving bug fixes and will not be receiving feature updates.
17
+ receiving security fixes and will not be receiving feature updates.
18
18
 
19
19
  0.39.* is the last versions that supported Python 3.6 and 3.7. Support for those
20
20
  was dropped to allow the use of new features from 3.8 and because the life spans
@@ -59,55 +59,59 @@ Currently, the README is in the process of being redone. For now, please
59
59
  refer to the usage information provided from the program's help dialog:
60
60
  ::
61
61
 
62
- usage: extract_msg [-h] [--use-content-id] [--json] [--file-logging] [-v] [--log LOG] [--config CONFIGPATH] [--out OUTPATH] [--use-filename] [--dump-stdout] [--html] [--pdf] [--wk-path WKPATH] [--wk-options [WKOPTIONS ...]]
63
- [--prepared-html] [--charset CHARSET] [--raw] [--rtf] [--allow-fallback] [--skip-body-not-found] [--zip ZIP] [--save-header] [--attachments-only] [--skip-hidden] [--no-folders] [--skip-embedded] [--extract-embedded]
64
- [--overwrite-existing] [--skip-not-implemented] [--out-name OUTNAME | --glob] [--ignore-rtfde] [--progress] [-s]
65
- msg [msg ...]
62
+ usage: extract_msg [-h] [--use-content-id] [--json] [--file-logging] [-v] [--log LOG] [--config CONFIGPATH] [--out OUTPATH] [--use-filename] [--dump-stdout] [--html]
63
+ [--pdf] [--wk-path WKPATH] [--wk-options [WKOPTIONS ...]] [--wk-allow-external-files] [--prepared-html] [--charset CHARSET] [--raw] [--rtf]
64
+ [--allow-fallback] [--skip-body-not-found] [--zip ZIP] [--save-header] [--attachments-only] [--skip-hidden] [--no-folders] [--skip-embedded]
65
+ [--extract-embedded] [--overwrite-existing] [--skip-not-implemented] [--out-name OUTNAME | --glob] [--ignore-rtfde] [--progress] [-s]
66
+ [msg ...]
66
67
 
67
68
  extract_msg: Extracts emails and attachments saved in Microsoft Outlook's .msg files. https://github.com/TeamMsgExtractor/msg-extractor
68
69
 
69
70
  positional arguments:
70
- msg An MSG file to be parsed.
71
+ msg An MSG file to be parsed.
71
72
 
72
73
  options:
73
- -h, --help show this help message and exit
74
- --use-content-id, --cid
75
- Save attachments by their Content ID, if they have one. Useful when working with the HTML body.
76
- --json Changes to write output files as json.
77
- --file-logging Enables file logging. Implies --verbose level 1.
78
- -v, --verbose Turns on console logging. Specify more than once for higher verbosity.
79
- --log LOG Set the path to write the file log to.
80
- --config CONFIGPATH Set the path to load the logging config from.
81
- --out OUTPATH Set the folder to use for the program output. (Default: Current directory)
82
- --use-filename Sets whether the name of each output is based on the msg filename.
83
- --dump-stdout Tells the program to dump the message body (plain text) to stdout. Overrides saving arguments.
84
- --html Sets whether the output should be HTML. If this is not possible, will error.
85
- --pdf Saves the body as a PDF. If this is not possible, will error.
86
- --wk-path WKPATH Overrides the path for finding wkhtmltopdf.
87
- --wk-options [WKOPTIONS ...]
88
- Sets additional options to be used in wkhtmltopdf. Should be a series of options and values, replacing the - or -- in the beginning with + or ++, respectively. For example: --wk-options "+O Landscape"
89
- --prepared-html When used in conjunction with --html, sets whether the HTML output should be prepared for embedded attachments.
90
- --charset CHARSET Character set to use for the prepared HTML in the added tag. (Default: utf-8)
91
- --raw Sets whether the output should be raw. If this is not possible, will error.
92
- --rtf Sets whether the output should be RTF. If this is not possible, will error.
93
- --allow-fallback Tells the program to fallback to a different save type if the selected one is not possible.
94
- --skip-body-not-found
95
- Skips saving the body if the body cannot be found, rather than throwing an error.
96
- --zip ZIP Path to use for saving to a zip file.
97
- --save-header Store the header in a separate file.
98
- --attachments-only Specify to only save attachments from an msg file.
99
- --skip-hidden Skips any attachment marked as hidden (usually ones embedded in the body).
100
- --no-folders Stores everything in the location specified by --out. Requires --attachments-only and is incompatible with --out-name.
101
- --skip-embedded Skips all embedded MSG files when saving attachments.
102
- --extract-embedded Extracts the embedded MSG files as MSG files instead of running their save functions.
103
- --overwrite-existing Disables filename conflict resolution code for attachments when saving a file, causing files to be overwriten if two attachments with the same filename are on an MSG file.
104
- --skip-not-implemented, --skip-ni
105
- Skips any attachments that are not implemented, allowing saving of the rest of the message.
106
- --out-name OUTNAME Name to be used with saving the file output. Cannot be used if you are saving more than one file.
107
- --glob, --wildcard Interpret all paths as having wildcards. Incompatible with --out-name.
108
- --ignore-rtfde Ignores all errors thrown from RTFDE when trying to save. Useful for allowing fallback to continue when an exception happens.
109
- --progress Shows what file the program is currently working on during it's progress.
110
- -s, --stdin Read file from stdin (only works with one file at a time).
74
+ -h, --help show this help message and exit
75
+ --use-content-id, --cid
76
+ Save attachments by their Content ID, if they have one. Useful when working with the HTML body.
77
+ --json Changes to write output files as json.
78
+ --file-logging Enables file logging. Implies --verbose level 1.
79
+ -v, --verbose Turns on console logging. Specify more than once for higher verbosity.
80
+ --log LOG Set the path to write the file log to.
81
+ --config CONFIGPATH Set the path to load the logging config from.
82
+ --out OUTPATH Set the folder to use for the program output. (Default: Current directory)
83
+ --use-filename Sets whether the name of each output is based on the MSG filename.
84
+ --dump-stdout Tells the program to dump the message body (plain text) to stdout. Overrides saving arguments.
85
+ --html Sets whether the output should be HTML. If this is not possible, will error.
86
+ --pdf Saves the body as a PDF. If this is not possible, will error.
87
+ --wk-path WKPATH Overrides the path for finding wkhtmltopdf.
88
+ --wk-options [WKOPTIONS ...]
89
+ Sets additional options to be used in wkhtmltopdf. Should be a series of options and values, replacing the - or -- in the beginning with + or ++ respectively. For example: --wk-options "+O Landscape"
90
+ --wk-allow-external-files
91
+ Enables external files to appear in the PDF output. WARNING: This allows wkpdftohtml to make url requests that are unchecked, and as such may be a security vulnerability in untrusted emails. Only use this option if you trust the source of the MSG file.
92
+ --prepared-html When used in conjunction with --html, sets whether the HTML output should be prepared for embedded attachments.
93
+ --charset CHARSET Character set to use for the prepared HTML in the added tag. (Default: utf-8)
94
+ --raw Sets whether the output should be raw. If this is not possible, will error.
95
+ --rtf Sets whether the output should be RTF. If this is not possible, will error.
96
+ --allow-fallback Tells the program to fallback to a different save type if the selected one is not possible.
97
+ --skip-body-not-found
98
+ Skips saving the body if the body cannot be found, rather than throwing an error.
99
+ --zip ZIP Path to use for saving to a zip file.
100
+ --save-header Store the header in a separate file.
101
+ --attachments-only Specify to only save attachments from an MSG file.
102
+ --skip-hidden Skips any attachment marked as hidden (usually ones embedded in the body).
103
+ --no-folders Stores everything in the location specified by --out. Requires --attachments-only and is incompatible with --out-name.
104
+ --skip-embedded Skips all embedded MSG files when saving attachments.
105
+ --extract-embedded Extracts the embedded MSG files as MSG files instead of running their save functions.
106
+ --overwrite-existing Disables filename conflict resolution code for attachments when saving a file, causing files to be overwritten if two attachments with the same
107
+ filename are on an MSG file.
108
+ --skip-not-implemented, --skip-ni
109
+ Skips any attachments that are not implemented, allowing saving of the rest of the message.
110
+ --out-name OUTNAME Name to be used with saving the file output. Cannot be used if you are saving more than one file.
111
+ --glob, --wildcard Interpret all paths as having wildcards. Incompatible with --out-name.
112
+ --ignore-rtfde Ignores all errors thrown from RTFDE when trying to save. Useful for allowing fallback to continue when an exception happens.
113
+ --progress Shows what file the program is currently working on during it's progress.
114
+ -s, --stdin Read file from stdin (only works with one file at a time).
111
115
 
112
116
  **To use this in your own script**, start by using:
113
117
 
@@ -122,7 +126,7 @@ From there, open the MSG file:
122
126
  msg = extract_msg.openMsg("path/to/msg/file.msg")
123
127
 
124
128
  Alternatively, if you wish to send a msg binary string instead of a file
125
- to the ``extract_msg.openMsg`` Method:
129
+ to the ``extract_msg.openMsg()`` Method:
126
130
 
127
131
  ::
128
132
 
@@ -238,14 +242,18 @@ Credits
238
242
 
239
243
  `Philippe Lagadec`_ - Python OleFile module developer.
240
244
 
245
+ `Seamus Tuohy`_ - Developer of the Python RTFDE module. Gave first examples of how to use the module and has worked with Destiny to ensure functionality.
246
+
247
+ `Kadhiraven EG`_ - Discovery of and assistance with vulnerability in PDF conversion, including assistance with updating security policies and notifying the public about the vulnerability.
248
+
241
249
  `Joel Kaufman`_ - First implementations of the json and filename flags.
242
250
 
243
251
  `Dean Malmgren`_ - First implementation of the setup.py script.
244
252
 
245
- `Seamus Tuohy`_ - Developer of the Python RTFDE module. Gave first examples of how to use the module and has worked with Destiny to ensure functionality.
246
-
247
253
  `Liam`_ - Significant reorganization and transfer of data.
248
254
 
255
+
256
+
249
257
  And thank you to everyone who has opened an issue and helped us track down those pesky bugs.
250
258
 
251
259
  Extra
@@ -260,12 +268,15 @@ your access to the newest major version of extract-msg.
260
268
  .. |License: GPL v3| image:: https://img.shields.io/badge/License-GPLv3-blue.svg
261
269
  :target: LICENSE.txt
262
270
 
263
- .. |PyPI3| image:: https://img.shields.io/badge/pypi-0.56.0-blue.svg
264
- :target: https://pypi.org/project/extract-msg/0.56.0/
271
+ .. |PyPI3| image:: https://img.shields.io/badge/pypi-0.57.0-blue.svg
272
+ :target: https://pypi.org/project/extract-msg/0.57.0/
265
273
 
266
274
  .. |PyPI2| image:: https://img.shields.io/badge/python-3.8+-brightgreen.svg
267
275
  :target: https://www.python.org/downloads/release/python-3810/
268
276
 
277
+ .. |Downloads| image:: https://img.shields.io/pypi/dm/extract-msg.svg
278
+ :target: https://pypistats.org/packages/extract-msg
279
+
269
280
  .. |Read the Docs| image:: https://readthedocs.org/projects/msg-extractor/badge/?version=latest
270
281
  :target: https://msg-extractor.readthedocs.io/en/stable/?badge=latest
271
282
  :alt: Documentation Status
@@ -277,6 +288,7 @@ your access to the newest major version of extract-msg.
277
288
  .. _Dean Malmgren: https://github.com/deanmalmgren
278
289
  .. _Joel Kaufman: https://github.com/joelkaufman
279
290
  .. _Liam: https://github.com/LiamPM5
291
+ .. _Kadhiraven EG: https://github.com/JOKER-53
280
292
  .. _Seamus Tuohy: https://github.com/seamustuohy
281
293
  .. _Discord: https://discord.com/invite/B77McRmzdc
282
294
  .. _Buy Me a Coffee: https://www.buymeacoffee.com/DestructionE
@@ -11,7 +11,7 @@ https://github.com/TeamMsgExtractor/msg-extractor
11
11
 
12
12
  # --- LICENSE.txt --------------------------------------------------------------
13
13
  #
14
- # Copyright 2013-2023 Matthew Walker and Destiny Peterson
14
+ # Copyright 2013-2026 Matthew Walker and Destiny Peterson
15
15
  #
16
16
  # This program is free software: you can redistribute it and/or modify
17
17
  # it under the terms of the GNU General Public License as published by
@@ -27,8 +27,8 @@ https://github.com/TeamMsgExtractor/msg-extractor
27
27
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
28
28
 
29
29
  __author__ = 'Destiny Peterson & Matthew Walker'
30
- __date__ = '2026-07-18'
31
- __version__ = '0.56.0'
30
+ __date__ = '2026-10-24'
31
+ __version__ = '0.57.0'
32
32
 
33
33
  __all__ = [
34
34
  # Modules:
@@ -63,6 +63,7 @@ def main(argv: List[str] = sys.argv) -> None:
63
63
  'useMsgFilename': args.useFilename,
64
64
  'wkOptions': args.wkOptions,
65
65
  'wkPath': args.wkPath,
66
+ 'wkAllowExternalFiles': args.allowExternalFiles,
66
67
  'zip': _zip,
67
68
  }
68
69
 
@@ -101,7 +102,7 @@ def main(argv: List[str] = sys.argv) -> None:
101
102
  msg.saveAttachments(**kwargs)
102
103
  else:
103
104
  msg.save(**kwargs)
104
- except Exception as e:
105
+ except Exception:
105
106
  try:
106
107
  print(f'Error with file "{x}": {traceback.format_exc()}')
107
108
  except UnicodeEncodeError:
@@ -111,5 +112,6 @@ def main(argv: List[str] = sys.argv) -> None:
111
112
  if createdZip:
112
113
  _zip.close()
113
114
 
115
+
114
116
  if __name__ == '__main__':
115
117
  main(sys.argv)
@@ -7,7 +7,7 @@ __all__ = [
7
7
 
8
8
 
9
9
  from functools import cached_property
10
- from typing import List, Optional, TYPE_CHECKING
10
+ from typing import Optional, TYPE_CHECKING
11
11
 
12
12
  from . import registerHandler
13
13
  from .custom_handler import CustomAttachmentHandler
@@ -106,4 +106,4 @@ class LinkedObjectAttachment(CustomAttachmentHandler):
106
106
 
107
107
 
108
108
 
109
- registerHandler(LinkedObjectAttachment)
109
+ registerHandler(LinkedObjectAttachment)
@@ -71,4 +71,4 @@ class WebAttachment(AttachmentBase):
71
71
  The url for the web attachment. If this is not set, that is probably an
72
72
  error.
73
73
  """
74
- return self.longPathname
74
+ return self.longPathname
@@ -66,7 +66,7 @@ HEADER_FORMAT_VALUE_TYPE = Union[str, Tuple[Union[str, None], bool], None]
66
66
  # Basically a dict of HEADER_FORMAT_TYPE and dicts containing them.
67
67
  HEADER_FORMAT_TYPE = Optional[Dict[str, Union[HEADER_FORMAT_VALUE_TYPE, Dict[str, HEADER_FORMAT_VALUE_TYPE]]]]
68
68
  SAVE_TYPE = Tuple[SaveType, Union[List[str], str, None]]
69
- MSG_PATH = Union[str, List[str], Tuple[str]]
69
+ MSG_PATH = Union[str, List[str], Tuple[str, ...]]
70
70
  # Type used for the getXAs methods' overrideClass argument.
71
71
  OVERRIDE_CLASS = Union[Type[_T], Callable[[Any], _T]]
72
72
 
@@ -43,4 +43,4 @@ PSETID_AIRSYNC: Final[str] = '{71035549-0739-4DCB-9163-00F0580DBBDF}'
43
43
  PSETID_SHARING: Final[str] = '{00062040-0000-0000-C000-000000000046}'
44
44
  PSETID_XMLEXTRACTEDENTITIES: Final[str] = '{23239608-685D-4732-9C55-4C95CB4E8E33}'
45
45
  PSETID_ATTACHMENT: Final[str] = '{96357F7F-59E1-47D0-99A7-46515C183B54}'
46
- PSETID_CALENDAR_ASSISTANT: Final[str] = '{11000E07-B51B-40D6-AF21-CAA85EDAB1D0}'
46
+ PSETID_CALENDAR_ASSISTANT: Final[str] = '{11000E07-B51B-40D6-AF21-CAA85EDAB1D0}'
@@ -4,6 +4,7 @@ Regular expression constants.
4
4
 
5
5
 
6
6
  __all__ = [
7
+ 'CSS_URL',
7
8
  'HTML_BODY_START',
8
9
  'HTML_SAN_SPACE',
9
10
  'INVALID_FILENAME_CHARS',
@@ -52,3 +53,6 @@ RTF_BODY_STRIP_INIT: Final[_RE_BYTES_TYPE] = re.compile(rb'(\\htmlrtf[^0{}][^{}]
52
53
  # Preprocessing steps to simplify the RTF.
53
54
  RTF_BODY_STRIP_PRE_CLOSE: Final[_RE_BYTES_TYPE] = re.compile(rb'(\\htmlrtf1? ?}\\htmlrtf0 ?)|(\\htmlrtf1? ?[^0{}][^{}]*?} ?\\htmlrtf0 ?)')
54
55
  RTF_BODY_STRIP_PRE_OPEN: Final[_RE_BYTES_TYPE] = re.compile(rb'\\htmlrtf1? ?{[^{}]*?\\htmlrtf0 ?')
56
+
57
+ # Used for stripping urls from CSS.
58
+ CSS_URL: Final[_RE_STR_TYPE] = re.compile(r'url\(\s*["\']?(https?:\/\/[^"\')\s]+)["\']?\s*\)', re.I)
@@ -93,7 +93,7 @@ ST_BE_UI8: Final[struct.Struct] = struct.Struct('>B')
93
93
  ST_BE_UI16: Final[struct.Struct] = struct.Struct('>H')
94
94
  ST_BE_UI32: Final[struct.Struct] = struct.Struct('>I')
95
95
  ST_BE_UI64: Final[struct.Struct] = struct.Struct('>Q')
96
- ST_BE_F32: Final[struct.Struct] = struct.Struct('>f')
96
+ ST_BE_F32: Final[struct.Struct] = struct.Struct('>f')
97
97
  ST_BE_F64: Final[struct.Struct] = struct.Struct('>d')
98
98
  # Structs that use the system byte order, where consistency on a single system
99
99
  # is all that matters. Mainly used for quick casts between signed and unsigned.
@@ -107,4 +107,4 @@ ST_SBO_UI32: Final[struct.Struct] = struct.Struct('@I')
107
107
  ST_SBO_UI64: Final[struct.Struct] = struct.Struct('@Q')
108
108
  # Struct for an RGB value that, in little endian, would be an int written in hex
109
109
  # as 0x00BBGGRR.
110
- ST_RGB: Final[struct.Struct] = struct.Struct('<BBBx')
110
+ ST_RGB: Final[struct.Struct] = struct.Struct('<BBBx')