mirror of
https://github.com/ysoftdevs/DependencyCheck.git
synced 2026-03-14 14:11:35 +01:00
updated method names to better state what is happening
This commit is contained in:
@@ -277,7 +277,7 @@ public class Engine implements FileFilter, AutoCloseable {
|
||||
final AnalyzerService service = new AnalyzerService(serviceClassLoader, loadExperimental);
|
||||
final List<Analyzer> iterator = service.getAnalyzers(mode.getPhases());
|
||||
for (Analyzer a : iterator) {
|
||||
a.initializeSettings(this.settings);
|
||||
a.initialize(this.settings);
|
||||
analyzers.get(a.getAnalysisPhase()).add(a);
|
||||
if (a instanceof FileTypeAnalyzer) {
|
||||
this.fileTypeAnalyzers.add((FileTypeAnalyzer) a);
|
||||
@@ -804,14 +804,14 @@ public class Engine implements FileFilter, AutoCloseable {
|
||||
/**
|
||||
* Initializes the given analyzer.
|
||||
*
|
||||
* @param analyzer the analyzer to initialize
|
||||
* @param analyzer the analyzer to prepare
|
||||
* @throws InitializationException thrown when there is a problem
|
||||
* initializing the analyzer
|
||||
*/
|
||||
protected void initializeAnalyzer(Analyzer analyzer) throws InitializationException {
|
||||
try {
|
||||
LOGGER.debug("Initializing {}", analyzer.getName());
|
||||
analyzer.initialize(this);
|
||||
analyzer.prepare(this);
|
||||
} catch (InitializationException ex) {
|
||||
LOGGER.error("Exception occurred initializing {}.", analyzer.getName());
|
||||
LOGGER.debug("", ex);
|
||||
|
||||
@@ -28,7 +28,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Base class for analyzers to avoid code duplication of initialize and close as
|
||||
* Base class for analyzers to avoid code duplication of prepare and close as
|
||||
* most analyzers do not need these methods.
|
||||
*
|
||||
* @author Jeremy Long
|
||||
@@ -83,48 +83,43 @@ public abstract class AbstractAnalyzer implements Analyzer {
|
||||
* @param settings the configured settings to use
|
||||
*/
|
||||
@Override
|
||||
public void initializeSettings(Settings settings) {
|
||||
public void initialize(Settings settings) {
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Returns the setting key to determine if the analyzer is enabled.</p>
|
||||
* Initialize the abstract analyzer.
|
||||
*
|
||||
* @return the key for the analyzer's enabled property
|
||||
* @param engine a reference to the dependency-check engine
|
||||
* @throws InitializationException thrown if there is an exception
|
||||
*/
|
||||
protected abstract String getAnalyzerEnabledSettingKey();
|
||||
@Override
|
||||
public final void prepare(Engine engine) throws InitializationException {
|
||||
final String key = getAnalyzerEnabledSettingKey();
|
||||
try {
|
||||
this.setEnabled(settings.getBoolean(key, true));
|
||||
} catch (InvalidSettingException ex) {
|
||||
final String msg = String.format("Invalid setting for property '%s'", key);
|
||||
LOGGER.warn(msg);
|
||||
LOGGER.debug(msg, ex);
|
||||
}
|
||||
|
||||
if (isEnabled()) {
|
||||
prepareAnalyzer(engine);
|
||||
} else {
|
||||
LOGGER.debug("{} has been disabled", getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyzes a given dependency. If the dependency is an archive, such as a
|
||||
* WAR or EAR, the contents are extracted, scanned, and added to the list of
|
||||
* dependencies within the engine.
|
||||
*
|
||||
* @param dependency the dependency to analyze
|
||||
* @param engine the engine scanning
|
||||
* @throws AnalysisException thrown if there is an analysis exception
|
||||
*/
|
||||
protected abstract void analyzeDependency(Dependency dependency, Engine engine) throws AnalysisException;
|
||||
|
||||
/**
|
||||
* Initializes a given Analyzer. This will be skipped if the analyzer is
|
||||
* Prepares a given Analyzer. This will be skipped if the analyzer is
|
||||
* disabled.
|
||||
*
|
||||
* @param engine a reference to the dependency-check engine
|
||||
* @throws InitializationException thrown if there is an exception
|
||||
*/
|
||||
protected void initializeAnalyzer(Engine engine) throws InitializationException {
|
||||
// Intentionally empty, analyzer will override this if they must initialize anything.
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes a given Analyzer. This will be skipped if the analyzer is
|
||||
* disabled.
|
||||
*
|
||||
* @throws Exception thrown if there is an exception
|
||||
*/
|
||||
protected void closeAnalyzer() throws Exception {
|
||||
// Intentionally empty, analyzer will override this if they must close a resource.
|
||||
protected void prepareAnalyzer(Engine engine) throws InitializationException {
|
||||
// Intentionally empty, analyzer will override this if they must prepare anything.
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -144,28 +139,15 @@ public abstract class AbstractAnalyzer implements Analyzer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the abstract analyzer.
|
||||
* Analyzes a given dependency. If the dependency is an archive, such as a
|
||||
* WAR or EAR, the contents are extracted, scanned, and added to the list of
|
||||
* dependencies within the engine.
|
||||
*
|
||||
* @param engine a reference to the dependency-check engine
|
||||
* @throws InitializationException thrown if there is an exception
|
||||
* @param dependency the dependency to analyze
|
||||
* @param engine the engine scanning
|
||||
* @throws AnalysisException thrown if there is an analysis exception
|
||||
*/
|
||||
@Override
|
||||
public final void initialize(Engine engine) throws InitializationException {
|
||||
final String key = getAnalyzerEnabledSettingKey();
|
||||
try {
|
||||
this.setEnabled(settings.getBoolean(key, true));
|
||||
} catch (InvalidSettingException ex) {
|
||||
final String msg = String.format("Invalid setting for property '%s'", key);
|
||||
LOGGER.warn(msg);
|
||||
LOGGER.debug(msg, ex);
|
||||
}
|
||||
|
||||
if (isEnabled()) {
|
||||
initializeAnalyzer(engine);
|
||||
} else {
|
||||
LOGGER.debug("{} has been disabled", getName());
|
||||
}
|
||||
}
|
||||
protected abstract void analyzeDependency(Dependency dependency, Engine engine) throws AnalysisException;
|
||||
|
||||
/**
|
||||
* The close method does nothing for this Analyzer.
|
||||
@@ -179,6 +161,16 @@ public abstract class AbstractAnalyzer implements Analyzer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes a given Analyzer. This will be skipped if the analyzer is
|
||||
* disabled.
|
||||
*
|
||||
* @throws Exception thrown if there is an exception
|
||||
*/
|
||||
protected void closeAnalyzer() throws Exception {
|
||||
// Intentionally empty, analyzer will override this if they must close a resource.
|
||||
}
|
||||
|
||||
/**
|
||||
* The default is to support parallel processing.
|
||||
*
|
||||
@@ -186,8 +178,15 @@ public abstract class AbstractAnalyzer implements Analyzer {
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsParallelProcessing() {
|
||||
//temporarily removing parallel processing from all analyzders until further examination of thread safety occurs.
|
||||
return true;
|
||||
//return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Returns the setting key to determine if the analyzer is enabled.</p>
|
||||
*
|
||||
* @return the key for the analyzer's enabled property
|
||||
*/
|
||||
protected abstract String getAnalyzerEnabledSettingKey();
|
||||
|
||||
}
|
||||
|
||||
@@ -48,7 +48,6 @@ public abstract class AbstractFileTypeAnalyzer extends AbstractAnalyzer implemen
|
||||
*/
|
||||
private boolean filesMatched = false;
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of filesMatched. A flag indicating whether the scan
|
||||
* included any file types this analyzer supports.
|
||||
@@ -69,9 +68,9 @@ public abstract class AbstractFileTypeAnalyzer extends AbstractAnalyzer implemen
|
||||
* initialization
|
||||
*/
|
||||
@Override
|
||||
protected final void initializeAnalyzer(Engine engine) throws InitializationException {
|
||||
protected final void prepareAnalyzer(Engine engine) throws InitializationException {
|
||||
if (filesMatched) {
|
||||
initializeFileTypeAnalyzer(engine);
|
||||
prepareFileTypeAnalyzer(engine);
|
||||
} else {
|
||||
this.setEnabled(false);
|
||||
}
|
||||
@@ -94,13 +93,13 @@ public abstract class AbstractFileTypeAnalyzer extends AbstractAnalyzer implemen
|
||||
protected abstract FileFilter getFileFilter();
|
||||
|
||||
/**
|
||||
* Initializes the file type analyzer.
|
||||
* Prepares the file type analyzer for dependency analysis.
|
||||
*
|
||||
* @param engine a reference to the dependency-check engine
|
||||
* @throws InitializationException thrown if there is an exception during
|
||||
* initialization
|
||||
*/
|
||||
protected abstract void initializeFileTypeAnalyzer(Engine engine) throws InitializationException;
|
||||
protected abstract void prepareFileTypeAnalyzer(Engine engine) throws InitializationException;
|
||||
|
||||
//</editor-fold>
|
||||
/**
|
||||
@@ -131,7 +130,7 @@ public abstract class AbstractFileTypeAnalyzer extends AbstractAnalyzer implemen
|
||||
* constructs a new Set that can be used in a final static declaration.</p>
|
||||
* <p>
|
||||
* This implementation was copied from
|
||||
* http://stackoverflow.com/questions/2041778/initialize-java-hashset-values-by-construction</p>
|
||||
* http://stackoverflow.com/questions/2041778/prepare-java-hashset-values-by-construction</p>
|
||||
*
|
||||
* @param strings a list of strings to add to the set.
|
||||
* @return a Set of strings.
|
||||
|
||||
@@ -79,13 +79,13 @@ public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer {
|
||||
}
|
||||
|
||||
/**
|
||||
* The initialize method loads the suppression XML file.
|
||||
* The prepare method loads the suppression XML file.
|
||||
*
|
||||
* @param engine a reference the dependency-check engine
|
||||
* @throws InitializationException thrown if there is an exception
|
||||
*/
|
||||
@Override
|
||||
public synchronized void initializeAnalyzer(Engine engine) throws InitializationException {
|
||||
public synchronized void prepareAnalyzer(Engine engine) throws InitializationException {
|
||||
if (rules == null) {
|
||||
try {
|
||||
rules = loadSuppressionData();
|
||||
|
||||
@@ -32,8 +32,8 @@ import org.owasp.dependencycheck.utils.Settings;
|
||||
* When the {@link org.owasp.dependencycheck.Engine} executes it will load the
|
||||
* analyzers and call the methods in the following order:</p>
|
||||
* <ol>
|
||||
* <li>{@link #initializeSettings(org.owasp.dependencycheck.utils.Settings)}</li>
|
||||
* <li>{@link #initialize(org.owasp.dependencycheck.Engine)}</li>
|
||||
* <li>{@link #initialize(org.owasp.dependencycheck.utils.Settings)}</li>
|
||||
* <li>{@link #prepare(org.owasp.dependencycheck.Engine)}</li>
|
||||
* <li>{@link #analyze(org.owasp.dependencycheck.dependency.Dependency, org.owasp.dependencycheck.Engine)}</li>
|
||||
* <li>{@link #close()}</li>
|
||||
* </ol>
|
||||
@@ -75,17 +75,17 @@ public interface Analyzer {
|
||||
*
|
||||
* @param settings the configured settings
|
||||
*/
|
||||
void initializeSettings(Settings settings);
|
||||
void initialize(Settings settings);
|
||||
|
||||
/**
|
||||
* The initialize method is called (once) prior to the analyze method being
|
||||
* The prepare method is called (once) prior to the analyze method being
|
||||
* called on all of the dependencies.
|
||||
*
|
||||
* @param engine a reference to the dependency-check engine
|
||||
* @throws InitializationException is thrown if an exception occurs
|
||||
* initializing the analyzer.
|
||||
*/
|
||||
void initialize(Engine engine) throws InitializationException;
|
||||
void prepare(Engine engine) throws InitializationException;
|
||||
|
||||
/**
|
||||
* The close method is called after all of the dependencies have been
|
||||
|
||||
@@ -126,8 +126,8 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
* @param settings the configured settings to use
|
||||
*/
|
||||
@Override
|
||||
public void initializeSettings(Settings settings) {
|
||||
super.initializeSettings(settings);
|
||||
public void initialize(Settings settings) {
|
||||
super.initialize(settings);
|
||||
initializeSettings();
|
||||
}
|
||||
|
||||
@@ -169,14 +169,14 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
}
|
||||
|
||||
/**
|
||||
* The initialize method does nothing for this Analyzer.
|
||||
* The prepare method does nothing for this Analyzer.
|
||||
*
|
||||
* @param engine a reference to the dependency-check engine
|
||||
* @throws InitializationException is thrown if there is an exception
|
||||
* deleting or creating temporary files
|
||||
*/
|
||||
@Override
|
||||
public void initializeFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
public void prepareFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
try {
|
||||
final File baseDir = getSettings().getTempDirectory();
|
||||
tempFileLocation = File.createTempFile("check", "tmp", baseDir);
|
||||
|
||||
@@ -205,7 +205,7 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
* @throws InitializationException thrown if anything goes wrong
|
||||
*/
|
||||
@Override
|
||||
public void initializeFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
public void prepareFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
final File tempFile;
|
||||
final File cfgFile;
|
||||
try {
|
||||
|
||||
@@ -260,7 +260,7 @@ public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
* initialization
|
||||
*/
|
||||
@Override
|
||||
protected void initializeFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
protected void prepareFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
// No initialization needed.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ public class CMakeAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
* instance of SHA1
|
||||
*/
|
||||
@Override
|
||||
protected void initializeFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
protected void prepareFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
try {
|
||||
getSha1MessageDigest();
|
||||
} catch (IllegalStateException ex) {
|
||||
|
||||
@@ -135,7 +135,7 @@ public class CPEAnalyzer extends AbstractAnalyzer {
|
||||
* the index.
|
||||
*/
|
||||
@Override
|
||||
public void initializeAnalyzer(Engine engine) throws InitializationException {
|
||||
public void prepareAnalyzer(Engine engine) throws InitializationException {
|
||||
try {
|
||||
this.open(engine.getDatabase());
|
||||
} catch (IOException ex) {
|
||||
|
||||
@@ -95,8 +95,8 @@ public class CentralAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
* @param settings the configured settings to use
|
||||
*/
|
||||
@Override
|
||||
public void initializeSettings(Settings settings) {
|
||||
super.initializeSettings(settings);
|
||||
public void initialize(Settings settings) {
|
||||
super.initialize(settings);
|
||||
enabled = checkEnabled();
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ public class CentralAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
* @throws InitializationException if there's an error during initialization
|
||||
*/
|
||||
@Override
|
||||
public void initializeFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
public void prepareFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
LOGGER.debug("Initializing Central analyzer");
|
||||
LOGGER.debug("Central analyzer enabled: {}", isEnabled());
|
||||
if (isEnabled()) {
|
||||
|
||||
@@ -85,7 +85,7 @@ public class CocoaPodsAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initializeFileTypeAnalyzer(Engine engine) {
|
||||
protected void prepareFileTypeAnalyzer(Engine engine) {
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ public class ComposerLockAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
* instance of SHA1
|
||||
*/
|
||||
@Override
|
||||
protected void initializeFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
protected void prepareFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
try {
|
||||
getSha1MessageDigest();
|
||||
} catch (IllegalStateException ex) {
|
||||
|
||||
@@ -112,13 +112,13 @@ public class HintAnalyzer extends AbstractAnalyzer {
|
||||
}
|
||||
|
||||
/**
|
||||
* The initialize method does nothing for this Analyzer.
|
||||
* The prepare method does nothing for this Analyzer.
|
||||
*
|
||||
* @param engine a reference the dependency-check engine
|
||||
* @throws InitializationException thrown if there is an exception
|
||||
*/
|
||||
@Override
|
||||
public void initializeAnalyzer(Engine engine) throws InitializationException {
|
||||
public void prepareAnalyzer(Engine engine) throws InitializationException {
|
||||
try {
|
||||
loadHintRules();
|
||||
} catch (HintParseException ex) {
|
||||
|
||||
@@ -920,7 +920,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
* creating a temporary directory
|
||||
*/
|
||||
@Override
|
||||
public void initializeFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
public void prepareFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
try {
|
||||
final File baseDir = getSettings().getTempDirectory();
|
||||
tempFileLocation = File.createTempFile("check", "tmp", baseDir);
|
||||
|
||||
@@ -106,8 +106,8 @@ public class NexusAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
* @param settings the configured settings to use
|
||||
*/
|
||||
@Override
|
||||
public void initializeSettings(Settings settings) {
|
||||
super.initializeSettings(settings);
|
||||
public void initialize(Settings settings) {
|
||||
super.initialize(settings);
|
||||
enabled = checkEnabled();
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ public class NexusAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
* @throws InitializationException if there's an error during initialization
|
||||
*/
|
||||
@Override
|
||||
public void initializeFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
public void prepareFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
LOGGER.debug("Initializing Nexus Analyzer");
|
||||
LOGGER.debug("Nexus Analyzer enabled: {}", isEnabled());
|
||||
if (isEnabled()) {
|
||||
|
||||
@@ -87,7 +87,7 @@ public class NodePackageAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initializeFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
protected void prepareFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ public class NspAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
* @throws InitializationException if there's an error during initialization
|
||||
*/
|
||||
@Override
|
||||
public void initializeFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
public void prepareFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
LOGGER.debug("Initializing {}", getName());
|
||||
try {
|
||||
searcher = new NspSearch(getSettings());
|
||||
|
||||
@@ -76,7 +76,7 @@ public class NuspecAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
* @throws InitializationException if there's an error during initialization
|
||||
*/
|
||||
@Override
|
||||
public void initializeFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
public void prepareFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
//nothing to initialize
|
||||
}
|
||||
|
||||
|
||||
@@ -163,7 +163,7 @@ public class OpenSSLAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
* @throws InitializationException never thrown
|
||||
*/
|
||||
@Override
|
||||
protected void initializeFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
protected void prepareFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
|
||||
@@ -230,7 +230,7 @@ public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
* temp directory cannot be created
|
||||
*/
|
||||
@Override
|
||||
protected void initializeFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
protected void prepareFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
try {
|
||||
final File baseDir = getSettings().getTempDirectory();
|
||||
tempFileLocation = File.createTempFile("check", "tmp", baseDir);
|
||||
|
||||
@@ -156,7 +156,7 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
* @throws InitializationException never thrown
|
||||
*/
|
||||
@Override
|
||||
protected void initializeFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
protected void prepareFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
* @throws InitializationException if anything goes wrong
|
||||
*/
|
||||
@Override
|
||||
public void initializeFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
public void prepareFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
// Now, need to see if bundle-audit actually runs from this location.
|
||||
if (engine != null) {
|
||||
this.cvedb = engine.getDatabase();
|
||||
|
||||
@@ -91,7 +91,7 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initializeFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
protected void prepareFileTypeAnalyzer(Engine engine) throws InitializationException {
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ public class SwiftPackageManagerAnalyzer extends AbstractFileTypeAnalyzer {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initializeFileTypeAnalyzer(Engine engine) {
|
||||
protected void prepareFileTypeAnalyzer(Engine engine) {
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user