subconverter icon indicating copy to clipboard operation
subconverter copied to clipboard

[BUG]有关filter_script中js代码的编码的问题

Open jacobin opened this issue 7 months ago • 5 comments

verify

  • [X] 我已经仔细阅读项目文档,确认现有功能无法解决我的需求
  • [X] 我已经检索过现有issue,确认与现有issue的内容并不重复
  • [X] 我已经尝试自行解决,确认自己没有能力解决

功能描述

对js代码A

function filter(node) {\n    const info = JSON.parse(node.ProxyInfo);\n    if(info.Type.toLowerCase()=='SS' && info.EncryptMethod.toLowerCase()=='chacha20-poly1305') {\n        return false;\n    }\n    return true;\n}

进行urlencode得结果A

function%20filter%28node%29%20%7B%5Cn%20%20%20%20const%20info%20%3D%20JSON.parse%28node.ProxyInfo%29%3B%5Cn%20%20%20%20if%28info.Type.toLowerCase%28%29%3D%3D%27SS%27%20%26%26%20info.EncryptMethod.toLowerCase%28%29%3D%3D%27chacha20-poly1305%27%29%20%7B%5Cn%20%20%20%20%20%20%20%20return%20false%3B%5Cn%20%20%20%20%7D%5Cn%20%20%20%20return%20true%3B%5Cn%7D

而对js代码B

function filter(node) {
    const info = JSON.parse(node.ProxyInfo);
    if(info.Type.toLowerCase()=='SS' && info.EncryptMethod.toLowerCase()=='chacha20-poly1305') {
        return false;
    }
    return true;
}

进行urlencode是得结果B

function%20filter%28node%29%20%7B%0A%20%20%20%20const%20info%20%3D%20JSON.parse%28node.ProxyInfo%29%3B%0A%20%20%20%20if%28info.Type.toLowerCase%28%29%3D%3D%27SS%27%20%26%26%20info.EncryptMethod.toLowerCase%28%29%3D%3D%27chacha20-poly1305%27%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

结果A和结果B当然是不一样的,请问在如下的调用

http://127.0.0.1:25500/sub?target=clash&enable_filter=true&filter_script=XXXXXX

中,我该以结果A还是结果B对XXXXXX进行代入?

注:代码A代码B其实是一样的。

可能的解决方案

No response N/A

jacobin avatar Dec 29 '23 17:12 jacobin

应该用结果B,因为A的源码不是有效的JavaScript脚本,'\n'是转义字符,你这里把它当文本用了。

lonelam avatar Jan 18 '24 07:01 lonelam

应该用结果B,因为A的源码不是有效的JavaScript脚本,'\n'是转义字符,你这里把它当文本用了。

你也许该先看看 https://github.com/tindy2013/subconverter/issues/697

jacobin avatar Jan 21 '24 03:01 jacobin

@jacobin

应该用结果B,因为A的源码不是有效的JavaScript脚本,'\n'是转义字符,你这里把它当文本用了。

你也许该先看看 #697

ini和url的转义规则不一样,url里面只会按uri encoding的规则解析的,另外你那个issue,显然两者都是对的,请按需使用。

lonelam avatar Jan 21 '24 08:01 lonelam

@jacobin

应该用结果B,因为A的源码不是有效的JavaScript脚本,'\n'是转义字符,你这里把它当文本用了。

你也许该先看看 #697

ini和url的转义规则不一样,url里面只会按uri encoding的规则解析的,另外你那个issue,显然两者都是对的,请按需使用。

对filter_script的使用,有两种情形,

  1. 是直接在地址行上将『脚本/jScript内容』进行『url编码』后代入XXXXXX,如本话题所举例子;
  2. 在地址行上指定脚本文件,譬如/etc/subconverter/myPref.ini,亦即,把/etc/subconverter/myPref.ini代入XXXXXX。

我这里不提第2种情况,就单指1,所以,这里不存在“ini和url的转义规则不一样”此类问题,你高人过虑了。我当然知道之所以引入譬如\n的转义是因为ini文件的key=VALUE只能占有一行。

迷花渐入迷人眼,概括我提出的本话题其实就一句话:在地址行直接插入的代码(/不是代码文件),用A还是B?

展开来说,1和2两种情形,我窃认为是要统一风格和机制的,『情形1的地址行中的XXXXXX』和 『情形2ini文件中的VALUE』必须统一做派。

太乱了

jacobin avatar Jan 24 '24 11:01 jacobin

还有,我认为在ini文件中的(key/)filter_script的value用『分号;』作为代码的一部分也是问题很严重的。在周知的『ini解析器』(/备注:往后简称INIer)里,分号是注释的开始,INIer会把『作为value的js中第一个分号开始的后面的全部』予以忽略。

譬如在https://github.com/tindy2013/subconverter/blob/master/base/pref.example.ini 中

;Enable script support for filtering nodes
enable_filter=true
;Script used for filtering nodes. Supports inline script and script path. A "filter" function with 1 argument which is a node should be defined in the script.
;Example: Inline script: Set value to content of script. Replace all line break with "\n".
;         Script path: set value to "path:/path/to/script.js".
filter_script=function filter(node) {\n    const info = JSON.parse(node.ProxyInfo);\n    if(info.EncryptMethod.includes('chacha20'))\n        return true;\n    return false;\n}

其中的filter_script的值,就有好几个分号。大多数的INIer,会把第一个分号后的所有的代码都忽视而去,效果如下 filter_script=function filter(node) {\n const info = JSON.parse(node.ProxyInfo) 当然,做的比较严谨的INIer,实际上是把空格+分号亦即『\x20;』当成『行内注释』的开始,问题是,就算体贴至此,在分号之前留一个空格难道是很难出现的疏漏吗?绝大多数的使用者,他们到达不了这样缜密细致/虑及代码的水平。

jacobin avatar Jan 26 '24 09:01 jacobin