Example #1
0
func (i *Identifier) Recognise(m core.MatcherType, idx int) (bool, string) {
	switch m {
	default:
		return false, ""
	case core.ExtensionMatcher:
		if idx >= i.eStart && idx < i.eStart+len(i.ePuids) {
			idx = idx - i.eStart
			return true, i.name + ": " + i.ePuids[idx]
		}
		return false, ""
	case core.MIMEMatcher:
		if idx >= i.mStart && idx < i.mStart+len(i.mPuids) {
			idx = idx - i.mStart
			return true, i.name + ": " + i.mPuids[idx]
		}
		return false, ""
	case core.ContainerMatcher:
		if idx >= i.cStart && idx < i.cStart+len(i.cPuids) {
			idx = idx - i.cStart
			return true, i.name + ": " + i.cPuids[idx]
		}
		return false, ""
	case core.ByteMatcher:
		if idx >= i.bStart && idx < i.bStart+len(i.bPuids) {
			return true, i.name + ": " + i.bPuids[idx]
		}
		return false, ""
	case core.TextMatcher:
		if idx == i.tStart {
			return true, i.name + ": " + config.TextPuid()
		}
		return false, ""
	}
}
Example #2
0
// add adds extension, bytematcher or containermatcher signatures to the identifier
func (p *pronom) add(m core.Matcher, t core.MatcherType) error {
	switch t {
	default:
		return fmt.Errorf("Pronom: unknown matcher type %d", t)
	case core.ExtensionMatcher:
		if !config.NoExt() {
			var exts [][]string
			exts, p.ePuids = p.j.Globs()
			l, err := m.Add(stringmatcher.SignatureSet(exts), nil)
			if err != nil {
				return err
			}
			p.eStart = l - len(p.ePuids)
			return nil
		}
	case core.MIMEMatcher:
		if !config.NoMIME() {
			var mimes [][]string
			mimes, p.mPuids = p.j.MIMEs()
			l, err := m.Add(stringmatcher.SignatureSet(mimes), nil)
			if err != nil {
				return err
			}
			p.mStart = l - len(p.mPuids)
			return nil
		}
	case core.ContainerMatcher:
		return p.contMatcher(m)
	case core.ByteMatcher:
		var sigs []frames.Signature
		var err error
		sigs, p.bPuids, err = p.j.Signatures()
		if err != nil {
			return err
		}
		var plist priority.List
		if !config.NoPriority() {
			plist = p.pm.List(p.bPuids)
		}
		l, err := m.Add(bytematcher.SignatureSet(sigs), plist)
		if err != nil {
			return err
		}
		p.bStart = l - len(p.bPuids)
	case core.TextMatcher:
		if !config.NoText() && p.hasPuid(config.TextPuid()) {
			l, _ := m.Add(textmatcher.SignatureSet{}, nil)
			p.tStart = l
		}
	}
	return nil
}
Example #3
0
func (r *Recorder) Satisfied(mt core.MatcherType) bool {
	if r.cscore < incScore {
		if mt == core.ByteMatcher {
			return false
		}
		if len(r.ids) == 0 {
			return false
		}
		for _, res := range r.ids {
			if res.Puid == config.TextPuid() {
				return false
			}
		}
	}
	r.satisfied = true
	return true
}
Example #4
0
// add adds extension, bytematcher or containermatcher signatures to the identifier
func (p *pronom) add(m core.Matcher) error {
	switch t := m.(type) {
	default:
		return fmt.Errorf("Pronom: unknown matcher type %T", t)
	case extensionmatcher.Matcher:
		if !config.NoExt() {
			var exts [][]string
			exts, p.ePuids = p.j.extensions()
			l, err := m.Add(extensionmatcher.SignatureSet(exts), nil)
			if err != nil {
				return err
			}
			p.eStart = l - len(p.ePuids)
			return nil
		}
	case containermatcher.Matcher:
		return p.contMatcher(m)
	case *bytematcher.Matcher:
		var sigs []frames.Signature
		var err error
		sigs, p.bPuids, err = p.j.signatures()
		if err != nil {
			return err
		}
		var plist priority.List
		if !config.NoPriority() {
			plist = p.pm.List(p.bPuids)
		}
		l, err := m.Add(bytematcher.SignatureSet(sigs), plist)
		if err != nil {
			return err
		}
		p.bStart = l - len(p.bPuids)
	case *textmatcher.Matcher:
		if !config.NoText() && p.hasPuid(config.TextPuid()) {
			l, _ := m.Add(textmatcher.SignatureSet{}, nil)
			p.tStart = l
		}
	}
	return nil
}
Example #5
0
func (r *Recorder) Report(res chan core.Identification) {
	if len(r.ids) > 0 {
		// if we don't have priority set, apply a warning
		if r.noPriority {
			for i := range r.ids {
				r.ids[i].Warning = "no priority set for this identifier"
			}
		}
		sort.Sort(r.ids)
		conf := r.ids[0].confidence
		// if we've only got extension / mime matches, check if those matches are ruled out by lack of byte match
		// only permit a single extension or mime only match
		// add warnings too
		if conf <= textScore {
			nids := make([]Identification, 0, 1)
			for _, v := range r.ids {
				// if overall confidence is greater than mime or ext only, then rule out any lesser confident matches
				if conf > mimeScore && v.confidence != conf {
					break
				}
				// if we have plain text result that is based on ext or mime only,
				// and not on a text match, and if text matcher is on for this identifier,
				// then don't report a text match
				if v.Puid == config.TextPuid() && conf < textScore && r.textActive {
					continue
				}
				// if the match has no corresponding byte or container signature...
				if ok := r.hasSig(v.Puid); !ok {
					// break immediately if more than one match
					if len(nids) > 0 {
						nids = nids[:0]
						break
					}
					if len(v.Warning) > 0 {
						v.Warning += "; " + "match on " + lowConfidence(v.confidence) + " only"
					} else {
						v.Warning = "match on " + lowConfidence(v.confidence) + " only"
					}
					nids = append(nids, v)
				}
			}
			if len(nids) != 1 {
				poss := make([]string, len(r.ids))
				for i, v := range r.ids {
					poss[i] = v.Puid
					conf = conf | v.confidence
				}
				nids = []Identification{Identification{r.name, "UNKNOWN", "", "", "", nil, fmt.Sprintf("no match; possibilities based on %v are %v", lowConfidence(conf), strings.Join(poss, ", ")), 0, 0}}
			}
			r.ids = nids
		}
		res <- r.checkActive(r.ids[0])
		if len(r.ids) > 1 {
			for i, v := range r.ids[1:] {
				if v.confidence == conf || (r.noPriority && v.confidence >= incScore) {
					res <- r.checkActive(r.ids[i+1])
				} else {
					break
				}
			}
		}
	} else {
		res <- Identification{r.name, "UNKNOWN", "", "", "", nil, "no match", 0, 0}
	}
}
Example #6
0
func (r *Recorder) Record(m core.MatcherType, res core.Result) bool {
	switch m {
	default:
		return false
	case core.ExtensionMatcher:
		if res.Index() >= r.eStart && res.Index() < r.eStart+len(r.ePuids) {
			idx := res.Index() - r.eStart
			r.ids = add(r.ids, r.name, r.ePuids[idx], r.infos[r.ePuids[idx]], res.Basis(), extScore)
			return true
		} else {
			return false
		}
	case core.MIMEMatcher:
		if res.Index() >= r.mStart && res.Index() < r.mStart+len(r.mPuids) {
			idx := res.Index() - r.mStart
			r.ids = add(r.ids, r.name, r.mPuids[idx], r.infos[r.mPuids[idx]], res.Basis(), mimeScore)
			return true
		} else {
			return false
		}
	case core.ContainerMatcher:
		// add zip default
		if res.Index() < 0 {
			if r.zipDefault {
				r.cscore += incScore
				r.ids = add(r.ids, r.name, config.ZipPuid(), r.infos[config.ZipPuid()], res.Basis(), r.cscore)
			}
			return false
		}
		if res.Index() >= r.cStart && res.Index() < r.cStart+len(r.cPuids) {
			idx := res.Index() - r.cStart
			r.cscore += incScore
			basis := res.Basis()
			p, t := place(idx, r.cPuids)
			if t > 1 {
				basis = basis + fmt.Sprintf(" (signature %d/%d)", p, t)
			}
			r.ids = add(r.ids, r.name, r.cPuids[idx], r.infos[r.cPuids[idx]], basis, r.cscore)
			return true
		} else {
			return false
		}
	case core.ByteMatcher:
		if res.Index() >= r.bStart && res.Index() < r.bStart+len(r.bPuids) {
			if r.satisfied {
				return true
			}
			idx := res.Index() - r.bStart
			r.cscore += incScore
			basis := res.Basis()
			p, t := place(idx, r.bPuids)
			if t > 1 {
				basis = basis + fmt.Sprintf(" (signature %d/%d)", p, t)
			}
			r.ids = add(r.ids, r.name, r.bPuids[idx], r.infos[r.bPuids[idx]], basis, r.cscore)
			return true
		} else {
			return false
		}
	case core.TextMatcher:
		if res.Index() == r.tStart {
			if r.satisfied {
				return true
			}
			r.ids = add(r.ids, r.name, config.TextPuid(), r.infos[config.TextPuid()], res.Basis(), textScore)
			return true
		} else {
			return false
		}
	}
}