Skip to content

Commit 1ec1500

Browse files
committed
add end node filter and relationship filter
1 parent 45f0539 commit 1ec1500

File tree

4 files changed

+64
-20
lines changed

4 files changed

+64
-20
lines changed

README.md

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,36 @@
33

44
## Chinese
55

6-
### 简介
6+
### Introduction
77

88
实现了自定义procedure
9+
910
- `bytecodedl.findOnePath`
10-
- `findOnePath(@Name("start") Node start, @Name("end") Node end, @Name("maxLength") Long maxLength @Name("callProperty") String callProperty)`
11+
- `findOnePath(@Name("start") Node start, @Name("end") Node end, @Name("maxLength") long maxLength, @Name(value = "relationshipType", defaultValue = "Call") String relationType, @Name(value = "callProperty", defaultValue = "insn") String callProperty)`
1112
- `bytecodedl.biFindOnePath`
12-
- `biFindOnePath(@Name("start") Node start, @Name("end") Node end, @Name("maxLength") Long maxLength @Name("callProperty") String callProperty)`
13+
- `biFindOnePath(@Name("start") Node start, @Name("end") Node end, @Name("maxLength") long maxLength, @Name(value = "relationshipType", defaultValue = "Call") String relationType, @Name(value = "callProperty", defaultValue = "insn") String callProperty)`
14+
15+
其中各个参数的意义
16+
17+
- start: 开始节点
18+
- end: 结束节点
19+
- maxLength: path 最大长度
20+
- relationshipType: 边的类型 默认是Call
21+
- callProperty: 边的属性名称 默认是insn 值的格式为`<org.apache.logging.log4j.core.appender.ScriptAppenderSelector$Builder: org.apache.logging.log4j.core.Appender build()>/org.apache.logging.log4j.Logger.error/0`,会根据这个值计算multi dispatch
1322

1423
功能包括:
1524
- 从start到end找到长度小于maxlength任意一条路径就返回 -> 速度较快
1625
- 然后找到该路径第一个存在multi dispatch的边,同时返回所有的dispatch结果 -> 方便排查virtual invoke存在多个callee的情况
26+
- 过滤掉属性is_deleted为1的边
27+
28+
### Build
29+
30+
`./mvnw clean package -DskipTests`
1731

18-
### 安装
32+
### Install
1933

