Example #1
0
Pagemodel::Pagemodel (QObject *parent)
      : QAbstractItemModel (parent)
   {
   _contents = 0;
   _start = 0;
   _count = 0;
   _column_count = 0;
   _scale_down = 24;
   _row_count = _count;
   _lost_contents = 0;
   _own_scan = _lost_scan = false;
   _rescaling = false;

   // create the pages
   _updateTimer = new QTimer (this);
   connect (_updateTimer, SIGNAL (timeout()), this, SLOT (nextUpdate ()));
   }
Example #2
0
Enumerator::Result Enumerator::backtrackFromModel(Solver& s, bool callContinue) {
	assert(s.numFreeVars() == 0 && !s.hasConflict());
	bool update             = updateModel(s) || optimize();
	bool expandSym          = !ignoreSymmetric();
	activeLevel_            = mini_ ? constraint(s)->minimize()->commitCurrent(s)+1 : s.decisionLevel();
	Enumerator::Result    r = Enumerator::enumerate_continue;
	EnumeratorConstraint* c = constraint(s);
	do {
		++enumerated;
		s.stats.addModel(s.decisionLevel());
		if (report_) { 
			report_->reportModel(s, *this); 
		}
		if ((numModels_ != 0 && --numModels_ == 0) || terminated()) {
			// enough models enumerated
			return enumerate_stop_enough;
		}
		// Process symmetric models, i.e. models that differ only in the 
		// assignment of atoms outside of the solver's assignment. 
		// Typical example: vars eliminated by the SAT-preprocessor
	} while (expandSym && s.nextSymModel());
	if (activeLevel_ <= s.rootLevel() || !backtrack(s)) {
		r = enumerate_stop_complete;
		s.undoUntil(0, true);
	}
	else if (restartOnModel_) { s.undoUntil(0); }	
	if (update && s.sharedContext()->isShared()) {
		// enumerator is not trivial w.r.t current search scheme
		// force update of other solvers
		// - this one is up to date
		c->setUpdates(nextUpdate());
	}
	if (callContinue && !continueFromModel(s)) {
		r = enumerate_stop_complete;
	}
	return r;
}
Example #3
0
// SingleResponse ::= SEQUENCE {
//    certID                       CertID,
//    certStatus                   CertStatus,
//    thisUpdate                   GeneralizedTime,
//    nextUpdate           [0]     EXPLICIT GeneralizedTime OPTIONAL,
//    singleExtensions     [1]     EXPLICIT Extensions{{re-ocsp-crl |
//                                              re-ocsp-archive-cutoff |
//                                              CrlEntryExtensions, ...}
//                                              } OPTIONAL }
static inline Result
SingleResponse(Reader& input, Context& context)
{
  bool match = false;
  Result rv = der::Nested(input, der::SEQUENCE,
                          bind(CertID, _1, cref(context), ref(match)));
  if (rv != Success) {
    return rv;
  }

  if (!match) {
    // This response does not reference the certificate we're interested in.
    // By consuming the rest of our input and returning successfully, we can
    // continue processing and examine another response that might have what
    // we want.
    input.SkipToEnd();
    return Success;
  }

  // CertStatus ::= CHOICE {
  //     good        [0]     IMPLICIT NULL,
  //     revoked     [1]     IMPLICIT RevokedInfo,
  //     unknown     [2]     IMPLICIT UnknownInfo }
  //
  // In the event of multiple SingleResponses for a cert that have conflicting
  // statuses, we use the following precedence rules:
  //
  // * revoked overrides good and unknown
  // * good overrides unknown
  if (input.Peek(static_cast<uint8_t>(CertStatus::Good))) {
    rv = der::ExpectTagAndEmptyValue(input,
                                     static_cast<uint8_t>(CertStatus::Good));
    if (rv != Success) {
      return rv;
    }
    if (context.certStatus != CertStatus::Revoked) {
      context.certStatus = CertStatus::Good;
    }
  } else if (input.Peek(static_cast<uint8_t>(CertStatus::Revoked))) {
    // We don't need any info from the RevokedInfo structure, so we don't even
    // parse it. TODO: We should mention issues like this in the explanation of
    // why we treat invalid OCSP responses equivalently to revoked for OCSP
    // stapling.
    rv = der::ExpectTagAndSkipValue(input,
                                    static_cast<uint8_t>(CertStatus::Revoked));
    if (rv != Success) {
      return rv;
    }
    context.certStatus = CertStatus::Revoked;
  } else {
    rv = der::ExpectTagAndEmptyValue(input,
                                     static_cast<uint8_t>(CertStatus::Unknown));
    if (rv != Success) {
      return rv;
    }
  }

  // http://tools.ietf.org/html/rfc6960#section-3.2
  // 5. The time at which the status being indicated is known to be
  //    correct (thisUpdate) is sufficiently recent;
  // 6. When available, the time at or before which newer information will
  //    be available about the status of the certificate (nextUpdate) is
  //    greater than the current time.

  Time thisUpdate(Time::uninitialized);
  rv = der::GeneralizedTime(input, thisUpdate);
  if (rv != Success) {
    return rv;
  }

  static const uint64_t SLOP_SECONDS = Time::ONE_DAY_IN_SECONDS;

  Time timePlusSlop(context.time);
  rv = timePlusSlop.AddSeconds(SLOP_SECONDS);
  if (rv != Success) {
    return rv;
  }
  if (thisUpdate > timePlusSlop) {
    return Result::ERROR_OCSP_FUTURE_RESPONSE;
  }

  Time notAfter(Time::uninitialized);
  static const uint8_t NEXT_UPDATE_TAG =
    der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 0;
  if (input.Peek(NEXT_UPDATE_TAG)) {
    Time nextUpdate(Time::uninitialized);
    rv = der::Nested(input, NEXT_UPDATE_TAG,
                    bind(der::GeneralizedTime, _1, ref(nextUpdate)));
    if (rv != Success) {
      return rv;
    }

    if (nextUpdate < thisUpdate) {
      return Result::ERROR_OCSP_MALFORMED_RESPONSE;
    }
    notAfter = thisUpdate;
    if (notAfter.AddSeconds(context.maxLifetimeInDays *
                            Time::ONE_DAY_IN_SECONDS) != Success) {
      // This could only happen if we're dealing with times beyond the year
      // 10,000AD.
      return Result::ERROR_OCSP_FUTURE_RESPONSE;
    }
    if (nextUpdate <= notAfter) {
      notAfter = nextUpdate;
    }
  } else {
    // NSS requires all OCSP responses without a nextUpdate to be recent.
    // Match that stricter behavior.
    notAfter = thisUpdate;
    if (notAfter.AddSeconds(Time::ONE_DAY_IN_SECONDS) != Success) {
      // This could only happen if we're dealing with times beyond the year
      // 10,000AD.
      return Result::ERROR_OCSP_FUTURE_RESPONSE;
    }
  }

  // Add some slop to hopefully handle clock-skew.
  Time notAfterPlusSlop(notAfter);
  rv = notAfterPlusSlop.AddSeconds(SLOP_SECONDS);
  if (rv != Success) {
    // This could only happen if we're dealing with times beyond the year
    // 10,000AD.
    return Result::ERROR_OCSP_FUTURE_RESPONSE;
  }
  if (context.time > notAfterPlusSlop) {
    context.expired = true;
  }

  rv = der::OptionalExtensions(input,
                               der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 1,
                               ExtensionNotUnderstood);
  if (rv != Success) {
    return rv;
  }

  if (context.thisUpdate) {
    *context.thisUpdate = thisUpdate;
  }
  if (context.validThrough) {
    *context.validThrough = notAfterPlusSlop;
  }

  return Success;
}