Open stszap opened 2 years ago
Hi,
I stumbled across the same issue. However if you look at the CSS sample you provided you see two CSS violations:
Therefore the CSS parser "mensch" used here is producing an invalid AST (as it claims it is not validating the CSS).
This invalid AST leads then to a property access in the inline.js line 205. There ".snippet" is interpretetd as css property without value. The var value, with undefined, is accessed with '.match(...' which leads to the crash.
Solution propsals:
Hello. You are absolutely right the email I provided has broken CSS. I should have mentioned it in the beginning but unfortunately, we can't control all the emails that we get. It's a kind of public service and anybody can send one. But we would like juice not to crash at least. I added the following hack back then
import juice from 'juice';
// monkey patch to fix juice crash when trying to use element without "value"
// https://github.com/Automattic/juice/issues/398
let parseCSS = juice.utils.parseCSS
juice.utils.parseCSS = function (css) {
let ret = parseCSS.apply(juice.utils, [css])
for (let i in ret) {
let declaractions = ret[i][1]
if (declaractions && declaractions.length) {
declaractions = declaractions.filter(elem => elem && elem.value !== undefined)
}
ret[i][1] = declaractions
}
return ret
}
It's ugly but after 2 months we haven't found any issues with it.
Hello. You are absolutely right the email I provided has broken CSS. I should have mentioned it in the beginning but unfortunately, we can't control all the emails that we get. It's a kind of public service and anybody can send one. But we would like juice not to crash at least. I added the following hack back then
import juice from 'juice'; // monkey patch to fix juice crash when trying to use element without "value" // https://github.com/Automattic/juice/issues/398 let parseCSS = juice.utils.parseCSS juice.utils.parseCSS = function (css) { let ret = parseCSS.apply(juice.utils, [css]) for (i in ret) { let declaractions = ret[i][1] if (declaractions && declaractions.length) { declaractions = declaractions.filter(elem => elem && elem.value !== undefined) } ret[i][1] = declaractions } return ret }
It's ugly but after 2 months we haven't found any issues with it.
Hi, I meet the same issue, juice crash but there's no error, and the callback is never called. I tried to use your solution but it not work.
Hi, I meet the same issue, juice crash but there's no error, and the callback is never called. I tried to use your solution but it not work.
I rechecked the code and found an error (i in ret
instead of let i in ret
in the loop), sorry for that. If that still doesn't fix the problem for you then I'm not sure I can help. It's just a very crude "solution" so it may not fix all the problems that cause unhandled exceptions.
thanks. I found the exception is caused by the inifinite loop when the css includes :not()
function, parse it will return a wrong selector. And I hack the parseCSS
to skip the wrong selector refer to yours.
The issue of inifinite loop: #390
Hello, we use juice to parse incoming emails and recently we got an email that causes juice to crash without any chance to catch the error. We narrowed it down to a simple example that gives the following error:
The callback is never called and try/catch can't catch the error either. The code to reproduce:
node: v14.18.1 juice: 8.0.0