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 ())); }
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; }
// 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; }