kdeui: fix possible out-of-bounds in KIconEffect::apply() methods

e.g. if KIconLoader::NoGroup (-1) is passed as group

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2023-05-21 23:53:28 +03:00
parent c2618febf9
commit 15252c920e

View file

@ -101,11 +101,10 @@ void KIconEffect::init()
QString _none("none"); QString _none("none");
QString _tomonochrome("tomonochrome"); QString _tomonochrome("tomonochrome");
for (it=groups.constBegin(), i=0; it!=groups.constEnd(); ++it, ++i) for (it = groups.constBegin(), i = 0; it != groups.constEnd(); ++it, ++i) {
{
// Default effects // Default effects
d->effect[i][0] = KIconEffect::NoEffect; d->effect[i][0] = KIconEffect::NoEffect;
d->effect[i][1] = ((i==0)||(i==4)) ? KIconEffect::ToGamma : KIconEffect::NoEffect; d->effect[i][1] = ((i==0 || i == 4) ? KIconEffect::ToGamma : KIconEffect::NoEffect);
d->effect[i][2] = KIconEffect::ToGray; d->effect[i][2] = KIconEffect::ToGray;
d->trans[i][0] = false; d->trans[i][0] = false;
@ -122,30 +121,30 @@ void KIconEffect::init()
d->color2[i][2] = QColor(0,0,0); d->color2[i][2] = QColor(0,0,0);
KConfigGroup cg(config, *it + "Icons"); KConfigGroup cg(config, *it + "Icons");
for (it2=states.constBegin(), j=0; it2!=states.constEnd(); ++it2, ++j) for (it2 = states.constBegin(), j = 0; it2 != states.constEnd(); ++it2, ++j) {
{
QString tmp = cg.readEntry(*it2 + "Effect", QString()); QString tmp = cg.readEntry(*it2 + "Effect", QString());
if (tmp == _togray) if (tmp == _togray) {
effect = KIconEffect::ToGray; effect = KIconEffect::ToGray;
else if (tmp == _colorize) } else if (tmp == _colorize) {
effect = KIconEffect::Colorize; effect = KIconEffect::Colorize;
else if (tmp == _desaturate) } else if (tmp == _desaturate) {
effect = KIconEffect::DeSaturate; effect = KIconEffect::DeSaturate;
else if (tmp == _togamma) } else if (tmp == _togamma) {
effect = KIconEffect::ToGamma; effect = KIconEffect::ToGamma;
else if (tmp == _tomonochrome) } else if (tmp == _tomonochrome) {
effect = KIconEffect::ToMonochrome; effect = KIconEffect::ToMonochrome;
else if (tmp == _none) } else if (tmp == _none) {
effect = KIconEffect::NoEffect; effect = KIconEffect::NoEffect;
else } else {
continue; continue;
if(effect != -1) }
if (effect != -1) {
d->effect[i][j] = effect; d->effect[i][j] = effect;
}
d->value[i][j] = cg.readEntry(*it2 + "Value", 0.0); d->value[i][j] = cg.readEntry(*it2 + "Value", 0.0);
d->color[i][j] = cg.readEntry(*it2 + "Color", QColor()); d->color[i][j] = cg.readEntry(*it2 + "Color", QColor());
d->color2[i][j] = cg.readEntry(*it2 + "Color2", QColor()); d->color2[i][j] = cg.readEntry(*it2 + "Color2", QColor());
d->trans[i][j] = cg.readEntry(*it2 + "SemiTransparent", false); d->trans[i][j] = cg.readEntry(*it2 + "SemiTransparent", false);
} }
} }
} }
@ -192,12 +191,12 @@ QString KIconEffect::fingerprint(int group, int state) const
QImage KIconEffect::apply(const QImage &image, int group, int state) const QImage KIconEffect::apply(const QImage &image, int group, int state) const
{ {
if (state >= KIconLoader::LastState) { if (group < 0 || group >= KIconLoader::LastGroup) {
kDebug(265) << "Illegal icon state: " << state << "\n"; kDebug(265) << "Illegal icon group: " << group;
return image; return image;
} }
if (group >= KIconLoader::LastGroup) { if (state >= KIconLoader::LastState) {
kDebug(265) << "Illegal icon group: " << group << "\n"; kDebug(265) << "Illegal icon state: " << state;
return image; return image;
} }
@ -223,7 +222,7 @@ QImage KIconEffect::apply(const QImage &img, int effect, float value,
const QColor &col, const QColor &col2, bool trans) const QColor &col, const QColor &col2, bool trans)
{ {
if (effect >= KIconEffect::LastEffect) { if (effect >= KIconEffect::LastEffect) {
kDebug(265) << "Illegal icon effect: " << effect << "\n"; kDebug(265) << "Illegal icon effect:" << effect;
return img; return img;
} }
@ -264,12 +263,12 @@ QImage KIconEffect::apply(const QImage &img, int effect, float value,
QPixmap KIconEffect::apply(const QPixmap &pixmap, int group, int state) const QPixmap KIconEffect::apply(const QPixmap &pixmap, int group, int state) const
{ {
if (state >= KIconLoader::LastState) { if (group < 0 || group >= KIconLoader::LastGroup) {
kDebug(265) << "Illegal icon state: " << state << "\n"; kDebug(265) << "Illegal icon group: " << group;
return pixmap; return pixmap;
} }
if (group >= KIconLoader::LastGroup) { if (state >= KIconLoader::LastState) {
kDebug(265) << "Illegal icon group: " << group << "\n"; kDebug(265) << "Illegal icon state: " << state;
return pixmap; return pixmap;
} }
@ -294,16 +293,16 @@ QPixmap KIconEffect::apply(const QPixmap &pixmap, int effect, float value,
QPixmap KIconEffect::apply(const QPixmap &pixmap, int effect, float value, QPixmap KIconEffect::apply(const QPixmap &pixmap, int effect, float value,
const QColor &col, const QColor &col2, bool trans) const QColor &col, const QColor &col2, bool trans)
{ {
if (effect >= LastEffect) { if (effect >= KIconEffect::LastEffect) {
kDebug(265) << "Illegal icon effect: " << effect << "\n"; kDebug(265) << "Illegal icon effect:" << effect;
return pixmap; return pixmap;
} }
QPixmap result; QPixmap result;
if ((trans == true) && (effect == NoEffect)) { if (trans == true && effect == KIconEffect::NoEffect) {
result = pixmap; result = pixmap;
semiTransparent(result); semiTransparent(result);
} else if ( effect != NoEffect) { } else if (effect != KIconEffect::NoEffect) {
QImage tmpImg = pixmap.toImage(); QImage tmpImg = pixmap.toImage();
tmpImg = apply(tmpImg, effect, value, col, col2, trans); tmpImg = apply(tmpImg, effect, value, col, col2, trans);
result = QPixmap::fromImage(tmpImg); result = QPixmap::fromImage(tmpImg);
@ -322,8 +321,7 @@ struct KIEImgEdit
KIEImgEdit(QImage& _img):img(_img) KIEImgEdit(QImage& _img):img(_img)
{ {
if (img.depth() > 8) if (img.depth() > 8) {
{
//Code using data and pixels assumes that the pixels are stored //Code using data and pixels assumes that the pixels are stored
//in 32bit values and that the image is not premultiplied //in 32bit values and that the image is not premultiplied
if ((img.format() != QImage::Format_ARGB32) && if ((img.format() != QImage::Format_ARGB32) &&
@ -333,9 +331,7 @@ struct KIEImgEdit
} }
data = (unsigned int*)img.bits(); data = (unsigned int*)img.bits();
pixels = img.width()*img.height(); pixels = img.width()*img.height();
} } else {
else
{
pixels = img.colorCount(); pixels = img.colorCount();
colors = img.colorTable(); colors = img.colorTable();
data = (unsigned int*)colors.data(); data = (unsigned int*)colors.data();
@ -344,9 +340,10 @@ struct KIEImgEdit
~KIEImgEdit() ~KIEImgEdit()
{ {
if (img.depth() == 1) if (img.depth() == 1) {
img.setColorTable(colors); img.setColorTable(colors);
} }
}
}; };
static bool painterSupportsAntialiasing() static bool painterSupportsAntialiasing()
@ -584,12 +581,13 @@ void KIconEffect::semiTransparent(QImage &img)
for (y = 0; y < img.height(); ++y){ for (y = 0; y < img.height(); ++y){
line = img.scanLine(y); line = img.scanLine(y);
for (x = (y%2); x < img.width(); x += 2) { for (x = (y%2); x < img.width(); x += 2) {
if(!setOn) if (!setOn) {
*(line + (x >> 3)) &= ~(1 << (x & 7)); *(line + (x >> 3)) &= ~(1 << (x & 7));
else } else {
*(line + (x >> 3)) |= (1 << (x & 7)); *(line + (x >> 3)) |= (1 << (x & 7));
} }
} }
}
} else { } else {
for(y = 0; y < img.height(); ++y) { for(y = 0; y < img.height(); ++y) {
line = img.scanLine(y); line = img.scanLine(y);
@ -635,11 +633,11 @@ void KIconEffect::semiTransparent(QPixmap &pix)
void KIconEffect::overlay(QImage &src, QImage &overlay) void KIconEffect::overlay(QImage &src, QImage &overlay)
{ {
if (src.depth() != overlay.depth()) { if (src.depth() != overlay.depth()) {
kDebug(265) << "Image depth src (" << src.depth() << ") != overlay " << "(" << overlay.depth() << ")!\n"; kDebug(265) << "Image depth src (" << src.depth() << ") != overlay " << "(" << overlay.depth() << ")!";
return; return;
} }
if (src.size() != overlay.size()) { if (src.size() != overlay.size()) {
kDebug(265) << "Image size src != overlay\n"; kDebug(265) << "Image size src != overlay";
return; return;
} }
@ -648,7 +646,7 @@ void KIconEffect::overlay(QImage &src, QImage &overlay)
} }
if (overlay.format() == QImage::Format_RGB32) { if (overlay.format() == QImage::Format_RGB32) {
kDebug(265) << "Overlay doesn't have alpha buffer!\n"; kDebug(265) << "Overlay doesn't have alpha buffer!";
return; return;
} else if (overlay.format() == QImage::Format_ARGB32_Premultiplied) { } else if (overlay.format() == QImage::Format_ARGB32_Premultiplied) {
overlay = overlay.convertToFormat(QImage::Format_ARGB32); overlay = overlay.convertToFormat(QImage::Format_ARGB32);
@ -656,7 +654,7 @@ void KIconEffect::overlay(QImage &src, QImage &overlay)
// We don't do 1 bpp // We don't do 1 bpp
if (src.depth() == 1) { if (src.depth() == 1) {
kDebug(265) << "1bpp not supported!\n"; kDebug(265) << "1bpp not supported!";
return; return;
} }
@ -784,8 +782,9 @@ inline static void blurHorizontal(QImage &image, unsigned int *stack, int div, i
sum -= sum_out; sum -= sum_out;
stackstart = stackindex + div - radius; stackstart = stackindex + div - radius;
if (stackstart >= div) if (stackstart >= div) {
stackstart -= div; stackstart -= div;
}
unsigned int *stackpix = &stack[stackstart]; unsigned int *stackpix = &stack[stackstart];
@ -798,8 +797,9 @@ inline static void blurHorizontal(QImage &image, unsigned int *stack, int div, i
sum_in += *stackpix; sum_in += *stackpix;
sum += sum_in; sum += sum_in;
if (++stackindex >= div) if (++stackindex >= div) {
stackindex = 0; stackindex = 0;
}
stackpix = &stack[stackindex]; stackpix = &stack[stackindex];
@ -856,8 +856,9 @@ inline static void blurVertical(QImage &image, unsigned int *stack, int div, int
sum -= sum_out; sum -= sum_out;
stackstart = stackindex + div - radius; stackstart = stackindex + div - radius;
if (stackstart >= div) if (stackstart >= div) {
stackstart -= div; stackstart -= div;
}
unsigned int *stackpix = &stack[stackstart]; unsigned int *stackpix = &stack[stackstart];
@ -870,8 +871,9 @@ inline static void blurVertical(QImage &image, unsigned int *stack, int div, int
sum_in += *stackpix; sum_in += *stackpix;
sum += sum_in; sum += sum_in;
if (++stackindex >= div) if (++stackindex >= div) {
stackindex = 0; stackindex = 0;
}
stackpix = &stack[stackindex]; stackpix = &stack[stackindex];