filetype

package module
v0.0.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 19, 2026 License: MIT Imports: 1 Imported by: 0

README

tinywasm/filetype

Identifies a file's real type from its bytes. Never decodes, never trusts the client.

A Content-Type header and a file extension are text the client chose — a claim, not evidence. Only the leading bytes decide.

go get github.com/tinywasm/filetype

Why it is tiny

Detection is a comparison of magic-byte prefixes and nothing else. Decoding a PNG merely to check that it is valid would pull in image/png + compress/zlib — hundreds of KB in a WASM binary. This package refuses that trade, which is the whole reason it exists.

Isomorphic: no build tags, no standard library. The same detection runs in the browser (validating before upload) and on the server (validating what arrived), so client and server can never disagree about what a file is.

Usage

import "github.com/tinywasm/filetype"

// Images is the safe default: raster images only, nothing scriptable.
t, err := filetype.Images.Validate(data)
if err != nil {
    return err // "filetype: PDF is not allowed" — the error names what it actually found
}

key := id + t.Ext        // ".png" — the extension comes from the bytes, not from a filename
bucket.Put(key, data, t.MIME)

Or detect without a policy:

t, ok := filetype.Detect(data)
if !ok {
    // No known signature. Reject — never fall back to what the client claimed.
}

Recognized types

Type Detected In Images
PNG, JPEG, GIF, WebP
PDF ❌ — add it explicitly if you want it
SVG, HTML never

SVG and HTML are detected on purpose, so they can be rejected by name instead of disappearing into "unknown". Both can carry JavaScript: served from your own domain, they execute in your origin. Type.Scriptable() reports this.

Build your own policy with NewAllowlist(...). Its zero value accepts nothing — a policy someone forgot to configure must not be permissive.

Testing

gotest

See AGENTS.md for the constraints that govern this library.

Documentation

Overview

Package filetype identifies a file's real type from its leading bytes.

It NEVER decodes content. Detection is a comparison of magic-byte prefixes, so the package costs almost nothing in a WASM binary — decoding a PNG merely to validate it would pull in image/png and compress/zlib, hundreds of KB.

Isomorphic: no build tags, no standard library. The same detection runs in a browser (validating before upload) and on a server (validating what arrived), so client and server can never disagree about what a file is.

The type a client declares — a Content-Type header, a file extension — is a claim, not evidence. Only the bytes are evidence.

Index

Constants

This section is empty.

Variables

View Source
var (
	PNG  = Type{MIME: "image/png", Ext: ".png", /* contains filtered or unexported fields */}
	JPEG = Type{MIME: "image/jpeg", Ext: ".jpg", /* contains filtered or unexported fields */}
	GIF  = Type{MIME: "image/gif", Ext: ".gif", /* contains filtered or unexported fields */}
	WebP = Type{MIME: "image/webp", Ext: ".webp", /* contains filtered or unexported fields */}
	PDF  = Type{MIME: "application/pdf", Ext: ".pdf", /* contains filtered or unexported fields */}

	SVG  = Type{MIME: "image/svg+xml", Ext: ".svg", /* contains filtered or unexported fields */}
	HTML = Type{MIME: "text/html", Ext: ".html", /* contains filtered or unexported fields */}
)

The types this package recognizes.

SVG and HTML are detected ON PURPOSE, so they can be rejected by name instead of vanishing into "unknown". Both can carry JavaScript: served from your own domain, they execute in your origin. Never put them in an Allowlist for user uploads.

Images is the safe default for user uploads: raster images only, nothing scriptable.

Functions

This section is empty.

Types

type Allowlist added in v0.0.2

type Allowlist struct {
	// contains filtered or unexported fields
}

Allowlist is the upload policy: which types this site accepts. The zero value accepts nothing — a policy you forgot to configure must not be permissive.

func NewAllowlist added in v0.0.2

func NewAllowlist(t ...Type) Allowlist

NewAllowlist builds a policy accepting exactly the given types.

func (Allowlist) Validate added in v0.0.2

func (a Allowlist) Validate(data []byte) (Type, error)

Validate detects data's type and checks it against the policy. The error names the type actually found, so a rejection is diagnosable.

type Type added in v0.0.2

type Type struct {
	MIME string // "image/png"
	Ext  string // ".png"
	// contains filtered or unexported fields
}

Type is a recognized file type: its real MIME type and canonical extension.

func Detect added in v0.0.2

func Detect(data []byte) (t Type, ok bool)

Detect returns the type deduced from data's leading bytes. ok=false means no known signature matched — the caller must reject the content, and never fall back to what the client claimed.

func (Type) Scriptable added in v0.0.2

func (t Type) Scriptable() bool

Scriptable reports whether the type can carry executable code. Serving a scriptable file from your own domain runs that code in your origin.

func (Type) String added in v0.0.2

func (t Type) String() string

String returns the type's short name ("PNG"), for diagnostics.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL