时溢

来自Limbo Wiki
欢迎您参与完善本页面~
欢迎正在阅读这个条目的您协助编辑本页面以做出您的改进。编辑前请先阅读入门指南,并了解像素塔基本设定。
林泊百科祝您在像素塔度过愉快的时光。
诈骗条目
本条目仅出于幽默感而保留。
认真你就输了!


“时溢”是一个■■■底层的程序漏洞,表现为错误时间日期输入下的算法异常。

简介

“时溢”是一个有关底层time库和random库的漏洞。

当尝试向time库中的类Datetime传入超出范围的日期(例如:3月32日、5月-29日,4月-365日等),仍然可以在不报错的情况下产生Datetime对象,并且该Datetime对象的所有方法均可正常使用。但是,若将异常对象传入random库的部分函数,则超限的时间会引起随机数生成异常,并可能导致一些使用随机效果的程序出现错误。

原理猜想

Datetime类用于表示日期时间,其构造函数参数列表如下

Datetime::Datetime(long year, int month, int day, int hour, int minute, int second, long microsecond) {}

猜测其可能使用了快速初始化之类的方案,如:

Datetime::Datetime(long year, int month, int day, int hour, int minute, int second, long microsecond):year(year), month(month), day(day), hour(hour), minute(minute), second(second), microsecond(microsecond) {}

因此,非法的日期和时间未被过滤。

解析像素塔回收的底层数据,研究者在大量垃圾数据中过滤出一些代码,部分证实了上方的猜想。

同时,研究者还发现了其它有趣之处,例如:

Datetime的另一个成员方法,toTimeStamp()的函数定义大致如下:(注释为笔者所加)

// 全局变量区
int daysM[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // 注意开头的零定义,似乎是为了方便直接用月份
int daysT[] = {0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
// end

unsigned long long Datetime::toTimeStamp(){
    unsigned long long static ts, ye;
    ts = 0;
    // 更新记录中显示,下面的ye、month / 12和%12是一次bugfix,似乎是计时器外设TIM的问题导致月份在某些条件下可能为13,于是做了这个更改
    // 因此month不再产生越界问题(Segment Fault),这导致时溢问题变得更加隐蔽
    ye = year + floor(month / 12);
    ts += ye * 31536000 + 86400 * floor(ye / 4 - 3 * ye / 400);
    ts += daysT[month%13] * 86400;
    ts += day * 86400;
    ts += hour * 3600 + minute * 60 + second;
}

笔者缺乏完整的设备,不知道外设TIM的问题是否已经解决。但是恢复数据显示上方代码之后就未被修改过,毕竟没有人愿意去碰一堆屎山代码。

上方代码的有趣之处在于它能将非法的Datetime转换成合法的时间戳,例如764年-3月将产生763年9月的时间戳,进一步隐藏了时溢的错误源头。