Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Tai-e: A Static Analysis Framework for Java
*
* Copyright (C) 2022 Tian Tan
* Copyright (C) 2022 Yue Li
*
* This file is part of Tai-e.
*
* Tai-e is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* Tai-e is distributed in the hope that it will be useful,but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
* Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Tai-e. If not, see .
*/
package pascal.taie.analysis.pta.plugin.taint;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import pascal.taie.analysis.pta.plugin.util.InvokeUtils;
import pascal.taie.config.ConfigException;
import pascal.taie.language.classes.ClassHierarchy;
import pascal.taie.language.classes.JClass;
import pascal.taie.language.classes.JField;
import pascal.taie.language.classes.JMethod;
import pascal.taie.language.classes.SignatureMatcher;
import pascal.taie.language.type.ArrayType;
import pascal.taie.language.type.ClassType;
import pascal.taie.language.type.Type;
import pascal.taie.language.type.TypeSystem;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;
import static pascal.taie.analysis.pta.plugin.taint.IndexRef.ARRAY_SUFFIX;
class YamlTaintConfigProvider extends TaintConfigProvider {
private static final Logger logger = LogManager.getLogger(YamlTaintConfigProvider.class);
private String path;
YamlTaintConfigProvider(ClassHierarchy hierarchy, TypeSystem typeSystem) {
super(hierarchy, typeSystem);
}
/**
* Sets path where the taint analysis configuration is loaded.
* If the path is a file, then loads config from the file;
* if the path is a directory, then loads all YAML files in the directory
* and merge them as the result.
*
* @param path the path
*/
void setPath(String path) {
this.path = path;
}
/**
* @throws pascal.taie.config.ConfigException if failed to load the config
*/
@Override
public TaintConfig get() {
ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
SimpleModule module = new SimpleModule();
module.addDeserializer(TaintConfig.class,
new YamlTaintConfigProvider.Deserializer(matcher, typeSystem));
mapper.registerModule(module);
File file = new File(path);
logger.info("Loading taint config from {}", file.getAbsolutePath());
if (file.isFile()) {
return loadSingle(mapper, file);
} else if (file.isDirectory()) {
// if file is a directory, then load all YAML files
// in the directory and merge them as the result
TaintConfig[] result = new TaintConfig[]{ TaintConfig.EMPTY };
try (Stream paths = Files.walk(file.toPath())) {
paths.filter(YamlTaintConfigProvider::isYAML)
.map(p -> loadSingle(mapper, p.toFile()))
.forEach(tc -> result[0] = result[0].mergeWith(tc));
return result[0];
} catch (IOException e) {
throw new ConfigException("Failed to load taint config from " + file, e);
}
} else {
throw new ConfigException(path + " is neither a file nor a directory");
}
}
/**
* Loads taint config from a single file.
*/
private static TaintConfig loadSingle(ObjectMapper mapper, File file) {
try {
return mapper.readValue(file, TaintConfig.class);
} catch (IOException e) {
throw new ConfigException("Failed to load taint config from " + file, e);
}
}
private static boolean isYAML(Path path) {
String pathStr = path.toString();
return pathStr.endsWith(".yml") || pathStr.endsWith(".yaml");
}
/**
* Deserializer for {@link TaintConfig}.
*/
private static class Deserializer extends JsonDeserializer {
private final SignatureMatcher matcher;
private final TypeSystem typeSystem;
private Deserializer(SignatureMatcher matcher, TypeSystem typeSystem) {
this.matcher = matcher;
this.typeSystem = typeSystem;
}
@Override
public TaintConfig deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException {
ObjectCodec oc = p.getCodec();
JsonNode node = oc.readTree(p);
List