# Buggy code
def ParseFileObject(self, parser_mediator, file_object, **unused_kwargs):
    """Parses a CSV text file-like object.

    Args:
      parser_mediator: a parser mediator object (instance of ParserMediator).
      file_object: a file-like object.

    Raises:
      UnableToParseFile: when the file cannot be parsed.
    """
    file_entry = parser_mediator.GetFileEntry()
    path_spec_printable = file_entry.path_spec.comparable.replace("\n", ";")

    text_file_object = text_file.TextFile(file_object)

    # If we specifically define a number of lines we should skip do that here.
    for _ in range(0, self.NUMBER_OF_HEADER_LINES):
        _ = text_file_object.readline()

    reader = csv.DictReader(
        text_file_object,
        fieldnames=self.COLUMNS,
        restkey=self.MAGIC_TEST_STRING,
        restval=self.MAGIC_TEST_STRING,
        delimiter=self.VALUE_SEPARATOR,
        quotechar=self.QUOTE_CHAR,
    )

    try:
        row = reader.next()
    except (csv.Error, StopIteration):
        raise errors.UnableToParseFile(
            "[{0:s}] Unable to parse CSV file: {1:s}.".format(
                self.NAME, path_spec_printable
            )
        )

    number_of_columns = len(self.COLUMNS)
    number_of_records = len(row)

    if number_of_records != number_of_columns:
        raise errors.UnableToParseFile(
            (
                "[{0:s}] Unable to parse CSV file: {1:s}. Wrong number of "
                "records (expected: {2:d}, got: {3:d})"
            ).format(
                self.NAME, path_spec_printable, number_of_columns, number_of_records
            )
        )

    for key, value in row.items():
        if key == self.MAGIC_TEST_STRING or value == self.MAGIC_TEST_STRING:
            raise errors.UnableToParseFile(
                ("[{0:s}] Unable to parse CSV file: {1:s}. Signature mismatch.").format(
                    self.NAME, path_spec_printable
                )
            )

    if not self.VerifyRow(parser_mediator, row):
        raise errors.UnableToParseFile(
            ("[{0:s}] Unable to parse CSV file: {1:s}. Verification failed.").format(
                self.NAME, path_spec_printable
            )
        )

    self.ParseRow(parser_mediator, text_file_object.tell(), row)

    for row in reader:
        self.ParseRow(parser_mediator, text_file_object.tell(), row)


# Traceback (AttributeError)
Processing started.
Traceback (most recent call last):
File "./tools/log2timeline.py", line 696, in <module>
if not Main():
File "./tools/log2timeline.py", line 682, in Main
tool.ProcessSources()
File "./tools/log2timeline.py", line 624, in ProcessSources
timezone=self._timezone)
File "/home/onager/code/plaso/frontend/extraction_frontend.py", line 456, in ProcessSources
self._PreprocessSetTimezone(pre_obj, timezone=timezone)
File "/home/onager/code/plaso/frontend/extraction_frontend.py", line 322, in _PreprocessSetTimezone
pre_obj.zone = timezone
AttributeError: 'NoneType' object has no attribute 'zone'

# Fixed code
def ParseFileObject(self, parser_mediator, file_object, **unused_kwargs):
    """Parses a CSV text file-like object.

    Args:
      parser_mediator: a parser mediator object (instance of ParserMediator).
      file_object: a file-like object.

    Raises:
      UnableToParseFile: when the file cannot be parsed.
    """
    file_entry = parser_mediator.GetFileEntry()
    path_spec_printable = file_entry.path_spec.comparable.replace("\n", ";")

    text_file_object = text_file.TextFile(file_object)

    # If we specifically define a number of lines we should skip, do that here.
    for _ in range(0, self.NUMBER_OF_HEADER_LINES):
        _ = text_file_object.readline()

    reader = csv.DictReader(
        text_file_object,
        fieldnames=self.COLUMNS,
        restkey=self.MAGIC_TEST_STRING,
        restval=self.MAGIC_TEST_STRING,
        delimiter=self.VALUE_SEPARATOR,
        quotechar=self.QUOTE_CHAR,
    )

    try:
        row = reader.next()
    except (csv.Error, StopIteration):
        raise errors.UnableToParseFile(
            "[{0:s}] Unable to parse CSV file: {1:s}.".format(
                self.NAME, path_spec_printable
            )
        )

    number_of_columns = len(self.COLUMNS)
    number_of_records = len(row)

    if number_of_records != number_of_columns:
        raise errors.UnableToParseFile(
            (
                "[{0:s}] Unable to parse CSV file: {1:s}. Wrong number of "
                "records (expected: {2:d}, got: {3:d})"
            ).format(
                self.NAME, path_spec_printable, number_of_columns, number_of_records
            )
        )

    for key, value in row.items():
        if key == self.MAGIC_TEST_STRING or value == self.MAGIC_TEST_STRING:
            raise errors.UnableToParseFile(
                ("[{0:s}] Unable to parse CSV file: {1:s}. Signature mismatch.").format(
                    self.NAME, path_spec_printable
                )
            )

    if not self.VerifyRow(parser_mediator, row):
        raise errors.UnableToParseFile(
            ("[{0:s}] Unable to parse CSV file: {1:s}. Verification failed.").format(
                self.NAME, path_spec_printable
            )
        )

    row = self._ConvertRowToUnicode(parser_mediator, row)
    self.ParseRow(parser_mediator, text_file_object.tell(), row)

    for row in reader:
        row = self._ConvertRowToUnicode(parser_mediator, row)
        self.ParseRow(parser_mediator, text_file_object.tell(), row)