Skip to content

Commit

Permalink
Hotfix for Overflow Error (#35)
Browse files Browse the repository at this point in the history
* adding new egg name to git ignore

* running compatibility test as a part of travis

* added test for overflow error in #34, fixed using decimals instead of ints and floats

* test compatibility script python 3 support

* using travis_wait for the compatibility tests

* added 60 minute travis_wait to compatibility tests
  • Loading branch information
dwolfhub authored May 10, 2018
1 parent e3b129f commit 84a8ace
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 48 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ venv*
*.pyc
dist
build
zxcvbn_python.egg-info
zxcvbn*.egg-info
.vscode
5 changes: 4 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ python:
- "3.5"
- "3.6"
install: "pip install -r requirements.txt"
script: pytest
script:
- pytest
- pip install -e .
- travis_wait 60 python tests/test_compatibility.py tests/password_expected_value.json
notifications:
email:
on_success: never
91 changes: 50 additions & 41 deletions tests/test_compatibility.py
Original file line number Diff line number Diff line change
@@ -1,71 +1,80 @@
import json
from zxcvbn import zxcvbn
import sys, getopt
from decimal import Decimal

MAX_NUMBER_FOR_ACCURACY = 1000000000000
MIN_NUMBER_FOR_ACCURACY = 1

def update_console_status(total):
""" iterate from 0 to total and show progress in console """
str_progress = "%d%% ["%total + "".join(['#' for s in xrange(total)]) + "".join([' ' for s in xrange(100-total)]) + "] \r"
total = int(total)
try:
range_total = xrange(total)
range_100_min_total = xrange(100-total)
except NameError:
range_total = range(total)
range_100_min_total = range(100-total)

str_progress = "%d%% ["%total + "".join(['#' for s in range_total]) + "".join([' ' for s in range_100_min_total]) + "] \r"
sys.stdout.write(str_progress)
sys.stdout.flush()

def main(argv):

verbose = False
tests_file = ""
try:
tests_file = argv[0]
opts, args = getopt.getopt(argv[1:],"v")
except getopt.GetoptError:
print (""""test_compatibility <path/to/tests.json> [options]
options:
-v: verbose""")
for opt, arg in opts:
if opt == '-v':
verbose = True
verbose = False
tests_file = ""

try:
tests_file = argv[0]
opts, args = getopt.getopt(argv[1:],"v")
except getopt.GetoptError:
print (""""test_compatibility <path/to/tests.json> [options]
options:
-v: verbose""")
for opt, arg in opts:
if opt == '-v':
verbose = True

with open(tests_file) as json_data:
d = json.load(json_data)
with open(tests_file) as json_data:
d = json.load(json_data)

number_of_passwords = len(d)
scores_collision = 0
guesses_collision = 0
refresh_rate = number_of_passwords/100
number_of_passwords = len(d)
scores_collision = 0
guesses_collision = 0
refresh_rate = number_of_passwords/100

i = 0
for js_zxcvbn_score in d:
if i%refresh_rate== 0:
update_console_status(i*100/number_of_passwords)
i += 1
i = 0
for js_zxcvbn_score in d:
if i%refresh_rate== 0:
update_console_status(i*100/number_of_passwords)
i += 1

py_zxcvbn_scroe = dict()
py_zxcvbn_scroe_full = zxcvbn(js_zxcvbn_score['password'])
py_zxcvbn_scroe["password"] = py_zxcvbn_scroe_full["password"]
py_zxcvbn_scroe["guesses"] = py_zxcvbn_scroe_full["guesses"]
py_zxcvbn_scroe["score"] = py_zxcvbn_scroe_full["score"]
py_zxcvbn_scroe = dict()
py_zxcvbn_scroe_full = zxcvbn(js_zxcvbn_score['password'])
py_zxcvbn_scroe["password"] = py_zxcvbn_scroe_full["password"]
py_zxcvbn_scroe["guesses"] = py_zxcvbn_scroe_full["guesses"]
py_zxcvbn_scroe["score"] = py_zxcvbn_scroe_full["score"]

if (abs(py_zxcvbn_scroe["guesses"] - js_zxcvbn_score["guesses"]) > MIN_NUMBER_FOR_ACCURACY and
py_zxcvbn_scroe["guesses"] < MAX_NUMBER_FOR_ACCURACY):
guesses_collision += 1
if verbose:
print ("""\033[91m==========================================
if (abs(py_zxcvbn_scroe["guesses"] - Decimal(js_zxcvbn_score["guesses"])) > MIN_NUMBER_FOR_ACCURACY and
py_zxcvbn_scroe["guesses"] < MAX_NUMBER_FOR_ACCURACY):
guesses_collision += 1
if verbose:
print ("""\033[91m==========================================
expected:
%s
results:
%s\033[00m""")%(js_zxcvbn_score, py_zxcvbn_scroe)

if py_zxcvbn_scroe["score"] != js_zxcvbn_score["score"]:
scores_collision += 1
if py_zxcvbn_scroe["score"] != js_zxcvbn_score["score"]:
scores_collision += 1

if (guesses_collision or scores_collision):
print ("""\033[91mFailed!
if (guesses_collision or scores_collision):
print ("""\033[91mFailed!
guesses_collision:%d
guesses_score:%d""")%(guesses_collision, scores_collision)
else:
print ("\033[92mPassed!")
else:
print ("\033[92mPassed!")

if __name__ == "__main__":
main(sys.argv[1:])
7 changes: 7 additions & 0 deletions tests/zxcvbn_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,10 @@ def test_invalid_user_inputs():
password = u'pÄssword junkiË'

zxcvbn(password, user_inputs=[input_])


def test_long_password():
input_ = None
password = "weopiopdsjmkldjvoisdjfioejiojweopiopdsjmkldjvoisdjfioejiojweopiopdsjmkldjvoisdjfioejiojweopiopdsjmkldjvoisdjfioejiojweopiopdsjmkldjvoisdjfioejiojweopiopdsjmkldjvoisdjfioejiojweopiopdsjmkldjvoisdjfioejiojweopiopdsjmkldjvoisdjfioejiojweopiopdsjmkldjvoisdjfioejiojweopiopdsjmkldjvoisdjfioejiojweopiopdsjmkldjvoisdjfioej"

zxcvbn(password, user_inputs=[input_])
12 changes: 7 additions & 5 deletions zxcvbn/scoring.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

from .adjacency_graphs import ADJACENCY_GRAPHS

from decimal import Decimal


def calc_average_degree(graph):
average = 0
Expand Down Expand Up @@ -114,7 +116,7 @@ def update(m, l):
# obtain the product term in the minimization function by
# multiplying m's guesses by the product of the length-(l-1)
# sequence ending just before m, at m.i - 1.
pi *= optimal['pi'][m['i'] - 1][l - 1]
pi = pi * Decimal(optimal['pi'][m['i'] - 1][l - 1])
# calculate the minimization func
g = factorial(l) * pi
if not _exclude_additive:
Expand Down Expand Up @@ -219,7 +221,7 @@ def unwind(n):

def estimate_guesses(match, password):
if match.get('guesses', False):
return match['guesses']
return Decimal(match['guesses'])

min_guesses = 1
if len(match['token']) < len(password):
Expand All @@ -242,7 +244,7 @@ def estimate_guesses(match, password):
match['guesses'] = max(guesses, min_guesses)
match['guesses_log10'] = log(match['guesses'], 10)

return match['guesses']
return Decimal(match['guesses'])


def bruteforce_guesses(match):
Expand All @@ -266,11 +268,11 @@ def dictionary_guesses(match):
reversed_variations = match.get('reversed', False) and 2 or 1

return match['base_guesses'] * match['uppercase_variations'] * \
match['l33t_variations'] * reversed_variations
match['l33t_variations'] * reversed_variations


def repeat_guesses(match):
return match['base_guesses'] * match['repeat_count']
return match['base_guesses'] * Decimal(match['repeat_count'])


def sequence_guesses(match):
Expand Down

0 comments on commit 84a8ace

Please sign in to comment.