tindy2013 / subconverter

Utility to convert between various subscription format
GNU General Public License v3.0
13.42k stars 2.87k forks source link

[BUG] filter_script不按预期工作,结果不正常 #708

Open jacobin opened 10 months ago

jacobin commented 10 months ago

确认版本最新

检索issue

subconverter版本

v0.8.1 win64版

转换过程

多地址/多点/多格式合并转换为clash

转换设置

将如下js

function filter(node) {
    if(node.Type.toLowerCase() === "ss" && node.EncryptMethod.toLowerCase() === "chacha20-poly1305") {
        return false;
    }
    return true;
}

进行urlencode之后代入filter_script,亦即

filter_script=function%20filter%28node%29%20%7B%0A%20%20%20%20if%28node.Type.toLowerCase%28%29%20%3D%3D%3D%20%22ss%22%20%26%26%20node.EncryptMethod.toLowerCase%28%29%20%3D%3D%3D%20%22chacha20-poly1305%22%29%20%7B%0A%20%20%20%20%20%20%20%20return%20false%3B%0A%20%20%20%20%7D%0A%20%20%20%20return%20true%3B%0A%7D

整体的链接地址譬如

http://127.0.0.1:25500/sub?target=clash&enable_filter=true&filter_script=filter_script=function%20filter%28node%29%20%7B%0A%20%20%20%20if%28node.Type.toLowerCase%28%29%20%3D%3D%3D%20%22ss%22%20%26%26%20node.EncryptMethod.toLowerCase%28%29%20%3D%3D%3D%20%22chacha20-poly1305%22%29%20%7B%0A%20%20%20%20%20%20%20%20return%20false%3B%0A%20%20%20%20%7D%0A%20%20%20%20return%20true%3B%0A%7D&url=https%3A%2F%2Fwww.abc.com%2Fsub.yaml

结果是,预期中将被过滤去的节点譬如如下

 ...
proxies:
   ...
 - {name: 英国-1.77MB/s, server: series-a2-me.samanehha.co, port: 443, type: ss, cipher: chacha20-poly1305, password: Bog0ELmMM9DSxDdQ, udp: true}
    ...

还大剌剌的存在着

复现步骤

见“转换设置”

期望结果

类型为ss节点加密方法为chacha20-poly1305的节点不该留下

实际结果

类型为ss节点加密方法为chacha20-poly1305的节点还是出现了

错误信息

No response

jacobin commented 6 months ago

这个问题不值得解决吗??

ningzimu commented 4 months ago

同样问题,测了一下:

测试以下脚本正常过滤掉了chacha20-poly1305加密节点

function filter(node) {
    if (node.EncryptMethod.toLowerCase() === 'chacha20-poly1305') {
        return true;
    }
    return false;
}

另外,#523 也提到过这个问题

jacobin commented 4 months ago

如果你这说法是真的,那么我原有的脚本就应该是只留下了『type==="ss" && encryptmethod==="chacha20-poly1305"』的节点。不是吗?

同样问题,测了一下:

  • 添加Type字段筛选会报错。
  • true代表过滤、false代表不过滤,这里和文档说明相反。

测试以下脚本正常过滤掉了chacha20-poly1305加密节点

function filter(node) {
    if (node.EncryptMethod.toLowerCase() === 'chacha20-poly1305') {
        return true;
    }
    return false;
}

另外,#523 也提到过这个问题

ningzimu commented 4 months ago

如果你这说法是真的,那么我原有的脚本就应该是只留下了『type==="ss" && encryptmethod==="chacha20-poly1305"』的节点。不是吗?

同样问题,测了一下:

  • 添加Type字段筛选会报错。

  • true代表过滤、false代表不过滤,这里和文档说明相反。

测试以下脚本正常过滤掉了chacha20-poly1305加密节点


function filter(node) {

    if (node.EncryptMethod.toLowerCase() === 'chacha20-poly1305') {

        return true;

    }

    return false;

}

另外,#523 也提到过这个问题

不是,是不生效,因为报错了

jacobin commented 4 months ago

如果你这说法是真的,那么我原有的脚本就应该是只留下了『type==="ss" && encryptmethod==="chacha20-poly1305"』的节点。不是吗?

同样问题,测了一下:

  • 添加Type字段筛选会报错。

  • true代表过滤、false代表不过滤,这里和文档说明相反。

测试以下脚本正常过滤掉了chacha20-poly1305加密节点

function filter(node) {

if (node.EncryptMethod.toLowerCase() === 'chacha20-poly1305') {
    return true;
}
return false;

}

另外,#523 也提到过这个问题

不是,是不生效,因为报错了

报错,报的是什么错?脚本错或者其它的什么错?请不吝赐教,愿闻其详

ningzimu commented 4 months ago

如果你这说法是真的,那么我原有的脚本就应该是只留下了『type==="ss" && encryptmethod==="chacha20-poly1305"』的节点。不是吗?

同样问题,测了一下:

  • 添加Type字段筛选会报错。

  • true代表过滤、false代表不过滤,这里和文档说明相反。

测试以下脚本正常过滤掉了chacha20-poly1305加密节点

function filter(node) {

if (node.EncryptMethod.toLowerCase() === 'chacha20-poly1305') {
    return true;
}
return false;

}

另外,#523 也提到过这个问题

不是,是不生效,因为报错了

报错,报的是什么错?脚本错或者其它的什么错?请不吝赐教,愿闻其详

