Beispiel #1
0
    def Parse(self, filedesc):  # pylint: disable=g-bare-generic
        """Iterator returning dict for each entry in history."""
        with sqlite.IOConnection(filedesc) as conn:
            for timestamp, url, title in conn.Query(self.VISITS_QUERY):
                if not isinstance(timestamp, int):
                    timestamp = 0

                yield timestamp, "FIREFOX3_VISIT", url, title
Beispiel #2
0
    def Parse(self, filepath: Text, filedesc: IO[bytes]) -> Iterator[Tuple]:  # pylint: disable=g-bare-generic
        """Iterator returning a list for each entry in history.

    We store all the download events in an array (choosing this over visits
    since there are likely to be less of them). We later interleave them with
    visit events to get an overall correct time order.

    Args:
      filepath: A path corresponding to the database file.
      filedesc: A file-like object

    Yields:
      a list of attributes for each entry
    """
        with sqlite.IOConnection(filedesc) as conn:
            # The artifact may collect also not-database objects (e.g. journals). To
            # prevent them from making the flow to fail we first check whether the
            # file is really an SQLite database. If it is, then we make certain
            # assumptions about its schema (to provide the user with visible error
            # message that the parsing failed and maybe the format changed). If it is
            # not, then we emit a warning but carry on without an error.
            try:
                list(conn.Query("SELECT * FROM sqlite_master LIMIT 0"))
            except sqlite3.DatabaseError as error:
                logging.warning("'%s' is not an SQLite database: %s", filepath,
                                error)
                return

            # Query for old style and newstyle downloads storage.
            rows = []

            try:
                rows.extend(conn.Query(self.DOWNLOADS_QUERY))
            except sqlite3.Error as error:
                logging.warning("Chrome history database error: %s", error)

            try:
                rows.extend(conn.Query(self.DOWNLOADS_QUERY_2))
            except sqlite3.Error as error:
                logging.warning("Chrome history database error: %s", error)

            results = []
            for timestamp, url, path, received_bytes, total_bytes in rows:
                timestamp = self.ConvertTimestamp(timestamp)
                results.append((timestamp, "CHROME_DOWNLOAD", url, path,
                                received_bytes, total_bytes))

            for timestamp, url, title, typed_count in conn.Query(
                    self.VISITS_QUERY):
                timestamp = self.ConvertTimestamp(timestamp)
                results.append(
                    (timestamp, "CHROME_VISIT", url, title, typed_count, ""))

        results.sort(key=lambda it: it[0])
        for it in results:
            yield it
Beispiel #3
0
  def testSmallDatabase(self):
    with temp.AutoTempFilePath(suffix=".sqlite") as db_filepath:
      with contextlib.closing(sqlite3.connect(db_filepath)) as conn:
        with contextlib.closing(conn.cursor()) as cursor:
          cursor.execute("CREATE TABLE foo (bar INTEGER, baz INTEGER)")
          cursor.execute("INSERT INTO foo(bar, baz) VALUES (1, 3), (3, 7)")

        conn.commit()

      with io.open(db_filepath, mode="rb") as db_filedesc:
        db_bytes = db_filedesc.read()

      with sqlite.IOConnection(io.BytesIO(db_bytes)) as context:
        results = list(context.Query("SELECT bar, baz FROM foo"))
        self.assertEqual(results, [(1, 3), (3, 7)])
Beispiel #4
0
  def testBigDatabase(self):
    blob = lambda sample: sample * 1024 * 1024

    with temp.AutoTempFilePath(suffix=".sqlite") as db_filepath:
      with contextlib.closing(sqlite3.connect(db_filepath)) as conn:
        with contextlib.closing(conn.cursor()) as cursor:
          cursor.execute("CREATE TABLE foo (bar BLOB)")
          cursor.execute("INSERT INTO foo(bar) VALUES (?)", (blob(b"A"),))
          cursor.execute("INSERT INTO foo(bar) VALUES (?)", (blob(b"B"),))
          cursor.execute("INSERT INTO foo(bar) VALUES (?)", (blob(b"C"),))

        conn.commit()

      with io.open(db_filepath, mode="rb") as db_filedesc:
        with sqlite.IOConnection(db_filedesc) as context:
          results = list(context.Query("SELECT bar FROM foo"))
          self.assertLen(results, 3)
          self.assertEqual(results[0], (blob(b"A"),))
          self.assertEqual(results[1], (blob(b"B"),))
          self.assertEqual(results[2], (blob(b"C"),))
Beispiel #5
0
  def Parse(self, filedesc):  # pylint: disable=g-bare-generic
    """Iterator returning a list for each entry in history.

    We store all the download events in an array (choosing this over visits
    since there are likely to be less of them). We later interleave them with
    visit events to get an overall correct time order.

    Args:
      filedesc: A file-like object

    Yields:
      a list of attributes for each entry
    """
    with sqlite.IOConnection(filedesc) as conn:
      # Query for old style and newstyle downloads storage.
      rows = []

      try:
        rows.extend(conn.Query(self.DOWNLOADS_QUERY))
      except sqlite3.Error as error:
        logging.warning("Chrome history database error: %s", error)

      try:
        rows.extend(conn.Query(self.DOWNLOADS_QUERY_2))
      except sqlite3.Error as error:
        logging.warning("Chrome history database error: %s", error)

      results = []
      for timestamp, url, path, received_bytes, total_bytes in rows:
        timestamp = self.ConvertTimestamp(timestamp)
        results.append((timestamp, "CHROME_DOWNLOAD", url, path, received_bytes,
                        total_bytes))

      for timestamp, url, title, typed_count in conn.Query(self.VISITS_QUERY):
        timestamp = self.ConvertTimestamp(timestamp)
        results.append((timestamp, "CHROME_VISIT", url, title, typed_count, ""))

    results.sort(key=lambda it: it[0])
    for it in results:
      yield it