Exemple #1
0
func textMIMES(m map[string]identifier.FormatInfo) []string {
	ret := make([]string, 1, len(m))
	ret[0] = config.TextMIME() // first one is the default
	for k, v := range m {
		if v.(formatInfo).text {
			ret = append(ret, k)
		}
	}
	return ret
}
Exemple #2
0
func (mi mimeinfo) Infos() map[string]identifier.FormatInfo {
	fmap := make(map[string]identifier.FormatInfo, len(mi.m))
	for _, v := range mi.m {
		fi := formatInfo{}
		if len(v.Comment) > 0 {
			fi.comment = v.Comment[0]
		} else if len(v.Comments) > 0 {
			fi.comment = v.Comments[0]
		}
		var magicWeight int
		for _, mg := range v.Magic {
			magicWeight += len(mg.Matches)
		}
		fi.globWeights, fi.magicWeights = make([]int, len(v.Globs)), make([]int, 0, magicWeight)
		for i, w := range v.Globs {
			if len(w.Weight) > 0 {
				num, err := strconv.Atoi(w.Weight)
				if err == nil {
					fi.globWeights[i] = num
					continue
				}
			}
			fi.globWeights[i] = 50
		}
		for _, w := range v.Magic {
			weight := 50
			if len(w.Priority) > 0 {
				if num, err := strconv.Atoi(w.Priority); err == nil {
					weight = num
				}
			}
			for _, s := range w.Matches {
				ss, _ := toSigs(s)
				for _, sig := range ss {
					if sig != nil {
						fi.magicWeights = append(fi.magicWeights, weight)
					}
				}
			}
		}
		if len(v.SuperiorClasses) == 1 && v.SuperiorClasses[0].SubClassOf == config.TextMIME() {
			fi.text = true
		}
		fmap[v.MIME] = fi
	}
	return fmap
}
Exemple #3
0
func newMIMEInfo(path string) (identifier.Parseable, error) {
	buf, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, err
	}
	mi := &mappings.MIMEInfo{}
	err = xml.Unmarshal(buf, mi)
	if err != nil {
		return nil, err
	}
	index := make(map[string]int)
	for i, v := range mi.MIMETypes {
		index[v.MIME] = i
	}
	for i, v := range mi.MIMETypes {
		if len(v.SuperiorClasses) == 1 && v.SuperiorClasses[0].SubClassOf != config.TextMIME() { // subclasses of text/plain shouldn't inherit text magic
			sup := index[v.SuperiorClasses[0].SubClassOf]
			if len(mi.MIMETypes[sup].XMLPattern) > 0 {
				mi.MIMETypes[i].XMLPattern = append(mi.MIMETypes[i].XMLPattern, mi.MIMETypes[sup].XMLPattern...)
			}
			if len(mi.MIMETypes[sup].Magic) > 0 {
				nm := make([]mappings.Magic, len(mi.MIMETypes[sup].Magic))
				copy(nm, mi.MIMETypes[sup].Magic)
				for i, w := range nm {
					if len(w.Priority) > 0 {
						num, err := strconv.Atoi(w.Priority)
						if err == nil {
							nm[i].Priority = strconv.Itoa(num - 1)
							continue
						}
					}
					nm[i].Priority = "49"
				}
				mi.MIMETypes[i].Magic = append(mi.MIMETypes[i].Magic, nm...)
			}
		}
	}
	return mimeinfo{mi.MIMETypes, identifier.Blank{}}, nil
}
func applyScore(id Identification, info formatInfo, t core.MatcherType, rel int) Identification {
	switch t {
	case core.NameMatcher:
		score := info.globWeights[rel]
		if score > id.globScore {
			id.globScore = score
		}
	case core.MIMEMatcher:
		id.mimeMatch = true
	case core.XMLMatcher:
		id.xmlMatch = true
	case core.ByteMatcher:
		score := info.magicWeights[rel]
		if score > id.magicScore {
			id.magicScore = score
		}
	case core.TextMatcher:
		id.textMatch = true
		if id.ID == config.TextMIME() {
			id.textDefault = true
		}
	}
	return id
}
func (r *Recorder) Report() []core.Identification {
	// no results
	if len(r.ids) == 0 {
		return []core.Identification{Identification{
			Namespace: r.Name(),
			ID:        "UNKNOWN",
			Warning:   "no match",
		}}
	}
	sort.Sort(r.ids)
	// exhaustive
	if r.Multi() == config.Exhaustive {
		ret := make([]core.Identification, len(r.ids))
		for i, v := range r.ids {
			ret[i] = r.updateWarning(v)
		}
		return ret
	}
	// if we've only got weak matches (match is filename/mime only) report only the first
	if !r.ids[0].xmlMatch && r.ids[0].magicScore == 0 {
		var nids []Identification
		if len(r.ids) == 1 || r.ids.Less(0, 1) { // // Less reports whether the element with index i (0) should sort before the element with index j
			if r.ids[0].ID != config.TextMIME() || r.ids[0].textMatch || !r.textActive {
				nids = []Identification{r.ids[0]}
			}
		}
		var conf string
		if len(nids) != 1 {
			lowConfidence := confidenceTrick()
			poss := make([]string, len(r.ids))
			for i, v := range r.ids {
				poss[i] = v.ID
				conf = lowConfidence(v)
			}
			return []core.Identification{Identification{
				Namespace: r.Name(),
				ID:        "UNKNOWN",
				Warning:   fmt.Sprintf("no match; possibilities based on %s are %v", conf, strings.Join(poss, ", ")),
			}}
		}
		r.ids = nids
	}
	// handle single result only
	if r.Multi() == config.Single && len(r.ids) > 1 && !r.ids.Less(0, 1) {
		poss := make([]string, 0, len(r.ids))
		for i, v := range r.ids {
			if i > 0 && r.ids.Less(i-1, i) {
				break
			}
			poss = append(poss, v.ID)
		}
		return []core.Identification{Identification{
			Namespace: r.Name(),
			ID:        "UNKNOWN",
			Warning:   fmt.Sprintf("multiple matches %v", strings.Join(poss, ", ")),
		}}
	}
	ret := make([]core.Identification, len(r.ids))
	for i, v := range r.ids {
		if i > 0 {
			switch r.Multi() {
			case config.Single:
				return ret[:i]
			case config.Conclusive:
				if r.ids.Less(i-1, i) {
					return ret[:i]
				}
			default:
				if !v.xmlMatch && v.magicScore == 0 { // if weak
					return ret[:i]
				}
			}
		}
		ret[i] = r.updateWarning(v)
	}
	return ret
}
func (r *Recorder) Satisfied(mt core.MatcherType) (bool, int) {
	if r.NoPriority() {
		return false, 0
	}
	sort.Sort(r.ids)
	if len(r.ids) > 0 && (r.ids[0].xmlMatch || (r.ids[0].magicScore > 0 && r.ids[0].ID != config.TextMIME())) {
		if mt == core.ByteMatcher {
			return true, r.Start(mt)
		}
		return true, 0
	}
	return false, 0
}