mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2025-12-22 09:57:07 +00:00
Merge pull request #4833 from projectdiscovery/maint-memory
Adding memguardian + various optimizations
This commit is contained in:
commit
b7f76cfd4b
12
go.mod
12
go.mod
@ -30,7 +30,7 @@ require (
|
|||||||
github.com/remeh/sizedwaitgroup v1.0.0
|
github.com/remeh/sizedwaitgroup v1.0.0
|
||||||
github.com/rs/xid v1.5.0
|
github.com/rs/xid v1.5.0
|
||||||
github.com/segmentio/ksuid v1.0.4
|
github.com/segmentio/ksuid v1.0.4
|
||||||
github.com/shirou/gopsutil/v3 v3.23.7 // indirect
|
github.com/shirou/gopsutil/v3 v3.24.2 // indirect
|
||||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||||
github.com/spf13/cast v1.5.1
|
github.com/spf13/cast v1.5.1
|
||||||
github.com/syndtr/goleveldb v1.0.0
|
github.com/syndtr/goleveldb v1.0.0
|
||||||
@ -94,7 +94,7 @@ require (
|
|||||||
github.com/projectdiscovery/tlsx v1.1.6
|
github.com/projectdiscovery/tlsx v1.1.6
|
||||||
github.com/projectdiscovery/uncover v1.0.7
|
github.com/projectdiscovery/uncover v1.0.7
|
||||||
github.com/projectdiscovery/useragent v0.0.40
|
github.com/projectdiscovery/useragent v0.0.40
|
||||||
github.com/projectdiscovery/utils v0.0.84-0.20240312214300-d3ba70dbb9ca
|
github.com/projectdiscovery/utils v0.0.84-0.20240313184656-e3ec80f4dd42
|
||||||
github.com/projectdiscovery/wappalyzergo v0.0.112
|
github.com/projectdiscovery/wappalyzergo v0.0.112
|
||||||
github.com/redis/go-redis/v9 v9.1.0
|
github.com/redis/go-redis/v9 v9.1.0
|
||||||
github.com/sashabaranov/go-openai v1.15.3
|
github.com/sashabaranov/go-openai v1.15.3
|
||||||
@ -204,6 +204,7 @@ require (
|
|||||||
github.com/projectdiscovery/stringsutil v0.0.2 // indirect
|
github.com/projectdiscovery/stringsutil v0.0.2 // indirect
|
||||||
github.com/quic-go/quic-go v0.40.1 // indirect
|
github.com/quic-go/quic-go v0.40.1 // indirect
|
||||||
github.com/refraction-networking/utls v1.6.1 // indirect
|
github.com/refraction-networking/utls v1.6.1 // indirect
|
||||||
|
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
|
||||||
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
||||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||||
github.com/skeema/knownhosts v1.2.1 // indirect
|
github.com/skeema/knownhosts v1.2.1 // indirect
|
||||||
@ -227,6 +228,7 @@ require (
|
|||||||
github.com/yuin/goldmark-emoji v1.0.1 // indirect
|
github.com/yuin/goldmark-emoji v1.0.1 // indirect
|
||||||
github.com/zeebo/blake3 v0.2.3 // indirect
|
github.com/zeebo/blake3 v0.2.3 // indirect
|
||||||
golang.org/x/arch v0.3.0 // indirect
|
golang.org/x/arch v0.3.0 // indirect
|
||||||
|
golang.org/x/sync v0.6.0 // indirect
|
||||||
gopkg.in/djherbis/times.v1 v1.3.0 // indirect
|
gopkg.in/djherbis/times.v1 v1.3.0 // indirect
|
||||||
mellium.im/sasl v0.3.1 // indirect
|
mellium.im/sasl v0.3.1 // indirect
|
||||||
)
|
)
|
||||||
@ -281,8 +283,8 @@ require (
|
|||||||
github.com/projectdiscovery/networkpolicy v0.0.8
|
github.com/projectdiscovery/networkpolicy v0.0.8
|
||||||
github.com/rivo/uniseg v0.4.6 // indirect
|
github.com/rivo/uniseg v0.4.6 // indirect
|
||||||
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d // indirect
|
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d // indirect
|
||||||
github.com/tklauser/go-sysconf v0.3.11 // indirect
|
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
||||||
github.com/tklauser/numcpus v0.6.0 // indirect
|
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||||
github.com/trivago/tgo v1.0.7
|
github.com/trivago/tgo v1.0.7
|
||||||
github.com/ulikunitz/xz v0.5.11 // indirect
|
github.com/ulikunitz/xz v0.5.11 // indirect
|
||||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
@ -290,7 +292,7 @@ require (
|
|||||||
github.com/ysmood/goob v0.4.0 // indirect
|
github.com/ysmood/goob v0.4.0 // indirect
|
||||||
github.com/ysmood/gson v0.7.3 // indirect
|
github.com/ysmood/gson v0.7.3 // indirect
|
||||||
github.com/ysmood/leakless v0.8.0 // indirect
|
github.com/ysmood/leakless v0.8.0 // indirect
|
||||||
github.com/yusufpapurcu/wmi v1.2.3 // indirect
|
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||||
github.com/zmap/rc2 v0.0.0-20190804163417-abaa70531248 // indirect
|
github.com/zmap/rc2 v0.0.0-20190804163417-abaa70531248 // indirect
|
||||||
github.com/zmap/zcrypto v0.0.0-20231219022726-a1f61fb1661c // indirect
|
github.com/zmap/zcrypto v0.0.0-20231219022726-a1f61fb1661c // indirect
|
||||||
go.etcd.io/bbolt v1.3.8 // indirect
|
go.etcd.io/bbolt v1.3.8 // indirect
|
||||||
|
|||||||
25
go.sum
25
go.sum
@ -890,8 +890,10 @@ github.com/projectdiscovery/uncover v1.0.7 h1:ut+2lTuvmftmveqF5RTjMWAgyLj8ltPQC7
|
|||||||
github.com/projectdiscovery/uncover v1.0.7/go.mod h1:HFXgm1sRPuoN0D4oATljPIdmbo/EEh1wVuxQqo/dwFE=
|
github.com/projectdiscovery/uncover v1.0.7/go.mod h1:HFXgm1sRPuoN0D4oATljPIdmbo/EEh1wVuxQqo/dwFE=
|
||||||
github.com/projectdiscovery/useragent v0.0.40 h1:1LUhReSGPkhqsM5n40OOC9dIoNqMGs1dyGFJcOmg2Fo=
|
github.com/projectdiscovery/useragent v0.0.40 h1:1LUhReSGPkhqsM5n40OOC9dIoNqMGs1dyGFJcOmg2Fo=
|
||||||
github.com/projectdiscovery/useragent v0.0.40/go.mod h1:EvK1x3s948Gtqb/XOahXcauyejCL/rSgy5d1IAvsKT4=
|
github.com/projectdiscovery/useragent v0.0.40/go.mod h1:EvK1x3s948Gtqb/XOahXcauyejCL/rSgy5d1IAvsKT4=
|
||||||
github.com/projectdiscovery/utils v0.0.84-0.20240312214300-d3ba70dbb9ca h1:GY9lUYDlENXPSFPJH01Bm1BfhrUF2jpnUBR+K4VPJIs=
|
github.com/projectdiscovery/utils v0.0.84-0.20240311212130-16ce15974a4a h1:njYY24OsTQJ80L8O+QxcYFljiVl83xp/BWz3dsIJF30=
|
||||||
github.com/projectdiscovery/utils v0.0.84-0.20240312214300-d3ba70dbb9ca/go.mod h1:wzMfHBq2I9oy+DEiMfUYV86g1D7eXKaQsgWnqFpmMtI=
|
github.com/projectdiscovery/utils v0.0.84-0.20240311212130-16ce15974a4a/go.mod h1:bvcudEteeZ5MIZeBCXEfpcgj9h3tyB9qtnmc7zQR92w=
|
||||||
|
github.com/projectdiscovery/utils v0.0.84-0.20240313184656-e3ec80f4dd42 h1:l22rSOP8i6HXu1QfAtIot8NvmJgUmBHEn6Mih7s8Gak=
|
||||||
|
github.com/projectdiscovery/utils v0.0.84-0.20240313184656-e3ec80f4dd42/go.mod h1:VsoXXTuNAAziuodKWakLyurVXaV4tNTJU4Eo8umyr3Q=
|
||||||
github.com/projectdiscovery/wappalyzergo v0.0.112 h1:QPpp5jmj1lqLd5mFdFKQ9VvcYhQNqyU9Mr+IB0US2zA=
|
github.com/projectdiscovery/wappalyzergo v0.0.112 h1:QPpp5jmj1lqLd5mFdFKQ9VvcYhQNqyU9Mr+IB0US2zA=
|
||||||
github.com/projectdiscovery/wappalyzergo v0.0.112/go.mod h1:hc/o+fgM8KtdpFesjfBTmHTwsR+yBd+4kYZW/DGy/x8=
|
github.com/projectdiscovery/wappalyzergo v0.0.112/go.mod h1:hc/o+fgM8KtdpFesjfBTmHTwsR+yBd+4kYZW/DGy/x8=
|
||||||
github.com/projectdiscovery/yamldoc-go v1.0.4 h1:eZoESapnMw6WAHiVgRwNqvbJEfNHEH148uthhFbG5jE=
|
github.com/projectdiscovery/yamldoc-go v1.0.4 h1:eZoESapnMw6WAHiVgRwNqvbJEfNHEH148uthhFbG5jE=
|
||||||
@ -964,8 +966,10 @@ github.com/seh-msft/burpxml v1.0.1/go.mod h1:lTViCHPtGGS0scK0B4krm6Ld1kVZLWzQccw
|
|||||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||||
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
|
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
|
||||||
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||||
github.com/shirou/gopsutil/v3 v3.23.7 h1:C+fHO8hfIppoJ1WdsVm1RoI0RwXoNdfTK7yWXV0wVj4=
|
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
|
||||||
github.com/shirou/gopsutil/v3 v3.23.7/go.mod h1:c4gnmoRC0hQuaLqvxnx1//VXQ0Ms/X9UnJF8pddY5z4=
|
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||||
|
github.com/shirou/gopsutil/v3 v3.24.2 h1:kcR0erMbLg5/3LcInpw0X/rrPSqq4CDPyI6A6ZRC18Y=
|
||||||
|
github.com/shirou/gopsutil/v3 v3.24.2/go.mod h1:tSg/594BcA+8UdQU2XcW803GWYgdtauFFPgJCJKZlVk=
|
||||||
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
||||||
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
|
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
|
||||||
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
|
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
|
||||||
@ -1044,10 +1048,10 @@ github.com/tidwall/tinyqueue v0.1.1 h1:SpNEvEggbpyN5DIReaJ2/1ndroY8iyEGxPYxoSaym
|
|||||||
github.com/tidwall/tinyqueue v0.1.1/go.mod h1:O/QNHwrnjqr6IHItYrzoHAKYhBkLI67Q096fQP5zMYw=
|
github.com/tidwall/tinyqueue v0.1.1/go.mod h1:O/QNHwrnjqr6IHItYrzoHAKYhBkLI67Q096fQP5zMYw=
|
||||||
github.com/tim-ywliu/nested-logrus-formatter v1.3.2 h1:jugNJ2/CNCI79SxOJCOhwUHeN3O7/7/bj+ZRGOFlCSw=
|
github.com/tim-ywliu/nested-logrus-formatter v1.3.2 h1:jugNJ2/CNCI79SxOJCOhwUHeN3O7/7/bj+ZRGOFlCSw=
|
||||||
github.com/tim-ywliu/nested-logrus-formatter v1.3.2/go.mod h1:oGPmcxZB65j9Wo7mCnQKSrKEJtVDqyjD666SGmyStXI=
|
github.com/tim-ywliu/nested-logrus-formatter v1.3.2/go.mod h1:oGPmcxZB65j9Wo7mCnQKSrKEJtVDqyjD666SGmyStXI=
|
||||||
github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
|
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
|
||||||
github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI=
|
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
|
||||||
github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
|
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
|
||||||
github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4=
|
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
github.com/trivago/tgo v1.0.7 h1:uaWH/XIy9aWYWpjm2CU3RpcqZXmX2ysQ9/Go+d9gyrM=
|
github.com/trivago/tgo v1.0.7 h1:uaWH/XIy9aWYWpjm2CU3RpcqZXmX2ysQ9/Go+d9gyrM=
|
||||||
github.com/trivago/tgo v1.0.7/go.mod h1:w4dpD+3tzNIIiIfkWWa85w5/B77tlvdZckQ+6PkFnhc=
|
github.com/trivago/tgo v1.0.7/go.mod h1:w4dpD+3tzNIIiIfkWWa85w5/B77tlvdZckQ+6PkFnhc=
|
||||||
@ -1116,8 +1120,8 @@ github.com/yuin/goldmark v1.5.4 h1:2uY/xC0roWy8IBEGLgB1ywIoEJFGmRrX21YQcvGZzjU=
|
|||||||
github.com/yuin/goldmark v1.5.4/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.5.4/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
github.com/yuin/goldmark-emoji v1.0.1 h1:ctuWEyzGBwiucEqxzwe0SOYDXPAucOrE9NQC18Wa1os=
|
github.com/yuin/goldmark-emoji v1.0.1 h1:ctuWEyzGBwiucEqxzwe0SOYDXPAucOrE9NQC18Wa1os=
|
||||||
github.com/yuin/goldmark-emoji v1.0.1/go.mod h1:2w1E6FEWLcDQkoTE+7HU6QF1F6SLlNGjRIBbIZQFqkQ=
|
github.com/yuin/goldmark-emoji v1.0.1/go.mod h1:2w1E6FEWLcDQkoTE+7HU6QF1F6SLlNGjRIBbIZQFqkQ=
|
||||||
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
|
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
||||||
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||||
github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY=
|
github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY=
|
||||||
github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
|
github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
|
||||||
github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg=
|
github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg=
|
||||||
@ -1387,6 +1391,7 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|||||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
||||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
|||||||
@ -64,6 +64,22 @@ func (operators *Operators) Compile() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (operators *Operators) HasDSL() bool {
|
||||||
|
for _, matcher := range operators.Matchers {
|
||||||
|
if len(matcher.DSL) > 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, extractor := range operators.Extractors {
|
||||||
|
if len(extractor.DSL) > 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// GetMatchersCondition returns the condition for the matchers
|
// GetMatchersCondition returns the condition for the matchers
|
||||||
func (operators *Operators) GetMatchersCondition() matchers.ConditionType {
|
func (operators *Operators) GetMatchersCondition() matchers.ConditionType {
|
||||||
return operators.matchersCondition
|
return operators.matchersCondition
|
||||||
|
|||||||
@ -73,6 +73,10 @@ var decolorizerRegex = regexp.MustCompile(`\x1B\[[0-9;]*[a-zA-Z]`)
|
|||||||
// InternalEvent is an internal output generation structure for nuclei.
|
// InternalEvent is an internal output generation structure for nuclei.
|
||||||
type InternalEvent map[string]interface{}
|
type InternalEvent map[string]interface{}
|
||||||
|
|
||||||
|
func (ie InternalEvent) Set(k string, v interface{}) {
|
||||||
|
ie[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
// InternalWrappedEvent is a wrapped event with operators result added to it.
|
// InternalWrappedEvent is a wrapped event with operators result added to it.
|
||||||
type InternalWrappedEvent struct {
|
type InternalWrappedEvent struct {
|
||||||
// Mutex is internal field which is implicitly used
|
// Mutex is internal field which is implicitly used
|
||||||
|
|||||||
98
pkg/protocols/common/protocolstate/memguardian.go
Normal file
98
pkg/protocols/common/protocolstate/memguardian.go
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
package protocolstate
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/projectdiscovery/gologger"
|
||||||
|
"github.com/projectdiscovery/utils/env"
|
||||||
|
httputil "github.com/projectdiscovery/utils/http"
|
||||||
|
"github.com/projectdiscovery/utils/memguardian"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
MaxThreadsOnLowMemory = env.GetEnvOrDefault("MEMGUARDIAN_THREADS", 0)
|
||||||
|
MaxBytesBufferAllocOnLowMemory = env.GetEnvOrDefault("MEMGUARDIAN_ALLOC", 0)
|
||||||
|
memTimer *time.Ticker
|
||||||
|
)
|
||||||
|
|
||||||
|
func StartActiveMemGuardian() {
|
||||||
|
if memguardian.DefaultMemGuardian == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
memTimer := time.NewTicker(memguardian.DefaultInterval)
|
||||||
|
go func() {
|
||||||
|
for range memTimer.C {
|
||||||
|
if IsLowOnMemory() {
|
||||||
|
_ = GlobalGuardBytesBufferAlloc()
|
||||||
|
} else {
|
||||||
|
GlobalRestoreBytesBufferAlloc()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
func StopActiveMemGuardian() {
|
||||||
|
if memguardian.DefaultMemGuardian == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
memTimer.Stop()
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsLowOnMemory() bool {
|
||||||
|
if memguardian.DefaultMemGuardian != nil && memguardian.DefaultMemGuardian.Warning.Load() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// GuardThreads on caller
|
||||||
|
func GuardThreadsOrDefault(current int) int {
|
||||||
|
if MaxThreadsOnLowMemory > 0 {
|
||||||
|
return MaxThreadsOnLowMemory
|
||||||
|
}
|
||||||
|
|
||||||
|
fraction := int(current / 5)
|
||||||
|
if fraction > 0 {
|
||||||
|
return fraction
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
var muGlobalChange sync.Mutex
|
||||||
|
|
||||||
|
// Global setting
|
||||||
|
func GlobalGuardBytesBufferAlloc() error {
|
||||||
|
if muGlobalChange.TryLock() {
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
defer muGlobalChange.Unlock()
|
||||||
|
|
||||||
|
// if current capacity was not reduced decrease it
|
||||||
|
if MaxBytesBufferAllocOnLowMemory > 0 && httputil.DefaultBytesBufferAlloc == httputil.GetPoolSize() {
|
||||||
|
gologger.Debug().Msgf("reducing bytes.buffer pool size to: %d", MaxBytesBufferAllocOnLowMemory)
|
||||||
|
delta := httputil.GetPoolSize() - int64(MaxBytesBufferAllocOnLowMemory)
|
||||||
|
return httputil.ChangePoolSize(-delta)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Global setting
|
||||||
|
func GlobalRestoreBytesBufferAlloc() {
|
||||||
|
if muGlobalChange.TryLock() {
|
||||||
|
return
|
||||||
|
|
||||||
|
}
|
||||||
|
defer muGlobalChange.Unlock()
|
||||||
|
|
||||||
|
if httputil.DefaultBytesBufferAlloc != httputil.GetPoolSize() {
|
||||||
|
delta := httputil.DefaultBytesBufferAlloc - httputil.GetPoolSize()
|
||||||
|
gologger.Debug().Msgf("restoring bytes.buffer pool size to: %d", httputil.DefaultBytesBufferAlloc)
|
||||||
|
_ = httputil.ChangePoolSize(delta)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -18,13 +18,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Dialer is a shared fastdialer instance for host DNS resolution
|
// Dialer is a shared fastdialer instance for host DNS resolution
|
||||||
var Dialer *fastdialer.Dialer
|
var (
|
||||||
|
Dialer *fastdialer.Dialer
|
||||||
|
)
|
||||||
|
|
||||||
// Init creates the Dialer instance based on user configuration
|
// Init creates the Dialer instance based on user configuration
|
||||||
func Init(options *types.Options) error {
|
func Init(options *types.Options) error {
|
||||||
if Dialer != nil {
|
if Dialer != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
lfaAllowed = options.AllowLocalFileAccess
|
lfaAllowed = options.AllowLocalFileAccess
|
||||||
opts := fastdialer.DefaultOptions
|
opts := fastdialer.DefaultOptions
|
||||||
if options.DialerTimeout > 0 {
|
if options.DialerTimeout > 0 {
|
||||||
@ -142,6 +145,8 @@ func Init(options *types.Options) error {
|
|||||||
return Dialer.Dial(ctx, "tcp", addr)
|
return Dialer.Dial(ctx, "tcp", addr)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
StartActiveMemGuardian()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,4 +207,5 @@ func Close() {
|
|||||||
if Dialer != nil {
|
if Dialer != nil {
|
||||||
Dialer.Close()
|
Dialer.Close()
|
||||||
}
|
}
|
||||||
|
StopActiveMemGuardian()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +0,0 @@
|
|||||||
package tostring
|
|
||||||
|
|
||||||
import "unsafe"
|
|
||||||
|
|
||||||
// UnsafeToString converts byte slice to string with zero allocations
|
|
||||||
func UnsafeToString(bs []byte) string {
|
|
||||||
return *(*string)(unsafe.Pointer(&bs))
|
|
||||||
}
|
|
||||||
@ -14,6 +14,7 @@ import (
|
|||||||
"github.com/projectdiscovery/nuclei/v3/pkg/protocols"
|
"github.com/projectdiscovery/nuclei/v3/pkg/protocols"
|
||||||
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/expressions"
|
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/expressions"
|
||||||
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/generators"
|
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/generators"
|
||||||
|
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
|
||||||
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/http/httpclientpool"
|
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/http/httpclientpool"
|
||||||
httputil "github.com/projectdiscovery/nuclei/v3/pkg/protocols/utils/http"
|
httputil "github.com/projectdiscovery/nuclei/v3/pkg/protocols/utils/http"
|
||||||
"github.com/projectdiscovery/rawhttp"
|
"github.com/projectdiscovery/rawhttp"
|
||||||
@ -411,6 +412,10 @@ func (request *Request) Compile(options *protocols.ExecutorOptions) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(request.Payloads) > 0 {
|
if len(request.Payloads) > 0 {
|
||||||
|
// specifically for http requests high concurrency and and threads will lead to memory exausthion, hence reduce the maximum parallelism
|
||||||
|
if protocolstate.IsLowOnMemory() {
|
||||||
|
request.Threads = protocolstate.GuardThreadsOrDefault(request.Threads)
|
||||||
|
}
|
||||||
// if we have payloads, adjust threads if none specified
|
// if we have payloads, adjust threads if none specified
|
||||||
request.Threads = options.GetThreadsForNPayloadRequests(request.Requests(), request.Threads)
|
request.Threads = options.GetThreadsForNPayloadRequests(request.Requests(), request.Threads)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -112,21 +112,21 @@ func (request *Request) responseToDSLMap(resp *http.Response, host, matched, raw
|
|||||||
data[k] = v
|
data[k] = v
|
||||||
}
|
}
|
||||||
for _, cookie := range resp.Cookies() {
|
for _, cookie := range resp.Cookies() {
|
||||||
data[strings.ToLower(cookie.Name)] = cookie.Value
|
request.setHashOrDefault(data, strings.ToLower(cookie.Name), cookie.Value)
|
||||||
}
|
}
|
||||||
for k, v := range resp.Header {
|
for k, v := range resp.Header {
|
||||||
k = strings.ToLower(strings.ReplaceAll(strings.TrimSpace(k), "-", "_"))
|
k = strings.ToLower(strings.ReplaceAll(strings.TrimSpace(k), "-", "_"))
|
||||||
data[k] = strings.Join(v, " ")
|
request.setHashOrDefault(data, k, strings.Join(v, " "))
|
||||||
}
|
}
|
||||||
data["host"] = host
|
data["host"] = host
|
||||||
data["type"] = request.Type().String()
|
data["type"] = request.Type().String()
|
||||||
data["matched"] = matched
|
data["matched"] = matched
|
||||||
data["request"] = rawReq
|
request.setHashOrDefault(data, "request", rawReq)
|
||||||
data["response"] = rawResp
|
request.setHashOrDefault(data, "response", rawResp)
|
||||||
data["status_code"] = resp.StatusCode
|
data["status_code"] = resp.StatusCode
|
||||||
data["body"] = body
|
request.setHashOrDefault(data, "body", body)
|
||||||
data["all_headers"] = headers
|
request.setHashOrDefault(data, "all_headers", headers)
|
||||||
data["header"] = headers
|
request.setHashOrDefault(data, "header", headers)
|
||||||
data["duration"] = duration.Seconds()
|
data["duration"] = duration.Seconds()
|
||||||
data["template-id"] = request.options.TemplateID
|
data["template-id"] = request.options.TemplateID
|
||||||
data["template-info"] = request.options.TemplateInfo
|
data["template-info"] = request.options.TemplateInfo
|
||||||
@ -140,6 +140,15 @@ func (request *Request) responseToDSLMap(resp *http.Response, host, matched, raw
|
|||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: disabling hdd storage while testing backpressure mechanism
|
||||||
|
func (request *Request) setHashOrDefault(data output.InternalEvent, k string, v string) {
|
||||||
|
// if hash, err := request.options.Storage.SetString(v); err == nil {
|
||||||
|
// data[k] = hash
|
||||||
|
// } else {
|
||||||
|
data[k] = v
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
// MakeResultEvent creates a result event from internal wrapped event
|
// MakeResultEvent creates a result event from internal wrapped event
|
||||||
func (request *Request) MakeResultEvent(wrapped *output.InternalWrappedEvent) []*output.ResultEvent {
|
func (request *Request) MakeResultEvent(wrapped *output.InternalWrappedEvent) []*output.ResultEvent {
|
||||||
return protocols.MakeDefaultResultEvent(request, wrapped)
|
return protocols.MakeDefaultResultEvent(request, wrapped)
|
||||||
|
|||||||
@ -28,7 +28,7 @@ import (
|
|||||||
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/helpers/eventcreator"
|
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/helpers/eventcreator"
|
||||||
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/helpers/responsehighlighter"
|
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/helpers/responsehighlighter"
|
||||||
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/interactsh"
|
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/interactsh"
|
||||||
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/tostring"
|
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
|
||||||
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/http/httpclientpool"
|
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/http/httpclientpool"
|
||||||
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/http/httputils"
|
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/http/httputils"
|
||||||
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/http/signer"
|
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/http/signer"
|
||||||
@ -168,6 +168,10 @@ func (request *Request) executeParallelHTTP(input *contextargs.Context, dynamicV
|
|||||||
// Workers that keeps enqueuing new requests
|
// Workers that keeps enqueuing new requests
|
||||||
maxWorkers := request.Threads
|
maxWorkers := request.Threads
|
||||||
|
|
||||||
|
if protocolstate.IsLowOnMemory() {
|
||||||
|
maxWorkers = protocolstate.GuardThreadsOrDefault(request.Threads)
|
||||||
|
}
|
||||||
|
|
||||||
// Stop-at-first-match logic while executing requests
|
// Stop-at-first-match logic while executing requests
|
||||||
// parallely using threads
|
// parallely using threads
|
||||||
shouldStop := (request.options.Options.StopAtFirstMatch || request.StopAtFirstMatch || request.options.StopAtFirstMatch)
|
shouldStop := (request.options.Options.StopAtFirstMatch || request.StopAtFirstMatch || request.options.StopAtFirstMatch)
|
||||||
@ -684,7 +688,7 @@ func (request *Request) executeRequest(input *contextargs.Context, generatedRequ
|
|||||||
// In case of interactsh markers and request times out, still send
|
// In case of interactsh markers and request times out, still send
|
||||||
// a callback event so in case we receive an interaction, correlation is possible.
|
// a callback event so in case we receive an interaction, correlation is possible.
|
||||||
// Also, to log failed use-cases.
|
// Also, to log failed use-cases.
|
||||||
outputEvent := request.responseToDSLMap(&http.Response{}, input.MetaInput.Input, formedURL, tostring.UnsafeToString(dumpedRequest), "", "", "", 0, generatedRequest.meta)
|
outputEvent := request.responseToDSLMap(&http.Response{}, input.MetaInput.Input, formedURL, convUtil.String(dumpedRequest), "", "", "", 0, generatedRequest.meta)
|
||||||
if i := strings.LastIndex(hostname, ":"); i != -1 {
|
if i := strings.LastIndex(hostname, ":"); i != -1 {
|
||||||
hostname = hostname[:i]
|
hostname = hostname[:i]
|
||||||
}
|
}
|
||||||
@ -695,8 +699,8 @@ func (request *Request) executeRequest(input *contextargs.Context, generatedRequ
|
|||||||
outputEvent["ip"] = httpclientpool.Dialer.GetDialedIP(hostname)
|
outputEvent["ip"] = httpclientpool.Dialer.GetDialedIP(hostname)
|
||||||
}
|
}
|
||||||
|
|
||||||
event := &output.InternalWrappedEvent{InternalEvent: outputEvent}
|
event := &output.InternalWrappedEvent{}
|
||||||
if request.CompiledOperators != nil {
|
if request.CompiledOperators != nil && request.CompiledOperators.HasDSL() {
|
||||||
event.InternalEvent = outputEvent
|
event.InternalEvent = outputEvent
|
||||||
}
|
}
|
||||||
callback(event)
|
callback(event)
|
||||||
|
|||||||
@ -14,9 +14,9 @@ import (
|
|||||||
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/contextargs"
|
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/contextargs"
|
||||||
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/generators"
|
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/generators"
|
||||||
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/helpers/eventcreator"
|
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/helpers/eventcreator"
|
||||||
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/tostring"
|
|
||||||
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/utils"
|
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/utils"
|
||||||
templateTypes "github.com/projectdiscovery/nuclei/v3/pkg/templates/types"
|
templateTypes "github.com/projectdiscovery/nuclei/v3/pkg/templates/types"
|
||||||
|
"github.com/projectdiscovery/utils/conversion"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ protocols.Request = &Request{}
|
var _ protocols.Request = &Request{}
|
||||||
@ -60,7 +60,7 @@ func (request *Request) ExecuteWithResults(input *contextargs.Context, metadata
|
|||||||
gologger.Error().Msgf("Could not read file path %s: %s\n", data, err)
|
gologger.Error().Msgf("Could not read file path %s: %s\n", data, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
dataStr := tostring.UnsafeToString(buffer)
|
dataStr := conversion.String(buffer)
|
||||||
|
|
||||||
resp, err := readResponseFromString(dataStr)
|
resp, err := readResponseFromString(dataStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -86,7 +86,7 @@ func (request *Request) ExecuteWithResults(input *contextargs.Context, metadata
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
outputEvent := request.responseToDSLMap(resp, data, data, data, tostring.UnsafeToString(dumpedResponse), tostring.UnsafeToString(body), utils.HeadersToString(resp.Header), 0, nil)
|
outputEvent := request.responseToDSLMap(resp, data, data, data, conversion.String(dumpedResponse), conversion.String(body), utils.HeadersToString(resp.Header), 0, nil)
|
||||||
// add response fields to template context and merge templatectx variables to output event
|
// add response fields to template context and merge templatectx variables to output event
|
||||||
request.options.AddTemplateVars(input.MetaInput, request.Type(), request.GetID(), outputEvent)
|
request.options.AddTemplateVars(input.MetaInput, request.Type(), request.GetID(), outputEvent)
|
||||||
if request.options.HasTemplateCtx(input.MetaInput) {
|
if request.options.HasTemplateCtx(input.MetaInput) {
|
||||||
|
|||||||
@ -7,13 +7,13 @@ package dedupe
|
|||||||
import (
|
import (
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
"os"
|
"os"
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/syndtr/goleveldb/leveldb"
|
"github.com/syndtr/goleveldb/leveldb"
|
||||||
"github.com/syndtr/goleveldb/leveldb/errors"
|
"github.com/syndtr/goleveldb/leveldb/errors"
|
||||||
|
|
||||||
"github.com/projectdiscovery/nuclei/v3/pkg/output"
|
"github.com/projectdiscovery/nuclei/v3/pkg/output"
|
||||||
"github.com/projectdiscovery/nuclei/v3/pkg/types"
|
"github.com/projectdiscovery/nuclei/v3/pkg/types"
|
||||||
|
"github.com/projectdiscovery/utils/conversion"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Storage is a duplicate detecting storage for nuclei scan events.
|
// Storage is a duplicate detecting storage for nuclei scan events.
|
||||||
@ -75,29 +75,29 @@ func (s *Storage) Close() {
|
|||||||
func (s *Storage) Index(result *output.ResultEvent) (bool, error) {
|
func (s *Storage) Index(result *output.ResultEvent) (bool, error) {
|
||||||
hasher := sha1.New()
|
hasher := sha1.New()
|
||||||
if result.TemplateID != "" {
|
if result.TemplateID != "" {
|
||||||
_, _ = hasher.Write(unsafeToBytes(result.TemplateID))
|
_, _ = hasher.Write(conversion.Bytes(result.TemplateID))
|
||||||
}
|
}
|
||||||
if result.MatcherName != "" {
|
if result.MatcherName != "" {
|
||||||
_, _ = hasher.Write(unsafeToBytes(result.MatcherName))
|
_, _ = hasher.Write(conversion.Bytes(result.MatcherName))
|
||||||
}
|
}
|
||||||
if result.ExtractorName != "" {
|
if result.ExtractorName != "" {
|
||||||
_, _ = hasher.Write(unsafeToBytes(result.ExtractorName))
|
_, _ = hasher.Write(conversion.Bytes(result.ExtractorName))
|
||||||
}
|
}
|
||||||
if result.Type != "" {
|
if result.Type != "" {
|
||||||
_, _ = hasher.Write(unsafeToBytes(result.Type))
|
_, _ = hasher.Write(conversion.Bytes(result.Type))
|
||||||
}
|
}
|
||||||
if result.Host != "" {
|
if result.Host != "" {
|
||||||
_, _ = hasher.Write(unsafeToBytes(result.Host))
|
_, _ = hasher.Write(conversion.Bytes(result.Host))
|
||||||
}
|
}
|
||||||
if result.Matched != "" {
|
if result.Matched != "" {
|
||||||
_, _ = hasher.Write(unsafeToBytes(result.Matched))
|
_, _ = hasher.Write(conversion.Bytes(result.Matched))
|
||||||
}
|
}
|
||||||
for _, v := range result.ExtractedResults {
|
for _, v := range result.ExtractedResults {
|
||||||
_, _ = hasher.Write(unsafeToBytes(v))
|
_, _ = hasher.Write(conversion.Bytes(v))
|
||||||
}
|
}
|
||||||
for k, v := range result.Metadata {
|
for k, v := range result.Metadata {
|
||||||
_, _ = hasher.Write(unsafeToBytes(k))
|
_, _ = hasher.Write(conversion.Bytes(k))
|
||||||
_, _ = hasher.Write(unsafeToBytes(types.ToString(v)))
|
_, _ = hasher.Write(conversion.Bytes(types.ToString(v)))
|
||||||
}
|
}
|
||||||
hash := hasher.Sum(nil)
|
hash := hasher.Sum(nil)
|
||||||
|
|
||||||
@ -112,12 +112,3 @@ func (s *Storage) Index(result *output.ResultEvent) (bool, error) {
|
|||||||
}
|
}
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// unsafeToBytes converts a string to byte slice and does it with
|
|
||||||
// zero allocations.
|
|
||||||
//
|
|
||||||
// Reference - https://stackoverflow.com/questions/59209493/how-to-use-unsafe-get-a-byte-slice-from-a-string-without-memory-copy
|
|
||||||
func unsafeToBytes(data string) []byte {
|
|
||||||
var buf = (*[]byte)(unsafe.Pointer(&data))
|
|
||||||
return *buf
|
|
||||||
}
|
|
||||||
|
|||||||
@ -10,6 +10,14 @@ import (
|
|||||||
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/contextargs"
|
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/contextargs"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ScanContextOption func(*ScanContext)
|
||||||
|
|
||||||
|
func WithEvents() ScanContextOption {
|
||||||
|
return func(sc *ScanContext) {
|
||||||
|
sc.withEvents = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type ScanContext struct {
|
type ScanContext struct {
|
||||||
context.Context
|
context.Context
|
||||||
// exported / configurable fields
|
// exported / configurable fields
|
||||||
@ -18,11 +26,16 @@ type ScanContext struct {
|
|||||||
// callbacks or hooks
|
// callbacks or hooks
|
||||||
OnError func(error)
|
OnError func(error)
|
||||||
OnResult func(e *output.InternalWrappedEvent)
|
OnResult func(e *output.InternalWrappedEvent)
|
||||||
|
OnWarning func(string)
|
||||||
|
|
||||||
// unexported state fields
|
// unexported state fields
|
||||||
errors []error
|
errors []error
|
||||||
warnings []string
|
warnings []string
|
||||||
events []*output.InternalWrappedEvent
|
events []*output.InternalWrappedEvent
|
||||||
|
results []*output.ResultEvent
|
||||||
|
|
||||||
|
// what to log
|
||||||
|
withEvents bool
|
||||||
|
|
||||||
// might not be required but better to sync
|
// might not be required but better to sync
|
||||||
m sync.Mutex
|
m sync.Mutex
|
||||||
@ -37,7 +50,8 @@ func NewScanContext(input *contextargs.Context) *ScanContext {
|
|||||||
func (s *ScanContext) GenerateResult() []*output.ResultEvent {
|
func (s *ScanContext) GenerateResult() []*output.ResultEvent {
|
||||||
s.m.Lock()
|
s.m.Lock()
|
||||||
defer s.m.Unlock()
|
defer s.m.Unlock()
|
||||||
return aggregateResults(s.events)
|
|
||||||
|
return s.results
|
||||||
}
|
}
|
||||||
|
|
||||||
// LogEvent logs events to all events and triggeres any callbacks
|
// LogEvent logs events to all events and triggeres any callbacks
|
||||||
@ -48,10 +62,16 @@ func (s *ScanContext) LogEvent(e *output.InternalWrappedEvent) {
|
|||||||
// do not log nil events
|
// do not log nil events
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.OnResult != nil {
|
if s.OnResult != nil {
|
||||||
s.OnResult(e)
|
s.OnResult(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if s.withEvents {
|
||||||
s.events = append(s.events, e)
|
s.events = append(s.events, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.results = append(s.results, e.Results...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// LogError logs error to all events and triggeres any callbacks
|
// LogError logs error to all events and triggeres any callbacks
|
||||||
@ -68,10 +88,11 @@ func (s *ScanContext) LogError(err error) {
|
|||||||
s.errors = append(s.errors, err)
|
s.errors = append(s.errors, err)
|
||||||
|
|
||||||
errorMessage := joinErrors(s.errors)
|
errorMessage := joinErrors(s.errors)
|
||||||
results := aggregateResults(s.events)
|
|
||||||
for _, result := range results {
|
for _, result := range s.results {
|
||||||
result.Error = errorMessage
|
result.Error = errorMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, e := range s.events {
|
for _, e := range s.events {
|
||||||
e.InternalEvent["error"] = errorMessage
|
e.InternalEvent["error"] = errorMessage
|
||||||
}
|
}
|
||||||
@ -82,6 +103,11 @@ func (s *ScanContext) LogWarning(format string, args ...any) {
|
|||||||
s.m.Lock()
|
s.m.Lock()
|
||||||
defer s.m.Unlock()
|
defer s.m.Unlock()
|
||||||
val := fmt.Sprintf(format, args...)
|
val := fmt.Sprintf(format, args...)
|
||||||
|
|
||||||
|
if s.OnWarning != nil {
|
||||||
|
s.OnWarning(val)
|
||||||
|
}
|
||||||
|
|
||||||
s.warnings = append(s.warnings, val)
|
s.warnings = append(s.warnings, val)
|
||||||
|
|
||||||
for _, e := range s.events {
|
for _, e := range s.events {
|
||||||
@ -91,15 +117,6 @@ func (s *ScanContext) LogWarning(format string, args ...any) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// aggregateResults aggregates results from multiple events
|
|
||||||
func aggregateResults(events []*output.InternalWrappedEvent) []*output.ResultEvent {
|
|
||||||
var results []*output.ResultEvent
|
|
||||||
for _, e := range events {
|
|
||||||
results = append(results, e.Results...)
|
|
||||||
}
|
|
||||||
return results
|
|
||||||
}
|
|
||||||
|
|
||||||
// joinErrors joins multiple errors and returns a single error string
|
// joinErrors joins multiple errors and returns a single error string
|
||||||
func joinErrors(errors []error) string {
|
func joinErrors(errors []error) string {
|
||||||
var errorMessages []string
|
var errorMessages []string
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user