--- a/WebBrowser/SafeBrowsing/SafeBrowsingCache.py Wed Jul 26 19:46:17 2017 +0200 +++ b/WebBrowser/SafeBrowsing/SafeBrowsingCache.py Sat Jul 29 19:41:16 2017 +0200 @@ -14,12 +14,11 @@ # https://github.com/afilipovich/gglsbl # -from __future__ import unicode_literals +from __future__ import unicode_literals, division import os -import hashlib -from PyQt5.QtCore import QObject +from PyQt5.QtCore import QObject, QByteArray, QCryptographicHash from PyQt5.QtSql import QSql, QSqlDatabase, QSqlQuery from .SafeBrowsingUtilities import toHex @@ -77,6 +76,45 @@ return '/'.join(self.asTuple()) +class HashPrefixList(object): + """ + Class implementing a container for threat list data. + """ + def __init__(self, prefixLength, rawHashes): + """ + Constructor + + @param prefixLength length of each hash prefix + @type int + @param rawHashes raw hash prefixes of given length concatenated and + sorted in lexicographical order + @type str + """ + self.__prefixLength = prefixLength + self.__rawHashes = rawHashes + + def __len__(self): + """ + Special method to calculate the number of entries. + + @return length + @rtype int + """ + return len(self.__rawHashes) // self.__prefixLength + + def __iter__(self): + """ + Special method to iterate over the raw hashes. + + @return iterator object + @rtype iterator + """ + n = self.__prefixLength + return (self.__rawHashes[index:index + n] + for index in range(0, len(self.__rawHashes), n) + ) + + class SafeBrowsingCache(QObject): """ Class implementing a cache for Google Safe Browsing. @@ -247,7 +285,8 @@ query.prepare( queryStr.format(",".join(["?" * len(hashValues)]))) for hashValue in hashValues: - query.addBindValue(hashValue, QSql.In | QSql.Binary) + query.addBindValue(QByteArray(hashValue), + QSql.In | QSql.Binary) query.exec_() @@ -299,7 +338,7 @@ threatType = query.value(1) platformType = query.value(2) threatEntryType = query.value(3) - negativeCacheExpired = query.value(4) + negativeCacheExpired = query.value(4) # TODO: check if bool threatList = ThreatList(threatType, platformType, threatEntryType) output.append((threatList, fullHash, negativeCacheExpired)) @@ -343,7 +382,8 @@ try: query = QSqlQuery(db) query.prepare(insertQueryStr) - query.addBindValue(hashValue, QSql.In | QSql.Binary) + query.addBindValue(QByteArray(hashValue), + QSql.In | QSql.Binary) query.addBindValue(threatList.threatType) query.addBindValue(threatList.platformType) query.addBindValue(threatList.threatEntryType) @@ -353,7 +393,8 @@ query = QSqlQuery(db) query.prepare(updateQueryStr) - query.addBindValue(hashValue, QSql.In | QSql.Binary) + query.addBindValue(QByteArray(hashValue), + QSql.In | QSql.Binary) query.addBindValue(threatList.threatType) query.addBindValue(threatList.platformType) query.addBindValue(threatList.threatEntryType) @@ -438,7 +479,8 @@ try: query = QSqlQuery(db) query.prepare(queryStr) - query.addBindValue(hashPrefix, QSql.In | QSql.Binary) + query.addBindValue(QByteArray(hashPrefix), + QSql.In | QSql.Binary) query.addBindValue(threatList.threatType) query.addBindValue(threatList.platformType) query.addBindValue(threatList.threatEntryType) @@ -514,7 +556,7 @@ """ Public method to delete a threat list from the cache. - @param threatlist threat list to be deleted + @param threatList threat list to be deleted @type ThreatList """ queryStr = """ @@ -585,7 +627,7 @@ db = QSqlDatabase.database(self.__connectionName) if db.isOpen(): db.transaction() - allHashes = b"" + hash = QCryptographicHash(QCryptographicHash.Sha256) try: query = QSqlQuery(db) query.prepare(queryStr) @@ -596,12 +638,12 @@ query.exec_() while query.next(): - allHashes += bytes(query.value(0)) + hash.addData(query.value(0)) del query finally: db.commit() - checksum = hashlib.sha256(allHashes).digest() + checksum = bytes(hash.result()) return checksum @@ -611,8 +653,8 @@ @param threatList threat list of the hash prefixes @type ThreatList - @param prefixes hash prefixes to be inserted - @type bytes + @param prefixes list of hash prefixes to be inserted + @type HashPrefixList """ queryStr = """ INSERT INTO hash_prefix @@ -628,7 +670,8 @@ for prefix in prefixes: query = QSqlQuery(db) query.prepare(queryStr) - query.addBindValue(prefix, QSql.In | QSql.Binary) + query.addBindValue(QByteArray(prefix), + QSql.In | QSql.Binary) query.addBindValue(toHex(prefix[:4])) query.addBindValue(threatList.threatType) query.addBindValue(threatList.platformType) @@ -717,7 +760,8 @@ query.addBindValue(threatList.platformType) query.addBindValue(threatList.threatEntryType) for prefix in removeBatch: - query.addBindValue(prefix, QSql.In | QSql.Binary) + query.addBindValue(QByteArray(prefix), + QSql.In | QSql.Binary) query.exec_() del query finally: