Fre*_*ios 13 rust deobfuscation
一个pull请求已经与锈编译一个新的测试完成.它验证一个奇怪的行可以编译:
fn main() {
let val = !((|(..):(_,_),__@_|__)((&*"\\",'@')/**/,{})=={&[..=..][..];})//
;
assert!(!val);
}
Run Code Online (Sandbox Code Playgroud)
这条线到底做了什么?
Luk*_*odt 23
让我们分解吧!首先,我重新格式化了这条线,以增加"可读性".
let val = !(
(
|(..): (_, _), __@_| __
)(
(
&*"\\",
'@'
) /**/,
{}
)
==
{
&[..=..][..];
}
)//
;
Run Code Online (Sandbox Code Playgroud)
它始于let val =和结束//<newline>;.所以这是一个简单的绑定表单let val = ?v?;.我们来讨论一下?v?:
!( ?_? )
==: ?lhs? == ?rhs?
( ?closure? )( ?args? )
|?first_param?, ?second_param?| ?body?
(..): (_, _).此参数具有类型注释,(_, _)意味着它是2元组.模式(通常情况下,您会找到一个名称)是(..)指:元组,但忽略它的所有元素.__@_.这是一种通常从匹配绑定中获知的模式:name @ pattern.所以实际模式是_(它不绑定任何东西),并且值通过@名称绑定__(两个下划线,这是一种有效的标识符).__.这只是我们将第二个参数绑定到的标识符.所以封闭基本上相当于|_, x| x./**/:?first_arg?/**/, ?second_arg?
(&*"\\", '@').这只是一个2元组,其中第一个元素是包含反斜杠的字符串,第二个元素是char'@'.第&*一个元素取消了.{}.这是一个具有类型的空块().所以作为第二个论点,一个单位被传递.{ ?stmt?; }.请注意,这是一个带分号的语句.这意味着结果不会从块返回.而是块返回()就像空块一样{}.
{ &?collection?[?index?] }.
[..=..].这是一个包含一个元素的数组.的元件是..= ..其是RangeToInclusive其中end的范围内的是RangeFull写入......这只是RangeFull一次.总而言之:我们将调用闭包的结果与计算结果的支撑块进行比较().闭包基本上是|_, x| x,我们传递给它的第二个参数是{}(计算结果()),所以整个闭包调用表达式求值为().
这意味着整个事情相当于:
let val = !( () == () );,相当于:let val = !( true );,相当于:let val = false;