Beispiel #1
0
func matchTagName(s string) string {
	if len(s) < 2 {
		return ""
	}

	i := 0
	if s[0] == '/' {
		i++
	}
	start := i
	max := min(15+i, len(s))
	for i < max && byteutil.IsLetter(s[i]) {
		i++
	}
	if i >= len(s) {
		return ""
	}

	switch s[i] {
	case ' ', '\n', '/', '>':
		return byteutil.ToLower(s[start:i])
	default:
		return ""
	}
}
Beispiel #2
0
func matchAutolink(s string) string {
	if len(s) < 6 || s[0] != '<' {
		return ""
	}

	st := 0
	n := 0
	for i := 1; i < len(s); i++ {
		b := s[i]
		switch st {
		case 0: // initial state
			switch {
			case schemecs[b]:
				st = 1
				n++
			default:
				return ""
			}

		case 1: // h
			switch {
			case schemecs[b]:
				n++
				if n > 23 {
					return ""
				}
			case b == ':':
				schema := byteutil.ToLower(s[1:i])
				if !matchSchema(schema) {
					return ""
				}
				st = 2
			default:
				return ""
			}

		case 2: // http:
			switch {
			case linkcs[b]:
				st = 3
				break
			default:
				return ""
			}
		case 3: // http:/
			switch {
			case linkcs[b]:
				break
			case b == '>':
				return s[1:i]
			default:
				return ""
			}
		}
	}
	return ""
}
Beispiel #3
0
// Parse parses rawurl into a URL structure.
func Parse(rawurl string) (*URL, error) {
	n, err := findScheme(rawurl)
	if err != nil {
		return nil, err
	}

	var url URL
	rest := rawurl
	hostless := false
	if n > 0 {
		url.Scheme, rest = byteutil.ToLower(rest[:n]), rest[n+1:]
		if url.Scheme == "javascript" {
			hostless = true
		}
	}

	if !hostless && strings.HasPrefix(rest, "//") {
		url.Slashes, rest = true, rest[2:]
	}

	if !hostless && (url.Slashes || (url.Scheme != "" && !slashedProtocol[url.Scheme])) {
		hostEnd := byteutil.IndexAnyTable(rest, &cs2)
		atSign := -1
		i := hostEnd
		if i == -1 {
			i = len(rest) - 1
		}
		for i >= 0 {
			if rest[i] == '@' {
				atSign = i
				break
			}
			i--
		}

		if atSign != -1 {
			url.Auth, rest = rest[:atSign], rest[atSign+1:]
		}

		hostEnd = byteutil.IndexAnyTable(rest, &cs3)
		if hostEnd == -1 {
			hostEnd = len(rest)
		}
		if hostEnd > 0 && hostEnd < len(rest) && rest[hostEnd-1] == ':' {
			hostEnd--
		}
		host := rest[:hostEnd]

		if len(host) > 1 {
			b := host[hostEnd-1]
			if byteutil.IsDigit(b) {
				for i := len(host) - 2; i >= 0; i-- {
					b := host[i]
					if b == ':' {
						url.Host, url.Port = host[:i], host[i+1:]
						break
					}
					if !byteutil.IsDigit(b) {
						break
					}
				}
			} else if b == ':' {
				host = host[:hostEnd-1]
				hostEnd--
			}
		}
		if url.Port == "" {
			url.Host = host
		}
		rest = rest[hostEnd:]

		if ipv6 := len(url.Host) > 2 &&
			url.Host[0] == '[' &&
			url.Host[len(url.Host)-1] == ']'; ipv6 {
			url.Host = url.Host[1 : len(url.Host)-1]
			url.IPv6 = true
		} else if i := strings.IndexByte(url.Host, ':'); i >= 0 {
			url.Host, rest = url.Host[:i], url.Host[i:]+rest
		}
	}

	rest, url.Fragment = split(rest, '#')
	url.Path, url.RawQuery = split(rest, '?')

	return &url, nil
}