Fix abort in files with broken Decode arrays

Fixes KDE bug #379835
diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index 2c81dfb..b17925f 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -5311,24 +5311,30 @@
   obj1.free();
   if (dict->lookup("Decode", &obj1)->isArray() &&
       obj1.arrayGetLength() >= 6) {
-    xMin = obj1.arrayGet(0, &obj2)->getNum();
+    bool decodeOk = true;
+    xMin = obj1.arrayGet(0, &obj2)->getNum(&decodeOk);
     obj2.free();
-    xMax = obj1.arrayGet(1, &obj2)->getNum();
+    xMax = obj1.arrayGet(1, &obj2)->getNum(&decodeOk);
     obj2.free();
     xMul = (xMax - xMin) / (pow(2.0, coordBits) - 1);
-    yMin = obj1.arrayGet(2, &obj2)->getNum();
+    yMin = obj1.arrayGet(2, &obj2)->getNum(&decodeOk);
     obj2.free();
-    yMax = obj1.arrayGet(3, &obj2)->getNum();
+    yMax = obj1.arrayGet(3, &obj2)->getNum(&decodeOk);
     obj2.free();
     yMul = (yMax - yMin) / (pow(2.0, coordBits) - 1);
     for (i = 0; 5 + 2*i < obj1.arrayGetLength() && i < gfxColorMaxComps; ++i) {
-      cMin[i] = obj1.arrayGet(4 + 2*i, &obj2)->getNum();
+      cMin[i] = obj1.arrayGet(4 + 2*i, &obj2)->getNum(&decodeOk);
       obj2.free();
-      cMax[i] = obj1.arrayGet(5 + 2*i, &obj2)->getNum();
+      cMax[i] = obj1.arrayGet(5 + 2*i, &obj2)->getNum(&decodeOk);
       obj2.free();
       cMul[i] = (cMax[i] - cMin[i]) / (double)((1 << compBits) - 1);
     }
     nComps = i;
+
+    if (!decodeOk) {
+      error(errSyntaxWarning, -1, "Missing or invalid Decode array in shading dictionary");
+      goto err2;
+    }
   } else {
     error(errSyntaxWarning, -1, "Missing or invalid Decode array in shading dictionary");
     goto err2;
diff --git a/poppler/Object.h b/poppler/Object.h
index e3f8f37..e55ba68 100644
--- a/poppler/Object.h
+++ b/poppler/Object.h
@@ -208,6 +208,13 @@
   // Where the exact value of integers up to 2^63 is required, use isInt64()/getInt64().
   double getNum() { OBJECT_3TYPES_CHECK(objInt, objInt64, objReal);
     return type == objInt ? (double)intg : type == objInt64 ? (double)int64g : real; }
+  double getNum(bool *ok) {
+    if (unlikely(type != objInt && type != objInt64 && type != objReal)) {
+      *ok = false;
+      return 0.;
+    }
+    return type == objInt ? (double)intg : type == objInt64 ? (double)int64g : real;
+  }
   GooString *getString() { OBJECT_TYPE_CHECK(objString); return string; }
   // After takeString() the only method that should be called for the object is free()
   // because the object it's not expected to have a NULL string.