Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fix sonarcloud maintainability #160

Merged
merged 11 commits into from
Aug 29, 2023
2 changes: 1 addition & 1 deletion src/main/java/com/nulabinc/zxcvbn/Feedback.java
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ private String l10n(ResourceBundle messages, String messageId) {
}

static Feedback getFeedback(int score, List<Match> sequence) {
if (sequence.size() == 0) {
if (sequence.isEmpty()) {
return FeedbackFactory.getFeedbackWithoutWarnings(
DEFAULT_SUGGESTIONS_USE_FEW_WORDS, DEFAULT_SUGGESTIONS_NO_NEED_SYMBOLS);
}
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/com/nulabinc/zxcvbn/FeedbackFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ class FeedbackFactory {
private static final List<String> NAME_DICTIONARIES =
Arrays.asList("surnames", "male_names", "female_names");

private FeedbackFactory() {
throw new IllegalStateException("FeedbackFactory should not be instantiated");
}

static Feedback getFeedbackWithoutWarnings(String... suggestions) {
return new Feedback(null, suggestions);
}
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/com/nulabinc/zxcvbn/Pattern.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
package com.nulabinc.zxcvbn;

public enum Pattern {
@SuppressWarnings("squid:S115")
Bruteforce("bruteforce"),
@SuppressWarnings("squid:S115")
Dictionary("dictionary"),
@SuppressWarnings("squid:S115")
Spatial("spatial"),
@SuppressWarnings("squid:S115")
Repeat("repeat"),
@SuppressWarnings("squid:S115")
Sequence("sequence"),
@SuppressWarnings("squid:S115")
Regex("regex"),
@SuppressWarnings("squid:S115")
Date("date");

private final String value;
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/com/nulabinc/zxcvbn/StandardContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@

class StandardContext {

private StandardContext() {
throw new IllegalStateException("StandardContext should not be instantiated");
}

static Context build() throws IOException {
Map<String, Dictionary> dictionaryMap = new LinkedHashMap<>();
for (Dictionary dictionary : StandardDictionaries.loadAllDictionaries()) {
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/com/nulabinc/zxcvbn/StandardDictionaries.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

public class StandardDictionaries {

@SuppressWarnings("squid:S1075")
private static final String BASE_PATH = "/com/nulabinc/zxcvbn/matchers/dictionaries/";

public static final String US_TV_AND_FILM = "us_tv_and_film";
Expand Down Expand Up @@ -42,6 +43,10 @@ public class StandardDictionaries {
public static final DictionaryLoader FEMALE_NAMES_LOADER =
new DictionaryLoader(FEMALE_NAMES, new ClasspathResource(BASE_PATH + "female_names.txt"));

private StandardDictionaries() {
throw new IllegalStateException("StandardDictionaries should not be instantiated");
}

private static final DictionaryLoader[] ALL_LOADERS = {
US_TV_AND_FILM_LOADER,
ENGLISH_WIKIPEDIA_LOADER,
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/com/nulabinc/zxcvbn/StandardKeyboards.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

public class StandardKeyboards {

@SuppressWarnings("squid:S1075")
private static final String RESOURCES_PACKAGE_PATH = "/com/nulabinc/zxcvbn/matchers/keyboards/";

public static final String QWERTY = "qwerty";
Expand All @@ -23,6 +24,10 @@ public class StandardKeyboards {

public static final String MAC_KEYPAD = "mac_keypad";

private StandardKeyboards() {
throw new IllegalStateException("StandardKeyboards should not be instantiated");
}

public static final KeyboardLoader QWERTY_LOADER =
new SlantedKeyboardLoader(
QWERTY, new ClasspathResource(RESOURCES_PACKAGE_PATH + "qwerty.txt"));
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/com/nulabinc/zxcvbn/TimeEstimates.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ public class TimeEstimates {
private static final double YEAR = MONTH * 12;
private static final double CENTURY = YEAR * 100;

private TimeEstimates() {
throw new IllegalStateException("TimeEstimates should not be instantiated");
}

public static AttackTimes estimateAttackTimes(double guesses) {
AttackTimes.CrackTimeSeconds crackTimeSeconds =
new AttackTimes.CrackTimeSeconds(
Expand Down
34 changes: 21 additions & 13 deletions src/main/java/com/nulabinc/zxcvbn/WipeableString.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ public void wipe() {

/** Returns a new wipeable string with the specified content forced into lower case. */
public static WipeableString lowerCase(CharSequence source) {
assert source != null;
if (source == null) {
throw new IllegalArgumentException("source is null");
}

char[] chars = new char[source.length()];
for (int n = 0; n < source.length(); n++) {
chars[n] = Character.toLowerCase(source.charAt(n));
Expand All @@ -65,7 +68,9 @@ public static WipeableString lowerCase(CharSequence source) {
* reversed.
*/
public static WipeableString reversed(CharSequence source) {
assert source != null;
if (source == null) {
throw new IllegalArgumentException("source is null");
}
int length = source.length();
char[] chars = new char[length];
for (int n = 0; n < source.length(); n++) {
Expand Down Expand Up @@ -135,6 +140,7 @@ public static int parseInt(CharSequence s) throws NumberFormatException {
}

/** A version of Integer.parse(String) that accepts CharSequence as parameter. */
@SuppressWarnings("squid:S3776")
public static int parseInt(CharSequence s, int radix) throws NumberFormatException {
if (s == null) {
throw new NumberFormatException("null");
Expand Down Expand Up @@ -165,10 +171,10 @@ public static int parseInt(CharSequence s, int radix) throws NumberFormatExcepti
negative = true;
limit = Integer.MIN_VALUE;
} else if (firstChar != '+') {
throw new NumberFormatException("For input string: \"" + s + "\"");
throw numberFormatException(s);
}
if (len == 1) { // Cannot have lone "+" or "-"
throw new NumberFormatException("For input string: \"" + s + "\"");
throw numberFormatException(s);
}
i++;
}
Expand All @@ -177,23 +183,27 @@ public static int parseInt(CharSequence s, int radix) throws NumberFormatExcepti
// Accumulating negatively avoids surprises near MAX_VALUE
digit = Character.digit(s.charAt(i++), radix);
if (digit < 0) {
throw new NumberFormatException("For input string: \"" + s + "\"");
throw numberFormatException(s);
}
if (result < multmin) {
throw new NumberFormatException("For input string: \"" + s + "\"");
throw numberFormatException(s);
}
result *= radix;
if (result < limit + digit) {
throw new NumberFormatException("For input string: \"" + s + "\"");
throw numberFormatException(s);
}
result -= digit;
}
} else {
throw new NumberFormatException("For input string: \"" + s + "\"");
throw numberFormatException(s);
}
return negative ? result : -result;
}

private static NumberFormatException numberFormatException(CharSequence s) {
return new NumberFormatException("For input string: \"" + s + "\"");
}

@Override
public String toString() {
return new String(content);
Expand Down Expand Up @@ -260,11 +270,9 @@ public static void wipeIfPossible(CharSequence text) {
((StringBuffer) text).setCharAt(n, ' ');
}
((StringBuffer) text).setLength(0);
} else if (text instanceof CharBuffer) {
if (!((CharBuffer) text).isReadOnly()) {
for (int n = 0; n < text.length(); n++) {
((CharBuffer) text).put(n, ' ');
}
} else if (text instanceof CharBuffer && !((CharBuffer) text).isReadOnly()) {
for (int n = 0; n < text.length(); n++) {
((CharBuffer) text).put(n, ' ');
}
}
}
Expand Down
60 changes: 39 additions & 21 deletions src/main/java/com/nulabinc/zxcvbn/guesses/DictionaryGuess.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.nulabinc.zxcvbn.Context;
import com.nulabinc.zxcvbn.WipeableString;
import com.nulabinc.zxcvbn.matchers.Match;
import java.util.AbstractMap;
import java.util.Map;
import java.util.regex.Pattern;

Expand Down Expand Up @@ -59,29 +60,46 @@ public int l33tVariations(Match match) {
int totalVariations = 1;
WipeableString lowercaseToken = WipeableString.lowerCase(match.token);
for (Map.Entry<Character, Character> substitution : match.sub.entrySet()) {
Character substitutedChar = substitution.getKey();
Character originalChar = substitution.getValue();
int substitutedCount = 0;
int originalCount = 0;
for (char currentChar : lowercaseToken.charArray()) {
if (currentChar == substitutedChar) {
substitutedCount++;
}
if (currentChar == originalChar) {
originalCount++;
}
totalVariations *= calculateSubstitutionVariation(substitution, lowercaseToken);
}
return totalVariations;
}

private static int calculateSubstitutionVariation(
Map.Entry<Character, Character> substitution, WipeableString token) {
Character substitutedChar = substitution.getKey();
Character originalChar = substitution.getValue();
AbstractMap.SimpleImmutableEntry<Integer, Integer> counts =
countCharOccurrences(token, substitutedChar, originalChar);
int substitutedCount = counts.getKey();
int originalCount = counts.getValue();
if (substitutedCount == 0 || originalCount == 0) {
return 2;
}
return calculatePossibleCombinations(originalCount, substitutedCount);
}

private static AbstractMap.SimpleImmutableEntry<Integer, Integer> countCharOccurrences(
WipeableString str, char char1, char char2) {
int count1 = 0;
int count2 = 0;
for (char currentChar : str.charArray()) {
if (currentChar == char1) {
count1++;
}
if (substitutedCount == 0 || originalCount == 0) {
totalVariations *= 2;
} else {
int minCount = Math.min(originalCount, substitutedCount);
int possibleCombinations = 0;
for (int i = 1; i <= minCount; i++) {
possibleCombinations += calculateBinomialCoefficient(originalCount + substitutedCount, i);
}
totalVariations *= possibleCombinations;
if (currentChar == char2) {
count2++;
}
}
return totalVariations;
return new AbstractMap.SimpleImmutableEntry<>(count1, count2);
}

private static int calculatePossibleCombinations(int originalCount, int substitutedCount) {
int minCount = Math.min(originalCount, substitutedCount);
int possibleCombinations = 0;
for (int i = 1; i <= minCount; i++) {
possibleCombinations += calculateBinomialCoefficient(originalCount + substitutedCount, i);
}
return possibleCombinations;
}
}
4 changes: 2 additions & 2 deletions src/main/java/com/nulabinc/zxcvbn/guesses/EstimateGuess.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
import com.nulabinc.zxcvbn.Pattern;
import com.nulabinc.zxcvbn.Scoring;
import com.nulabinc.zxcvbn.matchers.Match;
import java.util.HashMap;
import java.util.EnumMap;
import java.util.Map;

public class EstimateGuess extends BaseGuess {

private final CharSequence password;
private final Map<Pattern, Guess> patternGuessMap = new HashMap<>();
private final Map<Pattern, Guess> patternGuessMap = new EnumMap<>(Pattern.class);

public EstimateGuess(Context context, CharSequence password) {
super(context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public InputStream getInputStream() throws IOException {
* available; Next, the ClassLoader that loaded the ResourceLoader class will be used as fallback.
* Finally, if even the system ClassLoader could not access resource as stream, return null.
*/
@SuppressWarnings("squid:S1181")
private InputStream getResourceAsStreamWithFallback(String path) {
// Try loading the resource from the same artifact as this class
InputStream in = getClass().getResourceAsStream(path);
Expand Down