2034
- 手动安装
2135
-[releases](https://github.com/BytecodeDL/bytecodedl-pathfinder-neo4j-procedure/releases/)下载最新的jar, 然后放到neo4j的`/var/lib/neo4j/plugins`目录
2236
- 然后在`/var/lib/neo4j/conf/neo4j.conf`增加一行`dbms.security.procedures.unrestricted=bytecodedl.*`
2337
- docker
24-
-
38+
- `docker pull wuxxxxx/neo4j-server:5.12.0-bytecodedl-pathfinder-1.0.0`

pom.xml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,6 @@
4141
<scope>provided</scope>
4242
</dependency>
4343

44-
<!-- <dependency>-->
45-
<!-- <groupId>org.neo4j</groupId>-->
46-
<!-- <artifactId>neo4j-graph-algo</artifactId>-->
47-
<!-- <version>5.12.0</version>-->
48-
<!-- </dependency>-->
49-
5044
<!-- Test Dependencies -->
5145
<dependency>
5246
<!-- This is used for a utility that lets us start Neo4j with
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.bytecodedl.pathfinder;
2+
3+
import org.neo4j.graphdb.Node;
4+
import org.neo4j.graphdb.Path;
5+
import org.neo4j.graphdb.traversal.Evaluation;
6+
import org.neo4j.graphdb.traversal.Evaluator;
7+
8+
9+
/**
10+
11+
* @date 2023/12/16 16:40
12+
*/
13+
public class FindAnyOneEvaluator implements Evaluator {
14+
private Node endNode;
15+
private long maxLength;
16+
17+
public FindAnyOneEvaluator(Node endNode, long maxLength){
18+
this.endNode = endNode;
19+
this.maxLength = maxLength;
20+
}
21+
22+
@Override
23+
public Evaluation evaluate(Path path) {
24+
if (path.length() > this.maxLength){
25+
return Evaluation.EXCLUDE_AND_PRUNE;
26+
}
27+
28+
Node pathEndNode = path.endNode();
29+
if (pathEndNode.equals(endNode)){
30+
return Evaluation.INCLUDE_AND_PRUNE;
31+
}
32+
33+
return Evaluation.EXCLUDE_AND_CONTINUE;
34+
}
35+
}
36+

src/main/java/com/bytecodedl/pathfinder/FindAnyOnePath.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
package com.bytecodedl.pathfinder;
22

3-
import org.neo4j.graphalgo.GraphAlgoFactory;
4-
import org.neo4j.graphalgo.PathFinder;
5-
import org.neo4j.graphalgo.WeightedPath;
63
import org.neo4j.graphalgo.impl.util.PathImpl;
74
import org.neo4j.graphdb.*;
85
import org.neo4j.graphdb.traversal.*;
96
import org.neo4j.logging.Log;
107
import org.neo4j.procedure.*;
118

12-
import java.nio.DoubleBuffer;
139
import java.util.Collections;
1410
import java.util.List;
1511
import java.util.Optional;
@@ -31,11 +27,15 @@ public class FindAnyOnePath {
3127

3228
@Procedure(name = "bytecodedl.findOnePath", mode = Mode.READ)
3329
@Description("find one path from start to end under maxlength, also show first multi dispatch")
34-
public Stream<PathRecord> findOnePath(@Name("start") Node start, @Name("end") Node end, @Name("maxLength") long maxLength, @Name("callProperty") String callProperty){
30+
public Stream<PathRecord> findOnePath(@Name("start") Node start, @Name("end") Node end, @Name("maxLength") long maxLength, @Name(value = "relationshipType", defaultValue = "Call") String relationType, @Name(value = "callProperty", defaultValue = "insn") String callProperty){
3531
final Traverser traverser = tx.traversalDescription()
3632
.breadthFirst()
37-
.evaluator(Evaluators.toDepth((int)maxLength))
38-
.expand(PathExpanders.forTypeAndDirection(RelationshipType.withName("Call"), Direction.OUTGOING ))
33+
.evaluator(new FindAnyOneEvaluator(end, maxLength))
34+
.expand(
35+
PathExpanderBuilder.empty()
36+
.add(RelationshipType.withName(relationType), Direction.OUTGOING)
37+
// filter non delete relation
38+
.addRelationshipFilter(relationship -> relationship.getProperty("is_deleted", "0").equals("0")).build())
3939
.uniqueness(Uniqueness.NODE_GLOBAL)
4040
.traverse(start);
4141

@@ -44,9 +44,9 @@ public Stream<PathRecord> findOnePath(@Name("start") Node start, @Name("end") No
4444

4545
@Procedure(name = "bytecodedl.biFindOnePath", mode = Mode.READ)
4646
@Description("find one path from start to end between minlength and maxlength, also show first multi dispatch")
47-
public Stream<PathRecord> biFindOnePath(@Name("start") Node start, @Name("end") Node end, @Name("maxLength") long maxLength, @Name("callProperty") String callProperty){
47+
public Stream<PathRecord> biFindOnePath(@Name("start") Node start, @Name("end") Node end, @Name("maxLength") long maxLength, @Name(value = "relationshipType", defaultValue = "Call") String relationType, @Name(value = "callProperty", defaultValue = "insn") String callProperty){
4848
TraversalDescription base = tx.traversalDescription().depthFirst().uniqueness(Uniqueness.RELATIONSHIP_GLOBAL);
49-
PathExpander expander = PathExpanders.forTypeAndDirection(RelationshipType.withName("Call"), Direction.OUTGOING );
49+
PathExpander expander = PathExpanderBuilder.empty().add(RelationshipType.withName(relationType), Direction.OUTGOING).addRelationshipFilter(relationship -> relationship.getProperty("is_deleted", "0").equals("0")).build();
5050
int maxDepth = (int) maxLength;
5151

5252
final Traverser traverser = tx.bidirectionalTraversalDescription()

0 commit comments

Comments
 (0)