def run_print(): """This is called from test_read* tests as script. Prints & logs unicode""" from oletools.common.io_encoding import ensure_stdout_handles_unicode from oletools.common.log_helper import log_helper ensure_stdout_handles_unicode() print(u'Check: \u2713') # print check mark # check logging as well logger = log_helper.get_or_create_silent_logger('test_encoding_handler') log_helper.enable_logging(False, 'debug', stream=sys.stdout) logger.info(u'Check: \u2713') return 0
def preread_file(args): """helper for TestOleObj.test_non_streamed: preread + call process_file""" ensure_stdout_handles_unicode() # usually, main() call this ignore_arg, output_dir, filename = args if ignore_arg != '-d': raise ValueError('ignore_arg not as expected!') with open(filename, 'rb') as file_handle: data = file_handle.read() err_stream, err_dumping, did_dump = \ oleobj.process_file(filename, data, output_dir=output_dir) if did_dump and not err_stream and not err_dumping: return oleobj.RETURN_DID_DUMP else: return oleobj.RETURN_NO_DUMP # just anything else
def process_ole(ole): # parse and display metadata: meta = ole.get_metadata() # console output with UTF8 encoding: ensure_stdout_handles_unicode() # TODO: move similar code to a function print('Properties from the SummaryInformation stream:') t = tablestream.TableStream([21, 30], header_row=['Property', 'Value']) for prop in meta.SUMMARY_ATTRIBS: value = getattr(meta, prop) if value is not None: # TODO: pretty printing for strings, dates, numbers # TODO: better unicode handling # print('- %s: %s' % (prop, value)) # if isinstance(value, unicode): # # encode to UTF8, avoiding errors # value = value.encode('utf-8', errors='replace') # else: # value = str(value) t.write_row([prop, value], colors=[None, 'yellow']) t.close() print('') print('Properties from the DocumentSummaryInformation stream:') t = tablestream.TableStream([21, 30], header_row=['Property', 'Value']) for prop in meta.DOCSUM_ATTRIBS: value = getattr(meta, prop) if value is not None: # TODO: pretty printing for strings, dates, numbers # TODO: better unicode handling # print('- %s: %s' % (prop, value)) # if isinstance(value, unicode): # # encode to UTF8, avoiding errors # value = value.encode('utf-8', errors='replace') # else: # value = str(value) t.write_row([prop, value], colors=[None, 'yellow']) t.close()
def main(cmd_line_args=None): """ main function, called when running this as script Per default (cmd_line_args=None) uses sys.argv. For testing, however, can provide other arguments. """ # print banner with version ensure_stdout_handles_unicode() print('oleobj %s - http://decalage.info/oletools' % __version__) print('THIS IS WORK IN PROGRESS - Check updates regularly!') print('Please report any issue at ' 'https://github.com/decalage2/oletools/issues') print('') usage = 'usage: %(prog)s [options] <filename> [filename2 ...]' parser = argparse.ArgumentParser(usage=usage) # parser.add_argument('-o', '--outfile', dest='outfile', # help='output file') # parser.add_argument('-c', '--csv', dest='csv', # help='export results to a CSV file') parser.add_argument("-r", action="store_true", dest="recursive", help='find files recursively in subdirectories.') parser.add_argument("-d", type=str, dest="output_dir", default=None, help='use specified directory to output files.') parser.add_argument("-z", "--zip", dest='zip_password', type=str, default=None, help='if the file is a zip archive, open first file ' 'from it, using the provided password (requires ' 'Python 2.6+)') parser.add_argument("-f", "--zipfname", dest='zip_fname', type=str, default='*', help='if the file is a zip archive, file(s) to be ' 'opened within the zip. Wildcards * and ? are ' 'supported. (default:*)') parser.add_argument('-l', '--loglevel', dest="loglevel", action="store", default=DEFAULT_LOG_LEVEL, help='logging level debug/info/warning/error/critical ' '(default=%(default)s)') parser.add_argument('input', nargs='*', type=existing_file, metavar='FILE', help='Office files to parse (same as -i)') # options for compatibility with ripOLE parser.add_argument('-i', '--more-input', type=str, metavar='FILE', help='Additional file to parse (same as positional ' 'arguments)') parser.add_argument('-v', '--verbose', action='store_true', help='verbose mode, set logging to DEBUG ' '(overwrites -l)') options = parser.parse_args(cmd_line_args) if options.more_input: options.input += [ options.more_input, ] if options.verbose: options.loglevel = 'debug' # Print help if no arguments are passed if not options.input: parser.print_help() return RETURN_ERR_ARGS # Setup logging to the console: # here we use stdout instead of stderr by default, so that the output # can be redirected properly. logging.basicConfig(level=LOG_LEVELS[options.loglevel], stream=sys.stdout, format='%(levelname)-8s %(message)s') # enable logging in the modules: log.setLevel(logging.NOTSET) if options.loglevel == 'debug-olefile': olefile.enable_logging() # remember if there was a problem and continue with other data any_err_stream = False any_err_dumping = False any_did_dump = False for container, filename, data in \ xglob.iter_files(options.input, recursive=options.recursive, zip_password=options.zip_password, zip_fname=options.zip_fname): # ignore directory names stored in zip files: if container and filename.endswith('/'): continue err_stream, err_dumping, did_dump = \ process_file(filename, data, options.output_dir) any_err_stream |= err_stream any_err_dumping |= err_dumping any_did_dump |= did_dump # assemble return value return_val = RETURN_NO_DUMP if any_did_dump: return_val += RETURN_DID_DUMP if any_err_stream: return_val += RETURN_ERR_STREAM if any_err_dumping: return_val += RETURN_ERR_DUMP return return_val
def process_output(meta, output): # console output with UTF8 encoding: ensure_stdout_handles_unicode() # TODO: move similar code to a function if output == 'table': print('Properties from the SummaryInformation stream:') t = tablestream.TableStream([21, 30], header_row=['Property', 'Value']) for prop in meta.SUMMARY_ATTRIBS: value = getattr(meta, prop) if value is not None: # TODO: pretty printing for strings, dates, numbers # TODO: better unicode handling # print('- %s: %s' % (prop, value)) # if isinstance(value, unicode): # # encode to UTF8, avoiding errors # value = value.encode('utf-8', errors='replace') # else: # value = str(value) t.write_row([prop, value], colors=[None, 'yellow']) t.close() print('') print('Properties from the DocumentSummaryInformation stream:') t = tablestream.TableStream([21, 30], header_row=['Property', 'Value']) for prop in meta.DOCSUM_ATTRIBS: value = getattr(meta, prop) if value is not None: # TODO: pretty printing for strings, dates, numbers # TODO: better unicode handling # print('- %s: %s' % (prop, value)) # if isinstance(value, unicode): # # encode to UTF8, avoiding errors # value = value.encode('utf-8', errors='replace') # else: # value = str(value) t.write_row([prop, value], colors=[None, 'yellow']) t.close() else: # initalize a dictionary with keys for each type of attribute # update props/values like the table would output_dict = {"SUMMARY_ATTRIBS": {}, "DOCSUM_ATTRIBS": {}} for prop in meta.SUMMARY_ATTRIBS: value = getattr(meta, prop) if value: value = clean_output(value) output_dict['SUMMARY_ATTRIBS'][prop] = value else: # pass for now, when logging is enabled log as warning # logger.warning("Unable to log {}: {}".format(prop, value)) pass for prop in meta.DOCSUM_ATTRIBS: value = getattr(meta, prop) if value: value = clean_output(value) output_dict['DOCSUM_ATTRIBS'][prop] = value else: # pass for now, when logging is enabled log as warning # logger.warning("Unable to log {}: {}".format(prop, value)) pass return output_dict