Fix imported VLESS Reality nodes with null short-id#30
Open
hmtdpetn wants to merge 1 commit into
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
中文说明
问题说明
这个 PR 修复了一类会导致导入后的 VLESS Reality 节点完全无法使用的问题。
部分 Clash 订阅中的 VLESS Reality 节点可能包含:
Clash YAML 中的
null被解析为 Go 的nil后,原来的getMapString()会继续通过fmt.Sprint()将该值转换为字符串。对于 Go
nil,转换结果并不是空字符串,而是:因此,原来的代码可能生成以下无效 Xray 配置:
"<nil>"不是有效的 RealityshortId,Xray 会拒绝该配置。在实际使用中,受影响的节点会出现:
在本次实际测试使用的真实订阅中,所有受该字段影响的 VLESS Reality 节点都会出现上述问题,因此这不是单纯的配置显示错误,而是会直接导致节点不可用。
原因定位
问题不在 VLESS、Reality 或 Xray 本身,而是在 Clash 配置值转换过程中。
原来的
getMapString()只检查键是否存在:当键存在但值为真正的 Go
nil时,代码会继续执行兜底字符串转换,最终错误得到"<nil>"。修复方式
本次修改让
getMapString()同时处理不存在的键和真正的 Gonil:修复后,当 Clash Reality 的
short-id为null时:getMapString()返回空字符串;shortId;"shortId": "<nil>"。本次修改只处理真正的 Go
nil,不会改变用户明确填写的普通字符串:原有字符串、整数、浮点数和布尔值的转换行为也保持不变。
自动测试
新增两组回归测试。
第一组验证通用配置值转换:
nil返回空字符串;"null"、"nil"和"<nil>"保持原值;第二组模拟带有空 Reality
short-id的 VLESS 节点,并验证:streamSettings.security为reality;realitySettings正常存在;publicKey等有效字段得到保留;shortId键被完全省略;"<nil>"。同一组回归测试在官方原始
master上会失败:应用本次修复后,同一组测试通过。
测试结果:
go test -count=1 ./...在根包处失败,原因是当前源码目录没有生成frontend/dist:这是项目已有的前端嵌入构建前置条件,与本次后端修改无关。
真实订阅人工验证
我已经使用当前修复分支构建出的 Windows EXE,对一份此前存在问题的真实 Clash 订阅进行了端到端测试。
验证结果:
在本次实际测试使用的订阅中,所有受该问题影响的 VLESS Reality 节点均已恢复正常。
English Description
Problem
This PR fixes an issue that can make imported VLESS Reality nodes completely unusable.
Some Clash subscriptions contain VLESS Reality nodes with configurations such as:
After the YAML
nullvalue is decoded into a Gonil, the previous implementation ofgetMapString()continued to convert it throughfmt.Sprint().For a Go
nil, the resulting value is not an empty string, but the literal string:As a result, the generated Xray configuration could contain:
"<nil>"is not a valid RealityshortId, so Xray rejects the generated configuration.In practice, affected nodes can exhibit the following behavior:
In the real subscription used for this verification, every VLESS Reality node affected by this field showed the problem. This is therefore not merely a configuration-display issue; it directly prevents the affected nodes from working.
Root cause
The issue is not caused by VLESS, Reality, or Xray itself. It occurs while converting values from the parsed Clash configuration.
The previous
getMapString()implementation only checked whether the key existed:When the key existed but its value was a real Go
nil, the function continued to its fallback string conversion and incorrectly returned"<nil>".Fix
The updated implementation treats both a missing key and a real Go
nilas an empty value:With this change, when a Clash Reality
short-idisnull:getMapString()returns an empty string;shortId;"shortId": "<nil>".The change only handles real Go
nilvalues. It intentionally preserves explicitly supplied strings such as:Existing conversion behavior for strings, integers, floating-point values, and booleans is also preserved.
Automated tests
Two groups of regression tests were added.
The first group verifies generic configuration-value conversion:
nilreturns an empty string;"null","nil", and"<nil>"are preserved;The second group simulates a VLESS Reality node with a null
short-idand verifies that:streamSettings.securityisreality;realitySettingsis present;publicKeyare preserved;shortIdkey is completely omitted;"<nil>".The same regression tests fail against the original upstream
master:The tests pass after applying this fix.
Test results:
go test -count=1 ./...fails in the root package becausefrontend/disthas not been generated:This is an existing frontend embed build requirement and is unrelated to this backend change.
Manual verification with a real subscription
I built a Windows EXE from the current fix branch and completed end-to-end verification using a real Clash subscription that previously exhibited the issue.
Verification results:
In the real subscription used for this test, all VLESS Reality nodes affected by this issue were restored to normal operation.