Commit c49a5078902b973ccca6e23802735ed0b2a10a56
1 parent
281a2e3c
Add json output to msodde.py
Output is only json-compatible if program succeeded (return code 0). Otherwise there may be error messages (i.e. from argument parsing).
Showing
1 changed file
with
49 additions
and
10 deletions
oletools/msodde.py
| @@ -46,6 +46,7 @@ from __future__ import print_function | @@ -46,6 +46,7 @@ from __future__ import print_function | ||
| 46 | # CHANGELOG: | 46 | # CHANGELOG: |
| 47 | # 2017-10-18 v0.52 PL: - first version | 47 | # 2017-10-18 v0.52 PL: - first version |
| 48 | # 2017-10-20 PL: - fixed issue #202 (handling empty xml tags) | 48 | # 2017-10-20 PL: - fixed issue #202 (handling empty xml tags) |
| 49 | +# 2017-10-25 CH: - add json output | ||
| 49 | 50 | ||
| 50 | __version__ = '0.52dev2' | 51 | __version__ = '0.52dev2' |
| 51 | 52 | ||
| @@ -71,6 +72,7 @@ import argparse | @@ -71,6 +72,7 @@ import argparse | ||
| 71 | import zipfile | 72 | import zipfile |
| 72 | import os | 73 | import os |
| 73 | import sys | 74 | import sys |
| 75 | +import json | ||
| 74 | 76 | ||
| 75 | 77 | ||
| 76 | # === CONSTANTS ============================================================== | 78 | # === CONSTANTS ============================================================== |
| @@ -83,11 +85,26 @@ TAG_W_INSTRTEXT = '{%s}instrText' % NS_WORD | @@ -83,11 +85,26 @@ TAG_W_INSTRTEXT = '{%s}instrText' % NS_WORD | ||
| 83 | TAG_W_FLDSIMPLE = '{%s}fldSimple' % NS_WORD | 85 | TAG_W_FLDSIMPLE = '{%s}fldSimple' % NS_WORD |
| 84 | TAG_W_INSTRATTR= '{%s}instr' % NS_WORD | 86 | TAG_W_INSTRATTR= '{%s}instr' % NS_WORD |
| 85 | 87 | ||
| 88 | +# banner to be printed at program start | ||
| 89 | +BANNER = """ | ||
| 90 | +msodde %s - http://decalage.info/python/oletools | ||
| 91 | +THIS IS WORK IN PROGRESS - Check updates regularly! | ||
| 92 | +Please report any issue at https://github.com/decalage2/oletools/issues | ||
| 93 | +""" % __version__ | ||
| 94 | + | ||
| 95 | +BANNER_JSON = dict(type='meta', version=__version__, name='msodde', | ||
| 96 | + link='http://decalage.info/python/oletools', | ||
| 97 | + message='THIS IS WORK IN PROGRESS - Check updates regularly! ' | ||
| 98 | + 'Please report any issue at ' | ||
| 99 | + 'https://github.com/decalage2/oletools/issues') | ||
| 100 | + | ||
| 86 | # === FUNCTIONS ============================================================== | 101 | # === FUNCTIONS ============================================================== |
| 87 | 102 | ||
| 88 | def process_args(): | 103 | def process_args(): |
| 89 | parser = argparse.ArgumentParser(description='A python tool to detect and extract DDE links in MS Office files') | 104 | parser = argparse.ArgumentParser(description='A python tool to detect and extract DDE links in MS Office files') |
| 90 | parser.add_argument("filepath", help="path of the file to be analyzed") | 105 | parser.add_argument("filepath", help="path of the file to be analyzed") |
| 106 | + parser.add_argument("--json", '-j', action='store_true', | ||
| 107 | + help="Output in json format") | ||
| 91 | 108 | ||
| 92 | args = parser.parse_args() | 109 | args = parser.parse_args() |
| 93 | 110 | ||
| @@ -125,17 +142,39 @@ def process_file(filepath): | @@ -125,17 +142,39 @@ def process_file(filepath): | ||
| 125 | #=== MAIN ================================================================= | 142 | #=== MAIN ================================================================= |
| 126 | 143 | ||
| 127 | def main(): | 144 | def main(): |
| 128 | - # print banner with version | ||
| 129 | - print ('msodde %s - http://decalage.info/python/oletools' % __version__) | ||
| 130 | - print ('THIS IS WORK IN PROGRESS - Check updates regularly!') | ||
| 131 | - print ('Please report any issue at https://github.com/decalage2/oletools/issues') | ||
| 132 | - print ('') | ||
| 133 | - | ||
| 134 | args = process_args() | 145 | args = process_args() |
| 135 | - print('Opening file: %s' % args.filepath) | ||
| 136 | - text = process_file(args.filepath) | ||
| 137 | - print ('DDE Links:') | ||
| 138 | - print(text) | 146 | + |
| 147 | + if args.json: | ||
| 148 | + jout = [] | ||
| 149 | + jout.append(BANNER_JSON) | ||
| 150 | + else: | ||
| 151 | + # print banner with version | ||
| 152 | + print(BANNER) | ||
| 153 | + | ||
| 154 | + if not args.json: | ||
| 155 | + print('Opening file: %s' % args.filepath) | ||
| 156 | + | ||
| 157 | + text = '' | ||
| 158 | + return_code = 1 | ||
| 159 | + try: | ||
| 160 | + text = process_file(args.filepath) | ||
| 161 | + return_code = 0 | ||
| 162 | + except Exception as exc: | ||
| 163 | + if args.json: | ||
| 164 | + jout.append(dict(type='error', error=type(exc).__name__, | ||
| 165 | + message=str(exc))) # strange: str(exc) is enclosed in "" | ||
| 166 | + else: | ||
| 167 | + raise | ||
| 168 | + | ||
| 169 | + if args.json: | ||
| 170 | + for line in text.splitlines(): | ||
| 171 | + jout.append(dict(type='dde-link', link=line.strip())) | ||
| 172 | + json.dump(jout, sys.stdout, check_circular=False, indent=4) | ||
| 173 | + print() # add a newline after closing "]" | ||
| 174 | + sys.exit(return_code) # required if we catch an exception in json-mode | ||
| 175 | + else: | ||
| 176 | + print ('DDE Links:') | ||
| 177 | + print(text) | ||
| 139 | 178 | ||
| 140 | 179 | ||
| 141 | if __name__ == '__main__': | 180 | if __name__ == '__main__': |