热烈欢迎我们赶赴百度云+街道社区,以获取更多百度海量数据技术课堂教学蔬果哦~
责任编辑由
QQ终端产品开发项目组项目组发布在百度云+街道社区
序言
相信我们都碰到过几段特殊文档能让iOS设备大部份app维托县的经历。前几日除夕夜,又再次出现某一印地语字符串引发iOS11控制系统云讷。幸好QQ应用程序做了为保护并没引发太大难题。一般而言,转义维托县是控制电脑病毒引发,只要预览控制系统xml。但大部分使用者不愿意预览控制系统,而苹果公司也不一定第一时间解决难题。另外前台能截击蓄意文档传达,但对于邻近地区已印发的最新消息,前台没办法让它删掉。因此应用程序还是要做些为保护防治转义维托县。
方案
由于难以预先知道数组里包涵转义,因此只能先让它排印/绘出,看一看与否再次出现难题。作法是,在排印/绘出数组前,先增设记号位,排印/绘出结束后,去除记号位;一旦发现记号位存在,就意味着这数组可能有难题,到时候就不表明这个数组:
这里有几个难题:
有可能在排印/绘出过程中,其他缓存crash,导致记号位不能正常去除。因此crash时要推论crash缓存与否为排印/绘出缓存。究竟crash无数次才能推论这数组是有难题的。最早作法是crash一次就间接过滤,但很多使用者意见反馈,说某些挚友绰号难以表明。其实iOS绘出数组时也会很少机率再次出现维托县,从而错判。但crash三次才过滤不然,如果使用者已连续接到N条蓄意最新消息,那么至少crash 2N次才全盘把大部份有难题最新消息过滤。因此,第一次数组crash先不过滤,先期已连续数组crash不然,间接过滤。这样crash N+1次就能处理完了。
整个方法论标识符大体如下表所示:
// MessageItemView.mm, CP是CrashProtected的简称
@implementation MessageItemView
– (void)initContentLabel {
m_label = [[MMCPLabel alloc] init];
m_label.cpKey = [MMCPUtil generateKeyWithObject:self.messageModel];
if ([MMCPUtil isUnsafeWithKey:m_label.cpKey]) {
// 检验出messageModel最新消息文本有难题,过滤表明
m_label.text = @”该文本难以表明”;
} else {
m_label.text = self.messageModel.content;
}
}
@end
// MMCPLabel.mm
@implementation MMCPLabel
@synthesize cpKey = m_cpKey;
// 对常见的排印/绘出USB做检查
– (void)layoutSublayersOfLayer:(CALayer *)layer {
CScopedCrashCounter crashCounter(m_cpKey);
[super layoutSublayersOfLayer:layer];
}
– (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
CScopedCrashCounter crashCounter(m_cpKey);
[super drawLayer:layer inContext:ctx];
}
– (CGSize)sizeThatFits:(CGSize)size {
CScopedCrashCounter crashCounter(m_cpKey);
return [super sizeThatFits:size];
}
@end
// MMCPUtil.mm
// 利用C++特性,在声明C++类临时变量时,会自动执行构造函数,离开作用域会执行析构函数
// 因此构造函数做crashCount+1,析构函数做crashCount-1
class CScopedCrashCounter {
public:
CScopedCrashCounter(NSString *cpKey) {
m_cpKey = cpKey;
[MMCPUtil increaseCrashCountWithKey:m_cpKey];
}
~CScopedCrashCounter() {
[MMCPUtil decreaseCrashCountWithKey:m_cpKey];
}
private:
NSString *m_cpKey;
};
@implementation MMCPUtil
@synthesize crashKeyMemoryMappedKV = m_crashKeyMemoryMappedKV; // 被判定为蓄意信息对应的key
@synthesize crashCountMemoryMappedKV = m_crashCountMemoryMappedKV; // 每个key crash次数
– (BOOL)isUnsafeWithKey:(NSString *)key {
return [m_crashKeyMemoryMappedKV getBoolForKey:key] == YES;
}
– (void)increaseCrashCountWithKey:(NSString *)key {
// 这里记录key所在缓存
…
int32_t count = [m_crashCountMemoryMappedKV getInt32ForKey:key];
[m_crashCountMemoryMappedKV setInt32:count + 1 forKey:key]
}
– (void)decreaseCrashCountWithKey:(NSString *)key {
int32_t count = [m_crashCountMemoryMappedKV getInt32ForKey:key];
[m_crashCountMemoryMappedKV setInt32:MAX(0, count – 1) forKey:key];
}
// crash回调函数
– (void)onSignalCrash:(siginfo_t *)info {
// 先找到跟crash缓存相同的key
NSString *key = [self lastCPKey:info->si_pid];
if (key == nil) return;
if (m_isLastTimeCrashedBySpecialCharacter == NO) {
// 增设当前是转义引发的维托县,如果crash次数大于1,则过滤这数组表明
[self setLastTimeCrashedBySpecialCharacter:YES];
if ([m_crashCountMemoryMappedKV getInt32ForKey:key] > 1) {
[m_crashKeyMemoryMappedKV setBool:YES forKey:key];
}
} else {
// 已连续转义维托县,间接过滤
[m_crashKeyMemoryMappedKV setBool:YES forKey:key];
}
}
@end
即使有了上面的N+1优化,当N很大时,应用程序还是要crash很多次才能正常使用。之前有使用者乱扫二维码被拉进炸群,如果不发红包,群主不停炸群;使用者频繁crash,也难以退群。不少使用者会选择卸载重装应用程序。因此应用程序要加上安全模式的机制。当应用程序检验出已连续三次crash,到时候启动会再次出现安全模式的界面,提示使用者如何处理:
对于频繁维托县的群聊,主界面提供快捷入口方便使用者退群。另外对于可能错判的数组,界面也提供入口方便使用者恢复数组表明:
为了让前台第一时间发现新的转义变种,应用程序检验出转义crash后,会把相关信息上报到前台。通过应用程序上报、前台截击的闭环,能大大降低转义传播范围。这方案不仅用于转义,还能用于其他蓄意信息,如炸群最新消息、GIF、小视频、链接等。
MemoryMappedKV
由于需要埋点的地方太多了,绰号、最新消息文本、头像等等,为了不影响滑动性能,guoling同学开发了一套基于mmap的高性能通用key-value存储组件,敬请留意云+街道社区先期文章。
问答
如何看待QQ小程序开放插件功能?更多相关的
精华问答,尽在百度云+街道社区!
相关阅读
谈谈编程程序员字典:「牛逼」码云推荐 | Symphony 街道社区平台的QQ小程序
此文已由作者授权百度云+街道社区发布,转载请注明文章出处
原文链接:https://cloud.tencent.com/developer/article/1066209
本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 290004051@qq.com 举报,一经查实,本站将立刻删除。
如若转载,请注明出处:https://www.wuctw.com/15620.html