hiccLoghicc log by wccHipo日志

记一次开源贡献

toc

Intro

说来惭愧,工作这么久一直是伸手党,最近解决工作中突发 bug,才有机会第一次参与开源组件的贡献。

事情经过比较简单,升级开源组件marked到 最新 13 版本之后,突然线上收到了"Maximum call stack size exceeded"的错误日志,废了一点时间才发现是作者为了兼容老的行为,不小心引入了一种类似递归爆栈的 bug。比较难复现,兼容写法,累积执行很多次才会报错。

const marked = require('marked') const content = '\n## 1. some title\n\nsimple content' marked.use({ renderer: { heading(text, level) { const escapedText = encodeURIComponent(text).replaceAll('%', '.'); return `<h${level} id="${escapedText}"> ${text} </h${level}>`; }, }, }); for (const _ of new Array(10000).fill(0)) { marked.parse(content); }

定位到了 bug,提了 issue 就下班了。。。

回去洗完澡觉得既然已经发现问题了,应该直接帮忙修复呀,第二天才修复完提交了 pull request,review 一次,再次修复就算过了。也算对这个行当做了点小小贡献。

最终发布 V13.0.3 版本。


最后,错误大致是类似下面的写法导致的,大家可以发现么?哈哈(≧ω≦)

const marked = { renderer:{}, use({renderer}){ let renderFun = renderer.heading; this.renderer.heading = (...args) => { renderFun = this.convertRendererFunction(renderer.heading) return renderFun.apply(renderer,args) } }, convertRendererFunction(func) { return (token) => func.call(this, token) }, parse(txt) { return this.renderer.heading(txt) } } marked.use({ renderer:{ heading(text) { return text + 1 } } }); for (const _ of new Array(1000000).fill(0)) { try { marked.parse('11') } catch(e) { console.log(e) } }