你看一下程序的log就知道了,会报如下错误:

TypeError: not a function
    at filter (<eval>:2)

然后这个js脚本就跳过了,最终输出并不会过滤任何节点。

jacobin commented 4 months ago

我可没有用到譬如#523的JSON.parse(node.ProxyInfo)的方法。我早就注意到这个方法已经失效,不受支持。 这个系统,文档和代码的同步做的不好,给我有很大的挫败感,拿着南京的地图打柏林的感觉。

不是,是不生效,因为报错了

ningzimu commented 4 months ago

node.Type.toLowerCase() === "ss"

node.Type.toLowerCase() === "ss"这个也不支持。

通过以下代码,可以过滤掉chacha20-poly1305协议的节点,解决了部分clash客户端的报错问题,暂时也能用。等作者后续修复吧。

function filter(node) {
    if (node.EncryptMethod.toLowerCase() === 'chacha20-poly1305') {
        return true;
    }
    return false;
}
jacobin commented 4 months ago

node.Type.toLowerCase() === "ss"

node.Type.toLowerCase() === "ss"这个也不支持。

通过以下代码,可以过滤掉chacha20-poly1305协议的节点,解决了部分clash客户端的报错问题,暂时也能用。等作者后续修复吧。

function filter(node) {
    if (node.EncryptMethod.toLowerCase() === 'chacha20-poly1305') {
        return true;
    }
    return false;
}

非常感谢!我got到要点了:type不能用

ningzimu commented 4 months ago

node.Type.toLowerCase() === "ss"

node.Type.toLowerCase() === "ss"这个也不支持。 通过以下代码,可以过滤掉chacha20-poly1305协议的节点,解决了部分clash客户端的报错问题,暂时也能用。等作者后续修复吧。

function filter(node) {
    if (node.EncryptMethod.toLowerCase() === 'chacha20-poly1305') {
        return true;
    }
    return false;
}

非常感谢!我got到要点了:type不能用

发现问题了,可能是因为,在 C++ 枚举类型和 JavaScript 之间进行转换时,默认情况下枚举值会被作为数字处理。 所以实际上node.Type并不是字符串,而是数字。

目前版本,应该按照节点类型对应的索引值过滤,才可以达到预期效果。

具体映射关系为:

enum class ProxyType
{
    Unknown,        // 0
    Shadowsocks,    // 1
    ShadowsocksR,   // 2
    VMess,          // 3
    Trojan,         // 4
    Snell,          // 5
    HTTP,           // 6
    HTTPS,          // 7
    SOCKS5,         // 8
    WireGuard       // 9
};

对应源码中的https://github.com/tindy2013/subconverter/blob/master/src/parser/config/proxy.h#L12-L24

比如,如果你想过滤掉节点类型Shadowsocks, 并且EncryptMethodchacha20-poly1305的节点,应该用如下js脚本:

function filter(node) {
    if (node.Type === 1 && node.EncryptMethod.toLowerCase() === 'chacha20-poly1305') {
        return true;
    }
    return false;
}

以此类推,可过滤其他类型的节点。

节点可用参数,参见#705

jacobin commented 4 months ago

node.Type.toLowerCase() === "ss"

node.Type.toLowerCase() === "ss"这个也不支持。 通过以下代码,可以过滤掉chacha20-poly1305协议的节点,解决了部分clash客户端的报错问题,暂时也能用。等作者后续修复吧。

function filter(node) {
    if (node.EncryptMethod.toLowerCase() === 'chacha20-poly1305') {
        return true;
    }
    return false;
}

非常感谢!我got到要点了:type不能用

发现问题了,可能是因为,在 C++ 枚举类型和 JavaScript 之间进行转换时,默认情况下枚举值会被作为数字处理。 所以实际上node.Type并不是字符串,而是数字。

目前版本,应该按照节点类型对应的索引值过滤,才可以达到预期效果。

具体映射关系为:

enum class ProxyType
{
    Unknown,        // 0
    Shadowsocks,    // 1
    ShadowsocksR,   // 2
    VMess,          // 3
    Trojan,         // 4
    Snell,          // 5
    HTTP,           // 6
    HTTPS,          // 7
    SOCKS5,         // 8
    WireGuard       // 9
};

对应源码中的https://github.com/tindy2013/subconverter/blob/master/src/parser/config/proxy.h#L12-L24

比如,如果你想过滤掉节点类型Shadowsocks, 并且EncryptMethodchacha20-poly1305的节点,应该用如下js脚本:

function filter(node) {
    if (node.Type === 1 && node.EncryptMethod.toLowerCase() === 'chacha20-poly1305') {
        return true;
    }
    return false;
}

以此类推,可过滤其他类型的节点。

节点可用参数,参见#705

我一直回避去探究他的代码。从匆匆一瞥得到的印象是:1、在源码里“ss”和“SS”都有出现,而我认为这应该是统一的,免得自乱并令人莫衷一是,而在用户层面的js代码里,应该容错兼容两者;2、代码里有形如std::map<ProxyType, const char *>的映射,所以,用字符串或者数字,不应该成为一个问题;3、形如node.Type.toLowerCase() === "ss"的表达,不是我凭空画的,我也曾经看到过这么个葫芦的;4、文档同步很糟糕,我在配置文件里和在readme.md里看到矛盾冲突莫衷一是的例子,不止一次了。举例如下 #697

xinlingfeiwu commented 4 months ago

您好,邮件已经收到,我会尽快给您回复。