LinusU / decode-ico

Decode `.ico` icons
20 stars 2 forks source link

Handle png files masquerading as ico #2

Closed kchapelier closed 1 year ago

kchapelier commented 5 years ago

This PR allows the module to transparently support png files masquerading as ico files (issue reported here : https://github.com/LinusU/decode-ico/issues/1 ), although as discussed in the issue whether this case should be handled by the module is questionable. Two of the example files have been added to the test suite.

LeCoupa commented 4 years ago

Can we merge this? I also get the same issue.

LinusU commented 4 years ago

@LeCoupa thanks for the bump, I must have missed this. Will try to look at it this weekend 👍

LeCoupa commented 4 years ago

Thank you @LinusU :) If you need someone to test, I will be happy to help you.

kchapelier commented 4 years ago

From the look of it, even though the PR was based on the 0.3.1 version it should work as intended in the 0.4.0 version. Let me know if anything is amiss.

gregnr commented 1 year ago

@LinusU Any chance we can get this merged? I'm coming across the same issue. Right now I have to manually check for PNG myself - merging this would be a cleaner solution.

LinusU commented 1 year ago

Sorry for the huge delay in getting this merged!

This is now released as 🚢 0.4.1 / 2022-11-15

Thanks for the PR 🙏

terchris commented 1 year ago

Hi Thanks for the code. I have found another favicon.ico that results in the error message: 'Invalid magic bytes' In line 51:11 if (view.getUint16(0, true) !== 0) { throw new Error('Invalid magic bytes') }

I'm using the 0.4.1 version.

This is the favicon.ico as base64 R0lGODlhsAGwAfcAAIlVI51aHqpmLbRsJX1LIu6QM/+vP1QzE6RkLP6WOe+NMt2FLP+lPf+fO7lu LWQ9HfqWNcJyLf2XNfWSMEcqDbFrLv+jNjIdC+GHMv+yPf+gNysaDP+cNv+tOPOSM/qWO/+eNq9q Lv+hPYBKGdV/Kt6GOLRwJUMnDG1CGR0RB96CKv+vO+aKOdF7KFUyD+qKLf+wOq1lJqBhKv+iNdqD NSUWCUQpEv+sQf+rNth+K4NRHqdmIlg1ExkOBP+aOtF9Kv+sNuGHLXZIGq5pJggFBM55LYRSKKNm JvyYNeeLLv+oN105Gv+aNoRRJsp2LQYDADUgDf+kOu2OL5laHv+ePf+eOSETB/+cOsp7NTcjEq9o KM95KBUMBaliI/+mOFU0G8Z2MdZ9LEEnEbVsLcl1K/+uOQoEAf+oOlEvD5VdI9mCK/+gM/+YNfOS OhEJBb50MZ5fKRIKAgsLC2Q7FN+EK51dJQ0HAWpCIAMBAD8kCxcMAw8IA/+aMzghCxgPCBQKBP+p OJdYHRULAv+fNdiBK/+eNf+lN/+mN/+oODwjCk0tDr1xKP+cM/+rOXdHIf+YM/+bM/+bNP+cNP+d NP+gNf+bMv+YMv+fNP+eM/+dM/+gNM13Kf+qOP+eNP+dNv+aNP+aMhUVFf+rOP+aNf+bNgkJCf+h NOKFK+SILv2YM/+ZMv+XMuKELv+qOf6ZM/+cMv+cNf+lNuOILtmAKs58NgYEA5ZbKzwkED8kD/+n NpNWHOyLL5VaJ/+jQEorD0otDqtmIaJfJE8uDqhpIvaSOPeUOf2aNZNaIpZYHRMMB4xRG9uAKdR7 KdmBK5FXI9d/MTojD/qVMlAvFPCPMP+9QP+nOP+tPP+rPP6YM7huJPaUM39OJr92J/+mOvOTM4FN GrxzLuyOO/6aNPuYOv6aNeOHLKpkJ7FsLbduKg0HBmw/Ff+hNuuNMOaKMaBkJf+kOP+qOr93KP+h O51bHsZ0LOaILKpqJvCPL92BLcRzKblsKJVgJch5MZFcI/+ZMwAAACH/C1hNUCBEYXRhWE1QPD94 cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1w bWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgOS4w LWMwMDEgNzkuMTRlY2I0MmYyYywgMjAyMy8wMS8xMy0xMjoyNTo0NCAgICAgICAgIj4gPHJkZjpS REYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMj Ij4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRv YmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4w L21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNv dXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDI0LjIgKFdpbmRvd3Mp IiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjhBQzk2RDA3QjY4MzExRURCMEQ2RUUyOEZDQUQ4 RUEyIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjhBQzk2RDA4QjY4MzExRURCMEQ2RUUyOEZD QUQ4RUEyIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6OEFD OTZEMDVCNjgzMTFFREIwRDZFRTI4RkNBRDhFQTIiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6 OEFDOTZEMDZCNjgzMTFFREIwRDZFRTI4RkNBRDhFQTIiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwv cmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4B//79/Pv6+fj39vX08/Lx 8O/u7ezr6uno5+bl5OPi4eDf3t3c29rZ2NfW1dTT0tHQz87NzMvKycjHxsXEw8LBwL++vby7urm4 t7a1tLOysbCvrq2sq6qpqKempaSjoqGgn56dnJuamZiXlpWUk5KRkI+OjYyLiomIh4aFhIOCgYB/ fn18e3p5eHd2dXRzcnFwb25tbGtqaWhnZmVkY2JhYF9eXVxbWllYV1ZVVFNSUVBPTk1MS0pJSEdG RURDQkFAPz49PDs6OTg3NjU0MzIxMC8uLSwrKikoJyYlJCMiISAfHh0cGxoZGBcWFRQTEhEQDw4N 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 Ow==

LinusU commented 1 year ago

@terchris that is a GIF-image, and I'm not sure if that is within the scope of this project. Since ico files can already contain PNG data it was (as can be seen in this PR) easy and straight forward to add png support.

If we add support for gif, then do we also add support for jpeg? And webp? And any other image format? Then this library isn't really a "decode ico" library anymore...

In fact, I'm starting to question if adding support for plain PNG files was the right move 😅

Happy to get some input!

kchapelier commented 1 year ago

To some extent, it made sense to support PNG files as all the required dependencies were already in place and PNG files are quite often erroneously used as ".ico" favicons... A sad state of affairs.

Personally, I think the best thing this module might do is maybe to have more explicit error messages for those who are not used to deal with binary data. Like replacing "Invalid magic bytes" with "Invalid magic bytes, the provided file is not a valid .ico file". As a best-effort, the module could maybe output specific error messages for magic bytes corresponding to the most popular image file formats ("Invalid magic bytes, the provided file is not a valid .ico file, it appears to be a .gif file instead"). I'm talking about only checking the first 4 bytes, not doing a whole format header validation or even a more complete magic byte validation.

LinusU commented 1 year ago

@kchapelier @LeCoupa @gregnr @terchris do you think that @canvas/image would suit your needs better? I've just opened a pull request that adds support for ICO files (https://github.com/node-gfx/image/pull/2), and apart from that it already supports bmp, gif, jpeg, png, and webp.

edit after reading your last message: Hmm, that is certainly an interesting take, and I'm not opposed to it. However, I feel that maybe this library should focus on being more a low level library and instead steer people towards e.g. @canvas/image to get a more high level easy to use library 🤔