glassechidna / zxing-cpp

ZXing C++ Library
Apache License 2.0
598 stars 435 forks source link

GenericGFPoly::isZero() BAD_ACCESS crash #13

Open TimZaman opened 9 years ago

TimZaman commented 9 years ago

Yet another baby from my 5 million barcodes test..

Crashed Thread:        134  QThread

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000000000010

VM Regions Near 0x10:
--> 
    __TEXT                 000000010771e000-0000000107c16000 [ 5088K] r-x/rwx SM=COW  /Users/USER/Desktop/pixel_v2.205.app/Contents/MacOS/test

Thread 134 Crashed:: QThread
0   com.test            0x0000000107a240ca zxing::Array<int>::operator[](int) + 42
1   com.test            0x0000000107a2382f zxing::ArrayRef<int>::operator[](int) + 31
2   com.test            0x0000000107a297ee zxing::GenericGFPoly::isZero() + 30
3   com.test            0x0000000107a29a66 zxing::GenericGFPoly::addOrSubtract(zxing::Ref<zxing::GenericGFPoly>) + 198
4   com.test            0x0000000107a2c69d zxing::ReedSolomonDecoder::runEuclideanAlgorithm(zxing::Ref<zxing::GenericGFPoly>, zxing::Ref<zxing::GenericGFPoly>, int) + 1565
5   com.test            0x0000000107a2ba50 zxing::ReedSolomonDecoder::decode(zxing::ArrayRef<int>, int) + 992
6   com.test            0x0000000107a38bb2 zxing::datamatrix::Decoder::correctErrors(zxing::ArrayRef<char>, int) + 242
7   com.test            0x0000000107a390da zxing::datamatrix::Decoder::decode(zxing::Ref<zxing::BitMatrix>) + 954
8   com.test            0x0000000107a3032f zxing::datamatrix::DataMatrixReader::decode(zxing::Ref<zxing::BinaryBitmap>, zxing::DecodeHints) + 239
9   com.test            0x0000000107a5258a zxing::MultiFormatReader::decodeInternal(zxing::Ref<zxing::BinaryBitmap>) + 250
10  com.test            0x0000000107a52716 zxing::MultiFormatReader::decode(zxing::Ref<zxing::BinaryBitmap>, zxing::DecodeHints) + 118
11  com.test            0x0000000107995dd0 test::decode_image_barcode(cv::Mat const?, std::__1::vector<int, std::__1::allocator<int> >) + 1680
1

So this goes wrong in GenericGFPoly::isZero()

bool GenericGFPoly::isZero() {
  return coefficients_[0] == 0;
}

Which is called from

Ref<GenericGFPoly> GenericGFPoly::addOrSubtract(Ref<zxing::GenericGFPoly> other) {
  if (!(field_.object_ == other->field_.object_)) {
    throw IllegalArgumentException("GenericGFPolys do not have same GenericGF field");
  }
  if (isZero()) {
    return other;
  }
  if (other->isZero()) {
    return Ref<GenericGFPoly>(this);
  }

  ArrayRef<int> smallerCoefficients = coefficients_;
  ArrayRef<int> largerCoefficients = other->getCoefficients();
  if (smallerCoefficients.size() > largerCoefficients.size()) {
    ArrayRef<int> temp = smallerCoefficients;
    smallerCoefficients = largerCoefficients;
    largerCoefficients = temp;
  }

  ArrayRef<int> sumDiff(new Array<int>(largerCoefficients.size()));
  int lengthDiff = largerCoefficients.size() - smallerCoefficients.size();
  // Copy high-order terms only found in higher-degree polynomial's coefficients
  for (int i = 0; i < lengthDiff; i++) {
    sumDiff[i] = largerCoefficients[i];
  }

  for (int i = lengthDiff; i < (int)largerCoefficients.size(); i++) {
    sumDiff[i] = GenericGF::addOrSubtract(smallerCoefficients[i-lengthDiff],
                                          largerCoefficients[i]);
  }

  return Ref<GenericGFPoly>(new GenericGFPoly(field_, sumDiff));
}

From the error I guess coefficients_[0] doesnt exist, which gets initialized here, with his constructor

GenericGFPoly::GenericGFPoly(GenericGF &field,
                             ArrayRef<int> coefficients)
  :  field_(field) {
  if (coefficients->size() == 0) {
    throw IllegalArgumentException("need coefficients");
  }
  int coefficientsLength = coefficients->size();
  if (coefficientsLength > 1 && coefficients[0] == 0) {
    // Leading term must be non-zero for anything except the constant polynomial "0"
    int firstNonZero = 1;
    while (firstNonZero < coefficientsLength && coefficients[firstNonZero] == 0) {
      firstNonZero++;
    }
    if (firstNonZero == coefficientsLength) {
      coefficients_ = field.getZero()->getCoefficients();
    } else {
      coefficients_ = ArrayRef<int>(new Array<int>(coefficientsLength-firstNonZero));
      for (int i = 0; i < (int)coefficients_->size(); i++) {
        coefficients_[i] = coefficients[i + firstNonZero];
      }
    }
  } else {
    coefficients_ = coefficients;
  }
}

So i guess coefficients has to be declared, or it throws an error, which it does not. So then coefficients_ is not intialized. Then what.. Anyone understands this code better than I?

TimZaman commented 9 years ago

I found the bastard. screenshot 2015-05-19 11 20 18 This message was 'avoid accessing null field during construction'.

I guess change coefficients_[i] = coefficients[i + firstNonZero]; to coefficients_ = ArrayRef<int>(new Array<int>(1)); coefficients_[0] = 0;

Solid?