-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Selftests removed from library and placed into test-internals.
Selftests extracted (removed) from zxcvbn.c and test.c and placed into test-internals.c Makefile updated.
- Loading branch information
Perlbotics
committed
Nov 21, 2017
1 parent
3417c5e
commit f7037ff
Showing
4 changed files
with
154 additions
and
146 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
|
||
/* Internal tests that cannot be run against the library without unnecessary export of symbols. | ||
Copyright (c) 2017, Perlbotics / see LICENSE.txt | ||
*/ | ||
|
||
|
||
#include "zxcvbn.h" | ||
/* need access to internals for testing; not linked against library, just inlined */ | ||
#include "zxcvbn.c" | ||
|
||
|
||
/********************************************************************************** | ||
* Internal checks: Validate if the first element of each group is sorted in | ||
* ascending order. CharBinSearch(...) fails otherwise. | ||
* Returns 0 on success. | ||
* Returns element index [1..] of first error entry that is less than previous one. | ||
*/ | ||
static int check_order(const uint8_t *Ents, unsigned int NumEnts, unsigned int SizeEnts) { | ||
const uint8_t *last; | ||
unsigned int i; | ||
|
||
if (!Ents) return 0; | ||
last = 0; | ||
|
||
for (i = 0; i < NumEnts; ++i, Ents += SizeEnts) { | ||
if (last && *last > *Ents) { | ||
unsigned int j; | ||
|
||
printf("Entry#%d [%d]: '%c' > '%c' (0x%02X > 0x%02X)\n A: ", i, i * SizeEnts, *last, *Ents, *last, *Ents); | ||
for (j = 0; j < SizeEnts; ++j) { | ||
printf("'%c' ", last[j] ? last[j] : ' '); | ||
} | ||
printf("\n >\n B: "); | ||
for (j = 0; j < SizeEnts; ++j) { | ||
printf("'%c' ", Ents[j] ? Ents[j] : ' '); | ||
} | ||
printf("\n"); | ||
|
||
return i; | ||
} | ||
last = Ents; | ||
} | ||
|
||
return 0; /* cannot be a misordered position; first possible one: 1 */ | ||
} | ||
|
||
/********************************************************************************** | ||
* Internal checks: Checks keyboard data integrity. | ||
* Returns 0 on succes. | ||
* Otherwise, number of errors are reported. | ||
*/ | ||
static unsigned int selftest_keyboards() { | ||
unsigned int errors; | ||
const Keyboard_t *k; | ||
unsigned int Indx; | ||
const uint8_t *keys; | ||
int i,j,errpos, blanks; | ||
|
||
errors = 0; | ||
for(k = Keyboards, Indx = 0; Indx < (sizeof Keyboards / sizeof Keyboards[0]); ++Indx, ++k) { | ||
/* if one of these assrtion fails, we cannot use binary search algorithm */ | ||
if (k->Shifts && strlen((const char*)k->Shifts) % 2 == 1) { | ||
printf("ERROR: Keyboard[%d]: Shifts-string has odd number of entries.\n", Indx); | ||
++errors; | ||
} | ||
|
||
if ( (errpos = check_order(k->Shifts, k->NumShift, 2)) ) { | ||
printf("ERROR: Keyboard[%d]: Error above in sort order of Shifts-string near item #%d.\n", Indx, errpos); | ||
++errors; | ||
} | ||
|
||
if ( (errpos = check_order(k->Keys, k->NumKeys, k->NumNear)) ) { | ||
printf("ERROR: Keyboard[%d]: Error above in sort order of keyboard-entries! Problem near item #%d.\n", Indx, errpos); | ||
++errors; | ||
continue; | ||
} | ||
|
||
/* For each key (c0), check all its neighbours (ci): | ||
* Does the neighbour key (c1==ci) have an entry (cx) in the opposite direction [rev_idx] | ||
* pointing back to the current key c0? | ||
* c0: ...ci.. --> c1: ..cx... --> cx==c0? | ||
*/ | ||
keys = k->Keys; | ||
blanks = 0; | ||
for(i = 0; i < k->NumKeys; ++i) { | ||
uint8_t c0; | ||
c0 = keys[i * k->NumNear]; | ||
|
||
for (j = 0; j < k->NumNear - 1; ++j) { | ||
const uint8_t *c1; | ||
uint8_t ci, cx; | ||
int rev_idx; | ||
|
||
/* rev_idx: reverse/opposite index to find opposite key location [0..6|8] --> [0..6|8] */ | ||
rev_idx = (j + (k->NumNear - 1)/2) % (k->NumNear - 1); | ||
ci = keys[i * k->NumNear + j + 1]; | ||
|
||
if (ci) { | ||
c1 = CharBinSearch(ci, keys, k->NumKeys, k->NumNear); | ||
if (c1) { | ||
if (ci == c0) { | ||
printf("ERROR: Keyboard[%d]: recursion - key '%c' cannot be its own neighbour!\n", Indx, *c1); | ||
++errors; | ||
} else { | ||
if ( (cx = c1[ 1 + rev_idx ]) ) { | ||
if ( cx != c0 ) { | ||
printf("ERROR: Keyboard[%d]: c0='%c':...(ci=%c)... -> c1='%c':...(cx=%c)... --!--> c0='%c':... \n", | ||
Indx, c0, ci, *c1, cx, c0); | ||
++errors; | ||
} | ||
} else { /* reverse pointer is NULL */ | ||
printf("ERROR: Keyboard[%d]: reverse entry missing in row c1='%c'[%d] pointing back to c0='%c'!\n", Indx, *c1, 1+rev_idx, c0); | ||
++errors; | ||
} | ||
} | ||
} else { | ||
printf("ERROR: Keyboard[%d]: no entry (neighbour list) found for src-char c1==ci='%c'\n", Indx, ci); | ||
++errors; | ||
} | ||
} else { /* blank neighbour key reference found */ | ||
++blanks; | ||
} | ||
} | ||
} | ||
if (blanks != k->NumBlank) { | ||
printf("ERROR: Keyboard[%d]: number of blank keys announced (%d) does not match number of blank keys counted (%d)!\n", | ||
Indx, k->NumBlank, blanks); | ||
++errors; | ||
} | ||
} | ||
return errors; | ||
} | ||
|
||
|
||
|
||
|
||
int main() { | ||
unsigned int errors; | ||
|
||
if( (errors = selftest_keyboards()) ){ /* currently only these */ | ||
printf("FAILED: [KEYBOARDS] - selftest returned %d error(s).\n", errors); | ||
} | ||
|
||
return errors ? 1 : 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters