text:
// Copyright 2011 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"fmt"
	"go/ast"
	"go/parser"
	"go/token"
	"os"
	"path"
	"reflect"
	"strconv"
	"strings"
)

type fix struct {
	name string
	date string // date that fix was introduced, in YYYY-MM-DD format
	f    func(*ast.File) bool
	desc string
}

// main runs sort.Sort(byName(fixes)) before printing list of fixes.
type byName []fix

func (f byName) Len() int           { return len(f) }
func (f byName) Swap(i, j int)      { f[i], f[j] = f[j], f[i] }
func (f byName) Less(i, j int) bool { return f[i].name < f[j].name }

// main runs sort.Sort(byDate(fixes)) before applying fixes.
type byDate []fix

func (f byDate) Len() int           { return len(f) }
func (f byDate) Swap(i, j int)      { f[i], f[j] = f[j], f[i] }
func (f byDate) Less(i, j int) bool { return f[i].date < f[j].date }

var fixes []fix

func register(f fix) {
	fixes = append(fixes, f)
}

// walk traverses the AST x, calling visit(y) for each node y in the tree but
// also with a pointer to each ast.Expr, ast.Stmt, and *ast.BlockStmt,
// in a bottom-up traversal.
func walk(x interface{}, visit func(interface{})) {
	walkBeforeAfter(x, nop, visit)
}

func nop(interface{}) {}

// walkBeforeAfter is like walk but calls before(x) before traversing
// x's children and after(x) afterward.
func walkBeforeAfter(x interface{}, before, after func(interface{})) {
	before(x)

	switch n := x.(type) {
	default:
		panic(fmt.Errorf("unexpected type %T in walkBeforeAfter", x))

	case nil:

	// pointers to interfaces
	case *ast.Decl:
		walkBeforeAfter(*n, before, after)
	case *ast.Expr:
		walkBeforeAfter(*n, before, after)
	case *ast.Spec:
		walkBeforeAfter(*n, before, after)
	case *ast.Stmt:
		walkBeforeAfter(*n, before, after)

	// pointers to struct pointers
	case **ast.BlockStmt:
		walkBeforeAfter(*n, before, after)
	case **ast.CallExpr:
		walkBeforeAfter(*n, before, after)
	case **ast.FieldList:
		walkBeforeAfter(*n, before, after)
	case **ast.FuncType:
		walkBeforeAfter(*n, before, after)
	case **ast.Ident:
		walkBeforeAfter(*n, before, after)
	case **ast.BasicLit:
		walkBeforeAfter(*n, before, after)

	// pointers to slices
	case *[]ast.Decl:
		walkBeforeAfter(*n, before, after)
	case *[]ast.Expr:
		walkBeforeAfter(*n, before, after)
	case *[]*ast.File:
		walkBeforeAfter(*n, before, after)
	case *[]*ast.Ident:
		walkBeforeAfter(*n, before, after)
	case *[]ast.Spec:
		walkBeforeAfter(*n, before, after)
	case *[]ast.Stmt:
		walkBeforeAfter(*n, before, after)

	// These are ordered and grouped to match ../../pkg/go/ast/ast.go
	case *ast.Field:
		walkBeforeAfter(&n.Names, before, after)
		walkBeforeAfter(&n.Type, before, after)
		walkBeforeAfter(&n.Tag, before, after)
	case *ast.FieldList:
		for _, field := range n.List {
			walkBeforeAfter(field, before, after)
		}
	case *ast.BadExpr:
	case *ast.Ident:
	case *ast.Ellipsis:
		walkBeforeAfter(&n.Elt, before, after)
	case *ast.BasicLit:
	case *ast.FuncLit:
		walkBeforeAfter(&n.Type, before, after)
		walkBeforeAfter(&n.Body, before, after)
	case *ast.CompositeLit:
		walkBeforeAfter(&n.Type, before, after)
		walkBeforeAfter(&n.Elts, before, after)
	case *ast.ParenExpr:
		walkBeforeAfter(&n.X, before, after)
	case *ast.SelectorExpr:
		walkBeforeAfter(&n.X, before, after)
	case *ast.IndexExpr:
		walkBeforeAfter(&n.X, before, after)
		walkBeforeAfter(&n.Index, before, after)
	case *ast.SliceExpr:
		walkBeforeAfter(&n.X, before, after)
		if n.Low != nil {
			walkBeforeAfter(&n.Low, before, after)
		}
		if n.High != nil {
			walkBeforeAfter(&n.High, before, after)
		}
	case *ast.TypeAssertExpr:
		walkBeforeAfter(&n.X, before, after)
		walkBeforeAfter(&n.Type, before, after)
	case *ast.CallExpr:
		walkBeforeAfter(&n.Fun, before, after)
		walkBeforeAfter(&n.Args, before, after)
	case *ast.StarExpr:
		walkBeforeAfter(&n.X, before, after)
	case *ast.UnaryExpr:
		walkBeforeAfter(&n.X, before, after)
	case *ast.BinaryExpr:
		walkBeforeAfter(&n.X, before, after)
		walkBeforeAfter(&n.Y, before, after)
	case *ast.KeyValueExpr:
		walkBeforeAfter(&n.Key, before, after)
		walkBeforeAfter(&n.Value, before, after)

	case *ast.ArrayType:
		walkBeforeAfter(&n.Len, before, after)
		walkBeforeAfter(&n.Elt, before, after)
	case *ast.StructType:
		walkBeforeAfter(&n.Fields, before, after)
	case *ast.FuncType:
		walkBeforeAfter(&n.Params, before, after)
		if n.Results != nil {
			walkBeforeAfter(&n.Results, before, after)
		}
	case *ast.InterfaceType:
		walkBeforeAfter(&n.Methods, before, after)
	case *ast.MapType:
		walkBeforeAfter(&n.Key, before, after)
		walkBeforeAfter(&n.Value, before, after)
	case *ast.ChanType:
		walkBeforeAfter(&n.Value, before, after)

	case *ast.BadStmt:
	case *ast.DeclStmt:
		walkBeforeAfter(&n.Decl, before, after)
	case *ast.EmptyStmt:
	case *ast.LabeledStmt:
		walkBeforeAfter(&n.Stmt, before, after)
	case *ast.ExprStmt:
		walkBeforeAfter(&n.X, before, after)
	case *ast.SendStmt:
		walkBeforeAfter(&n.Chan, before, after)
		walkBeforeAfter(&n.Value, before, after)
	case *ast.IncDecStmt:
		walkBeforeAfter(&n.X, before, after)
	case *ast.AssignStmt:
		walkBeforeAfter(&n.Lhs, before, after)
		walkBeforeAfter(&n.Rhs, before, after)
	case *ast.GoStmt:
		walkBeforeAfter(&n.Call, before, after)
	case *ast.DeferStmt:
		walkBeforeAfter(&n.Call, before, after)
	case *ast.ReturnStmt:
		walkBeforeAfter(&n.Results, before, after)
	case *ast.BranchStmt:
	case *ast.BlockStmt:
		walkBeforeAfter(&n.List, before, after)
	case *ast.IfStmt:
		walkBeforeAfter(&n.Init, before, after)
		walkBeforeAfter(&n.Cond, before, after)
		walkBeforeAfter(&n.Body, before, after)
		walkBeforeAfter(&n.Else, before, after)
	case *ast.CaseClause:
		walkBeforeAfter(&n.List, before, after)
		walkBeforeAfter(&n.Body, before, after)
	case *ast.SwitchStmt:
		walkBeforeAfter(&n.Init, before, after)
		walkBeforeAfter(&n.Tag, before, after)
		walkBeforeAfter(&n.Body, before, after)
	case *ast.TypeSwitchStmt:
		walkBeforeAfter(&n.Init, before, after)
		walkBeforeAfter(&n.Assign, before, after)
		walkBeforeAfter(&n.Body, before, after)
	case *ast.CommClause:
		walkBeforeAfter(&n.Comm, before, after)
		walkBeforeAfter(&n.Body, before, after)
	case *ast.SelectStmt:
		walkBeforeAfter(&n.Body, before, after)
	case *ast.ForStmt:
		walkBeforeAfter(&n.Init, before, after)
		walkBeforeAfter(&n.Cond, before, after)
		walkBeforeAfter(&n.Post, before, after)
		walkBeforeAfter(&n.Body, before, after)
	case *ast.RangeStmt:
		walkBeforeAfter(&n.Key, before, after)
		walkBeforeAfter(&n.Value, before, after)
		walkBeforeAfter(&n.X, before, after)
		walkBeforeAfter(&n.Body, before, after)

	case *ast.ImportSpec:
	case *ast.ValueSpec:
		walkBeforeAfter(&n.Type, before, after)
		walkBeforeAfter(&n.Values, before, after)
		walkBeforeAfter(&n.Names, before, after)
	case *ast.TypeSpec:
		walkBeforeAfter(&n.Type, before, after)

	case *ast.BadDecl:
	case *ast.GenDecl:
		walkBeforeAfter(&n.Specs, before, after)
	case *ast.FuncDecl:
		if n.Recv != nil {
			walkBeforeAfter(&n.Recv, before, after)
		}
		walkBeforeAfter(&n.Type, before, after)
		if n.Body != nil {
			walkBeforeAfter(&n.Body, before, after)
		}

	case *ast.File:
		walkBeforeAfter(&n.Decls, before, after)

	case *ast.Package:
		walkBeforeAfter(&n.Files, before, after)

	case []*ast.File:
		for i := range n {
			walkBeforeAfter(&n[i], before, after)
		}
	case []ast.Decl:
		for i := range n {
			walkBeforeAfter(&n[i], before, after)
		}
	case []ast.Expr:
		for i := range n {
			walkBeforeAfter(&n[i], before, after)
		}
	case []*ast.Ident:
		for i := range n {
			walkBeforeAfter(&n[i], before, after)
		}
	case []ast.Stmt:
		for i := range n {
			walkBeforeAfter(&n[i], before, after)
		}
	case []ast.Spec:
		for i := range n {
			walkBeforeAfter(&n[i], before, after)
		}
	}
	after(x)
}

// imports returns true if f imports path.
func imports(f *ast.File, path string) bool {
	return importSpec(f, path) != nil
}

// importSpec returns the import spec if f imports path,
// or nil otherwise.
func importSpec(f *ast.File, path string) *ast.ImportSpec {
	for _, s := range f.Imports {
		if importPath(s) == path {
			return s
		}
	}
	return nil
}

// importPath returns the unquoted import path of s,
// or "" if the path is not properly quoted.
func importPath(s *ast.ImportSpec) string {
	t, err := strconv.Unquote(s.Path.Value)
	if err == nil {
		return t
	}
	return ""
}

// declImports reports whether gen contains an import of path.
func declImports(gen *ast.GenDecl, path string) bool {
	if gen.Tok != token.IMPORT {
		return false
	}
	for _, spec := range gen.Specs {
		impspec := spec.(*ast.ImportSpec)
		if importPath(impspec) == path {
			return true
		}
	}
	return false
}

// isPkgDot returns true if t is the expression "pkg.name"
// where pkg is an imported identifier.
func isPkgDot(t ast.Expr, pkg, name string) bool {
	sel, ok := t.(*ast.SelectorExpr)
	return ok && isTopName(sel.X, pkg) && sel.Sel.String() == name
}

// isPtrPkgDot returns true if f is the expression "*pkg.name"
// where pkg is an imported identifier.
func isPtrPkgDot(t ast.Expr, pkg, name string) bool {
	ptr, ok := t.(*ast.StarExpr)
	return ok && isPkgDot(ptr.X, pkg, name)
}

// isTopName returns true if n is a top-level unresolved identifier with the given name.
func isTopName(n ast.Expr, name string) bool {
	id, ok := n.(*ast.Ident)
	return ok && id.Name == name && id.Obj == nil
}

// isName returns true if n is an identifier with the given name.
func isName(n ast.Expr, name string) bool {
	id, ok := n.(*ast.Ident)
	return ok && id.String() == name
}

// isCall returns true if t is a call to pkg.name.
func isCall(t ast.Expr, pkg, name string) bool {
	call, ok := t.(*ast.CallExpr)
	return ok && isPkgDot(call.Fun, pkg, name)
}

// If n is an *ast.Ident, isIdent returns it; otherwise isIdent returns nil.
func isIdent(n interface{}) *ast.Ident {
	id, _ := n.(*ast.Ident)
	return id
}

// refersTo returns true if n is a reference to the same object as x.
func refersTo(n ast.Node, x *ast.Ident) bool {
	id, ok := n.(*ast.Ident)
	// The test of id.Name == x.Name handles top-level unresolved
	// identifiers, which all have Obj == nil.
	return ok && id.Obj == x.Obj && id.Name == x.Name
}

// isBlank returns true if n is the blank identifier.
func isBlank(n ast.Expr) bool {
	return isName(n, "_")
}

// isEmptyString returns true if n is an empty string literal.
func isEmptyString(n ast.Expr) bool {
	lit, ok := n.(*ast.BasicLit)
	return ok && lit.Kind == token.STRING && len(lit.Value) == 2
}

func warn(pos token.Pos, msg string, args ...interface{}) {
	if pos.IsValid() {
		msg = "%s: " + msg
		arg1 := []interface{}{fset.Position(pos).String()}
		args = append(arg1, args...)
	}
	fmt.Fprintf(os.Stderr, msg+"\n", args...)
}

// countUses returns the number of uses of the identifier x in scope.
func countUses(x *ast.Ident, scope []ast.Stmt) int {
	count := 0
	ff := func(n interface{}) {
		if n, ok := n.(ast.Node); ok && refersTo(n, x) {
			count++
		}
	}
	for _, n := range scope {
		walk(n, ff)
	}
	return count
}

// rewriteUses replaces all uses of the identifier x and !x in scope
// with f(x.Pos()) and fnot(x.Pos()).
func rewriteUses(x *ast.Ident, f, fnot func(token.Pos) ast.Expr, scope []ast.Stmt) {
	var lastF ast.Expr
	ff := func(n interface{}) {
		ptr, ok := n.(*ast.Expr)
		if !ok {
			return
		}
		nn := *ptr

		// The child node was just walked and possibly replaced.
		// If it was replaced and this is a negation, replace with fnot(p).
		not, ok := nn.(*ast.UnaryExpr)
		if ok && not.Op == token.NOT && not.X == lastF {
			*ptr = fnot(nn.Pos())
			return
		}
		if refersTo(nn, x) {
			lastF = f(nn.Pos())
			*ptr = lastF
		}
	}
	for _, n := range scope {
		walk(n, ff)
	}
}

// assignsTo returns true if any of the code in scope assigns to or takes the address of x.
func assignsTo(x *ast.Ident, scope []ast.Stmt) bool {
	assigned := false
	ff := func(n interface{}) {
		if assigned {
			return
		}
		switch n := n.(type) {
		case *ast.UnaryExpr:
			// use of &x
			if n.Op == token.AND && refersTo(n.X, x) {
				assigned = true
				return
			}
		case *ast.AssignStmt:
			for _, l := range n.Lhs {
				if refersTo(l, x) {
					assigned = true
					return
				}
			}
		}
	}
	for _, n := range scope {
		if assigned {
			break
		}
		walk(n, ff)
	}
	return assigned
}

// newPkgDot returns an ast.Expr referring to "pkg.name" at position pos.
func newPkgDot(pos token.Pos, pkg, name string) ast.Expr {
	return &ast.SelectorExpr{
		X: &ast.Ident{
			NamePos: pos,
			Name:    pkg,
		},
		Sel: &ast.Ident{
			NamePos: pos,
			Name:    name,
		},
	}
}

// renameTop renames all references to the top-level name old.
// It returns true if it makes any changes.
func renameTop(f *ast.File, old, new string) bool {
	var fixed bool

	// Rename any conflicting imports
	// (assuming package name is last element of path).
	for _, s := range f.Imports {
		if s.Name != nil {
			if s.Name.Name == old {
				s.Name.Name = new
				fixed = true
			}
		} else {
			_, thisName := path.Split(importPath(s))
			if thisName == old {
				s.Name = ast.NewIdent(new)
				fixed = true
			}
		}
	}

	// Rename any top-level declarations.
	for _, d := range f.Decls {
		switch d := d.(type) {
		case *ast.FuncDecl:
			if d.Recv == nil && d.Name.Name == old {
				d.Name.Name = new
				d.Name.Obj.Name = new
				fixed = true
			}
		case *ast.GenDecl:
			for _, s := range d.Specs {
				switch s := s.(type) {
				case *ast.TypeSpec:
					if s.Name.Name == old {
						s.Name.Name = new
						s.Name.Obj.Name = new
						fixed = true
					}
				case *ast.ValueSpec:
					for _, n := range s.Names {
						if n.Name == old {
							n.Name = new
							n.Obj.Name = new
							fixed = true
						}
					}
				}
			}
		}
	}

	// Rename top-level old to new, both unresolved names
	// (probably defined in another file) and names that resolve
	// to a declaration we renamed.
	walk(f, func(n interface{}) {
		id, ok := n.(*ast.Ident)
		if ok && isTopName(id, old) {
			id.Name = new
			fixed = true
		}
		if ok && id.Obj != nil && id.Name == old && id.Obj.Name == new {
			id.Name = id.Obj.Name
			fixed = true
		}
	})

	return fixed
}

// matchLen returns the length of the longest prefix shared by x and y.
func matchLen(x, y string) int {
	i := 0
	for i < len(x) && i < len(y) && x[i] == y[i] {
		i++
	}
	return i
}

// addImport adds the import path to the file f, if absent.
func addImport(f *ast.File, ipath string) (added bool) {
	if imports(f, ipath) {
		return false
	}

	// Determine name of import.
	// Assume added imports follow convention of using last element.
	_, name := path.Split(ipath)

	// Rename any conflicting top-level references from name to name_.
	renameTop(f, name, name+"_")

	newImport := &ast.ImportSpec{
		Path: &ast.BasicLit{
			Kind:  token.STRING,
			Value: strconv.Quote(ipath),
		},
	}

	// Find an import decl to add to.
	var (
		bestMatch  = -1
		lastImport = -1
		impDecl    *ast.GenDecl
		impIndex   = -1
	)
	for i, decl := range f.Decls {
		gen, ok := decl.(*ast.GenDecl)
		if ok && gen.Tok == token.IMPORT {
			lastImport = i
			// Do not add to import "C", to avoid disrupting the
			// association with its doc comment, breaking cgo.
			if declImports(gen, "C") {
				continue
			}

			// Compute longest shared prefix with imports in this block.
			for j, spec := range gen.Specs {
				impspec := spec.(*ast.ImportSpec)
				n := matchLen(importPath(impspec), ipath)
				if n > bestMatch {
					bestMatch = n
					impDecl = gen
					impIndex = j
				}
			}
		}
	}

	// If no import decl found, add one after the last import.
	if impDecl == nil {
		impDecl = &ast.GenDecl{
			Tok: token.IMPORT,
		}
		f.Decls = append(f.Decls, nil)
		copy(f.Decls[lastImport+2:], f.Decls[lastImport+1:])
		f.Decls[lastImport+1] = impDecl
	}

	// Ensure the import decl has parentheses, if needed.
	if len(impDecl.Specs) > 0 && !impDecl.Lparen.IsValid() {
		impDecl.Lparen = impDecl.Pos()
	}

	insertAt := impIndex + 1
	if insertAt == 0 {
		insertAt = len(impDecl.Specs)
	}
	impDecl.Specs = append(impDecl.Specs, nil)
	copy(impDecl.Specs[insertAt+1:], impDecl.Specs[insertAt:])
	impDecl.Specs[insertAt] = newImport
	if insertAt > 0 {
		// Assign same position as the previous import,
		// so that the sorter sees it as being in the same block.
		prev := impDecl.Specs[insertAt-1]
		newImport.Path.ValuePos = prev.Pos()
		newImport.EndPos = prev.Pos()
	}

	f.Imports = append(f.Imports, newImport)
	return true
}

// deleteImport deletes the import path from the file f, if present.
func deleteImport(f *ast.File, path string) (deleted bool) {
	oldImport := importSpec(f, path)

	// Find the import node that imports path, if any.
	for i, decl := range f.Decls {
		gen, ok := decl.(*ast.GenDecl)
		if !ok || gen.Tok != token.IMPORT {
			continue
		}
		for j, spec := range gen.Specs {
			impspec := spec.(*ast.ImportSpec)
			if oldImport != impspec {
				continue
			}

			// We found an import spec that imports path.
			// Delete it.
			deleted = true
			copy(gen.Specs[j:], gen.Specs[j+1:])
			gen.Specs = gen.Specs[:len(gen.Specs)-1]

			// If this was the last import spec in this decl,
			// delete the decl, too.
			if len(gen.Specs) == 0 {
				copy(f.Decls[i:], f.Decls[i+1:])
				f.Decls = f.Decls[:len(f.Decls)-1]
			} else if len(gen.Specs) == 1 {
				gen.Lparen = token.NoPos // drop parens
			}
			if j > 0 {
				// We deleted an entry but now there will be
				// a blank line-sized hole where the import was.
				// Close the hole by making the previous
				// import appear to "end" where this one did.
				gen.Specs[j-1].(*ast.ImportSpec).EndPos = impspec.End()
			}
			break
		}
	}

	// Delete it from f.Imports.
	for i, imp := range f.Imports {
		if imp == oldImport {
			copy(f.Imports[i:], f.Imports[i+1:])
			f.Imports = f.Imports[:len(f.Imports)-1]
			break
		}
	}

	return
}

// rewriteImport rewrites any import of path oldPath to path newPath.
func rewriteImport(f *ast.File, oldPath, newPath string) (rewrote bool) {
	for _, imp := range f.Imports {
		if importPath(imp) == oldPath {
			rewrote = true
			// record old End, because the default is to compute
			// it using the length of imp.Path.Value.
			imp.EndPos = imp.End()
			imp.Path.Value = strconv.Quote(newPath)
		}
	}
	return
}

func usesImport(f *ast.File, path string) (used bool) {
	spec := importSpec(f, path)
	if spec == nil {
		return
	}

	name := spec.Name.String()
	switch name {
	case "<nil>":
		// If the package name is not explicitly specified,
		// make an educated guess. This is not guaranteed to be correct.
		lastSlash := strings.LastIndex(path, "/")
		if lastSlash == -1 {
			name = path
		} else {
			name = path[lastSlash+1:]
		}
	case "_", ".":
		// Not sure if this import is used - err on the side of caution.
		return true
	}

	walk(f, func(n interface{}) {
		sel, ok := n.(*ast.SelectorExpr)
		if ok && isTopName(sel.X, name) {
			used = true
		}
	})

	return
}

func expr(s string) ast.Expr {
	x, err := parser.ParseExpr(s)
	if err != nil {
		panic("parsing " + s + ": " + err.Error())
	}
	// Remove position information to avoid spurious newlines.
	killPos(reflect.ValueOf(x))
	return x
}

var posType = reflect.TypeOf(token.Pos(0))

func killPos(v reflect.Value) {
	switch v.Kind() {
	case reflect.Ptr, reflect.Interface:
		if !v.IsNil() {
			killPos(v.Elem())
		}
	case reflect.Slice:
		n := v.Len()
		for i := 0; i < n; i++ {
			killPos(v.Index(i))
		}
	case reflect.Struct:
		n := v.NumField()
		for i := 0; i < n; i++ {
			f := v.Field(i)
			if f.Type() == posType {
				f.SetInt(0)
				continue
			}
			killPos(f)
		}
	}
}

// A Rename describes a single renaming.
type rename struct {
	OldImport string // only apply rename if this import is present
	NewImport string // add this import during rewrite
	Old       string // old name: p.T or *p.T
	New       string // new name: p.T or *p.T
}

func renameFix(tab []rename) func(*ast.File) bool {
	return func(f *ast.File) bool {
		return renameFixTab(f, tab)
	}
}

func parseName(s string) (ptr bool, pkg, nam string) {
	i := strings.Index(s, ".")
	if i < 0 {
		panic("parseName: invalid name " + s)
	}
	if strings.HasPrefix(s, "*") {
		ptr = true
		s = s[1:]
		i--
	}
	pkg = s[:i]
	nam = s[i+1:]
	return
}

func renameFixTab(f *ast.File, tab []rename) bool {
	fixed := false
	added := map[string]bool{}
	check := map[string]bool{}
	for _, t := range tab {
		if !imports(f, t.OldImport) {
			continue
		}
		optr, opkg, onam := parseName(t.Old)
		walk(f, func(n interface{}) {
			np, ok := n.(*ast.Expr)
			if !ok {
				return
			}
			x := *np
			if optr {
				p, ok := x.(*ast.StarExpr)
				if !ok {
					return
				}
				x = p.X
			}
			if !isPkgDot(x, opkg, onam) {
				return
			}
			if t.NewImport != "" && !added[t.NewImport] {
				addImport(f, t.NewImport)
				added[t.NewImport] = true
			}
			*np = expr(t.New)
			check[t.OldImport] = true
			fixed = true
		})
	}

	for ipath := range check {
		if !usesImport(f, ipath) {
			deleteImport(f, ipath)
		}
	}
	return fixed
}


text:
// Copyright 2015 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

// Program aebundler turns a Go app into a fully self-contained tar file.
// The app and its subdirectories (if any) are placed under "."
// and the dependencies from $GOPATH are placed under ./_gopath/src.
// A main func is synthesized if one does not exist.
//
// A sample Dockerfile to be used with this bundler could look like this:
//     FROM gcr.io/google_appengine/go-compat
//     ADD . /app
//     RUN GOPATH=/app/_gopath go build -tags appenginevm -o /app/_ah/exe
package main

import (
	"archive/tar"
	"flag"
	"fmt"
	"go/ast"
	"go/build"
	"go/parser"
	"go/token"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
)

var (
	output  = flag.String("o", "", "name of output tar file or '-' for stdout")
	rootDir = flag.String("root", ".", "directory name of application root")
	vm      = flag.Bool("vm", true, `bundle an app for App Engine "flexible environment"`)

	skipFiles = map[string]bool{
		".git":        true,
		".gitconfig":  true,
		".hg":         true,
		".travis.yml": true,
	}
)

const (
	newMain = `package main
import "google.golang.org/appengine"
func main() {
	appengine.Main()
}
`
)

func usage() {
	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
	fmt.Fprintf(os.Stderr, "\t%s -o <file.tar|->\tBundle app to named tar file or stdout\n", os.Args[0])
	fmt.Fprintf(os.Stderr, "\noptional arguments:\n")
	flag.PrintDefaults()
}

func main() {
	flag.Usage = usage
	flag.Parse()

	var tags []string
	if *vm {
		tags = append(tags, "appenginevm")
	} else {
		tags = append(tags, "appengine")
	}

	tarFile := *output
	if tarFile == "" {
		usage()
		errorf("Required -o flag not specified.")
	}

	app, err := analyze(tags)
	if err != nil {
		errorf("Error analyzing app: %v", err)
	}
	if err := app.bundle(tarFile); err != nil {
		errorf("Unable to bundle app: %v", err)
	}
}

// errorf prints the error message and exits.
func errorf(format string, a ...interface{}) {
	fmt.Fprintf(os.Stderr, "aebundler: "+format+"\n", a...)
	os.Exit(1)
}

type app struct {
	hasMain  bool
	appFiles []string
	imports  map[string]string
}

// analyze checks the app for building with the given build tags and returns hasMain,
// app files, and a map of full directory import names to original import names.
func analyze(tags []string) (*app, error) {
	ctxt := buildContext(tags)
	hasMain, appFiles, err := checkMain(ctxt)
	if err != nil {
		return nil, err
	}
	gopath := filepath.SplitList(ctxt.GOPATH)
	im, err := imports(ctxt, *rootDir, gopath)
	return &app{
		hasMain:  hasMain,
		appFiles: appFiles,
		imports:  im,
	}, err
}

// buildContext returns the context for building the source.
func buildContext(tags []string) *build.Context {
	return &build.Context{
		GOARCH:    build.Default.GOARCH,
		GOOS:      build.Default.GOOS,
		GOROOT:    build.Default.GOROOT,
		GOPATH:    build.Default.GOPATH,
		Compiler:  build.Default.Compiler,
		BuildTags: append(build.Default.BuildTags, tags...),
	}
}

// bundle bundles the app into the named tarFile ("-"==stdout).
func (s *app) bundle(tarFile string) (err error) {
	var out io.Writer
	if tarFile == "-" {
		out = os.Stdout
	} else {
		f, err := os.Create(tarFile)
		if err != nil {
			return err
		}
		defer func() {
			if cerr := f.Close(); err == nil {
				err = cerr
			}
		}()
		out = f
	}
	tw := tar.NewWriter(out)

	for srcDir, importName := range s.imports {
		dstDir := "_gopath/src/" + importName
		if err = copyTree(tw, dstDir, srcDir); err != nil {
			return fmt.Errorf("unable to copy directory %v to %v: %v", srcDir, dstDir, err)
		}
	}
	if err := copyTree(tw, ".", *rootDir); err != nil {
		return fmt.Errorf("unable to copy root directory to /app: %v", err)
	}
	if !s.hasMain {
		if err := synthesizeMain(tw, s.appFiles); err != nil {
			return fmt.Errorf("unable to synthesize new main func: %v", err)
		}
	}

	if err := tw.Close(); err != nil {
		return fmt.Errorf("unable to close tar file %v: %v", tarFile, err)
	}
	return nil
}

// synthesizeMain generates a new main func and writes it to the tarball.
func synthesizeMain(tw *tar.Writer, appFiles []string) error {
	appMap := make(map[string]bool)
	for _, f := range appFiles {
		appMap[f] = true
	}
	var f string
	for i := 0; i < 100; i++ {
		f = fmt.Sprintf("app_main%d.go", i)
		if !appMap[filepath.Join(*rootDir, f)] {
			break
		}
	}
	if appMap[filepath.Join(*rootDir, f)] {
		return fmt.Errorf("unable to find unique name for %v", f)
	}
	hdr := &tar.Header{
		Name: f,
		Mode: 0644,
		Size: int64(len(newMain)),
	}
	if err := tw.WriteHeader(hdr); err != nil {
		return fmt.Errorf("unable to write header for %v: %v", f, err)
	}
	if _, err := tw.Write([]byte(newMain)); err != nil {
		return fmt.Errorf("unable to write %v to tar file: %v", f, err)
	}
	return nil
}

// imports returns a map of all import directories (recursively) used by the app.
// The return value maps full directory names to original import names.
func imports(ctxt *build.Context, srcDir string, gopath []string) (map[string]string, error) {
	pkg, err := ctxt.ImportDir(srcDir, 0)
	if err != nil {
		return nil, fmt.Errorf("unable to analyze source: %v", err)
	}

	// Resolve all non-standard-library imports
	result := make(map[string]string)
	for _, v := range pkg.Imports {
		if !strings.Contains(v, ".") {
			continue
		}
		src, err := findInGopath(v, gopath)
		if err != nil {
			return nil, fmt.Errorf("unable to find import %v in gopath %v: %v", v, gopath, err)
		}
		result[src] = v
		im, err := imports(ctxt, src, gopath)
		if err != nil {
			return nil, fmt.Errorf("unable to parse package %v: %v", src, err)
		}
		for k, v := range im {
			result[k] = v
		}
	}
	return result, nil
}

// findInGopath searches the gopath for the named import directory.
func findInGopath(dir string, gopath []string) (string, error) {
	for _, v := range gopath {
		dst := filepath.Join(v, "src", dir)
		if _, err := os.Stat(dst); err == nil {
			return dst, nil
		}
	}
	return "", fmt.Errorf("unable to find package %v in gopath %v", dir, gopath)
}

// copyTree copies srcDir to tar file dstDir, ignoring skipFiles.
func copyTree(tw *tar.Writer, dstDir, srcDir string) error {
	entries, err := ioutil.ReadDir(srcDir)
	if err != nil {
		return fmt.Errorf("unable to read dir %v: %v", srcDir, err)
	}
	for _, entry := range entries {
		n := entry.Name()
		if skipFiles[n] {
			continue
		}
		s := filepath.Join(srcDir, n)
		d := filepath.Join(dstDir, n)
		if entry.IsDir() {
			if err := copyTree(tw, d, s); err != nil {
				return fmt.Errorf("unable to copy dir %v to %v: %v", s, d, err)
			}
			continue
		}
		if err := copyFile(tw, d, s); err != nil {
			return fmt.Errorf("unable to copy dir %v to %v: %v", s, d, err)
		}
	}
	return nil
}

// copyFile copies src to tar file dst.
func copyFile(tw *tar.Writer, dst, src string) error {
	s, err := os.Open(src)
	if err != nil {
		return fmt.Errorf("unable to open %v: %v", src, err)
	}
	defer s.Close()
	fi, err := s.Stat()
	if err != nil {
		return fmt.Errorf("unable to stat %v: %v", src, err)
	}

	hdr, err := tar.FileInfoHeader(fi, dst)
	if err != nil {
		return fmt.Errorf("unable to create tar header for %v: %v", dst, err)
	}
	hdr.Name = dst
	if err := tw.WriteHeader(hdr); err != nil {
		return fmt.Errorf("unable to write header for %v: %v", dst, err)
	}
	_, err = io.Copy(tw, s)
	if err != nil {
		return fmt.Errorf("unable to copy %v to %v: %v", src, dst, err)
	}
	return nil
}

// checkMain verifies that there is a single "main" function.
// It also returns a list of all Go source files in the app.
func checkMain(ctxt *build.Context) (bool, []string, error) {
	pkg, err := ctxt.ImportDir(*rootDir, 0)
	if err != nil {
		return false, nil, fmt.Errorf("unable to analyze source: %v", err)
	}
	if !pkg.IsCommand() {
		errorf("Your app's package needs to be changed from %q to \"main\".\n", pkg.Name)
	}
	// Search for a "func main"
	var hasMain bool
	var appFiles []string
	for _, f := range pkg.GoFiles {
		n := filepath.Join(*rootDir, f)
		appFiles = append(appFiles, n)
		if hasMain, err = readFile(n); err != nil {
			return false, nil, fmt.Errorf("error parsing %q: %v", n, err)
		}
	}
	return hasMain, appFiles, nil
}

// isMain returns whether the given function declaration is a main function.
// Such a function must be called "main", not have a receiver, and have no arguments or return types.
func isMain(f *ast.FuncDecl) bool {
	ft := f.Type
	return f.Name.Name == "main" && f.Recv == nil && ft.Params.NumFields() == 0 && ft.Results.NumFields() == 0
}

// readFile reads and parses the Go source code file and returns whether it has a main function.
func readFile(filename string) (hasMain bool, err error) {
	var src []byte
	src, err = ioutil.ReadFile(filename)
	if err != nil {
		return
	}
	fset := token.NewFileSet()
	file, err := parser.ParseFile(fset, filename, src, 0)
	for _, decl := range file.Decls {
		funcDecl, ok := decl.(*ast.FuncDecl)
		if !ok {
			continue
		}
		if !isMain(funcDecl) {
			continue
		}
		hasMain = true
		break
	}
	return
}

repo_name: dan-v/dosxvpn

repo_language: Go

mime_type: text/x-shellscript


text:
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

/*
Package mail provides the means of sending email from an
App Engine application.

Example:
	msg := &mail.Message{
		Sender:  "romeo@montague.com",
		To:      []string{"Juliet <juliet@capulet.org>"},
		Subject: "See you tonight",
		Body:    "Don't forget our plans. Hark, 'til later.",
	}
	if err := mail.Send(c, msg); err != nil {
		log.Errorf(c, "Alas, my user, the email failed to sendeth: %v", err)
	}
*/
package mail // import "google.golang.org/appengine/mail"

import (
	"net/mail"

	"github.com/golang/protobuf/proto"
	"golang.org/x/net/context"

	"google.golang.org/appengine/internal"
	bpb "google.golang.org/appengine/internal/base"
	pb "google.golang.org/appengine/internal/mail"
)

// A Message represents an email message.
// Addresses may be of any form permitted by RFC 822.
type Message struct {
	// Sender must be set, and must be either an application admin
	// or the currently signed-in user.
	Sender  string
	ReplyTo string // may be empty

	// At least one of these slices must have a non-zero length,
	// except when calling SendToAdmins.
	To, Cc, Bcc []string

	Subject string

	// At least one of Body or HTMLBody must be non-empty.
	Body     string
	HTMLBody string

	Attachments []Attachment

	// Extra mail headers.
	// See https://cloud.google.com/appengine/docs/go/mail/
	// for permissible headers.
	Headers mail.Header
}

// An Attachment represents an email attachment.
type Attachment struct {
	// Name must be set to a valid file name.
	Name      string
	Data      []byte
	ContentID string
}

// Send sends an email message.
func Send(c context.Context, msg *Message) error {
	return send(c, "Send", msg)
}

// SendToAdmins sends an email message to the application's administrators.
func SendToAdmins(c context.Context, msg *Message) error {
	return send(c, "SendToAdmins", msg)
}

func send(c context.Context, method string, msg *Message) error {
	req := &pb.MailMessage{
		Sender:  &msg.Sender,
		To:      msg.To,
		Cc:      msg.Cc,
		Bcc:     msg.Bcc,
		Subject: &msg.Subject,
	}
	if msg.ReplyTo != "" {
		req.ReplyTo = &msg.ReplyTo
	}
	if msg.Body != "" {
		req.TextBody = &msg.Body
	}
	if msg.HTMLBody != "" {
		req.HtmlBody = &msg.HTMLBody
	}
	if len(msg.Attachments) > 0 {
		req.Attachment = make([]*pb.MailAttachment, len(msg.Attachments))
		for i, att := range msg.Attachments {
			req.Attachment[i] = &pb.MailAttachment{
				FileName: proto.String(att.Name),
				Data:     att.Data,
			}
			if att.ContentID != "" {
				req.Attachment[i].ContentID = proto.String(att.ContentID)
			}
		}
	}
	for key, vs := range msg.Headers {
		for _, v := range vs {
			req.Header = append(req.Header, &pb.MailHeader{
				Name:  proto.String(key),
				Value: proto.String(v),
			})
		}
	}
	res := &bpb.VoidProto{}
	if err := internal.Call(c, "mail", method, req, res); err != nil {
		return err
	}
	return nil
}

func init() {
	internal.RegisterErrorCodeMap("mail", pb.MailServiceError_ErrorCode_name)
}


text:
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

package mail

import (
	"testing"

	"github.com/golang/protobuf/proto"

	"google.golang.org/appengine/internal/aetesting"
	basepb "google.golang.org/appengine/internal/base"
	pb "google.golang.org/appengine/internal/mail"
)

func TestMessageConstruction(t *testing.T) {
	var got *pb.MailMessage
	c := aetesting.FakeSingleContext(t, "mail", "Send", func(in *pb.MailMessage, out *basepb.VoidProto) error {
		got = in
		return nil
	})

	msg := &Message{
		Sender: "dsymonds@example.com",
		To:     []string{"nigeltao@example.com"},
		Body:   "Hey, lunch time?",
		Attachments: []Attachment{
			// Regression test for a prod bug. The address of a range variable was used when
			// constructing the outgoing proto, so multiple attachments used the same name.
			{
				Name:      "att1.txt",
				Data:      []byte("data1"),
				ContentID: "<att1>",
			},
			{
				Name: "att2.txt",
				Data: []byte("data2"),
			},
		},
	}
	if err := Send(c, msg); err != nil {
		t.Fatalf("Send: %v", err)
	}
	want := &pb.MailMessage{
		Sender:   proto.String("dsymonds@example.com"),
		To:       []string{"nigeltao@example.com"},
		Subject:  proto.String(""),
		TextBody: proto.String("Hey, lunch time?"),
		Attachment: []*pb.MailAttachment{
			{
				FileName:  proto.String("att1.txt"),
				Data:      []byte("data1"),
				ContentID: proto.String("<att1>"),
			},
			{
				FileName: proto.String("att2.txt"),
				Data:     []byte("data2"),
			},
		},
	}
	if !proto.Equal(got, want) {
		t.Errorf("Bad proto for %+v\n got %v\nwant %v", msg, got, want)
	}
}


text:
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

/*
Package capability exposes information about outages and scheduled downtime
for specific API capabilities.

This package does not work in App Engine "flexible environment".

Example:
	if !capability.Enabled(c, "datastore_v3", "write") {
		// show user a different page
	}
*/
package capability // import "google.golang.org/appengine/capability"

import (
	"golang.org/x/net/context"

	"google.golang.org/appengine/internal"
	"google.golang.org/appengine/log"

	pb "google.golang.org/appengine/internal/capability"
)

// Enabled returns whether an API's capabilities are enabled.
// The wildcard "*" capability matches every capability of an API.
// If the underlying RPC fails (if the package is unknown, for example),
// false is returned and information is written to the application log.
func Enabled(ctx context.Context, api, capability string) bool {
	req := &pb.IsEnabledRequest{
		Package:    &api,
		Capability: []string{capability},
	}
	res := &pb.IsEnabledResponse{}
	if err := internal.Call(ctx, "capability_service", "IsEnabled", req, res); err != nil {
		log.Warningf(ctx, "capability.Enabled: RPC failed: %v", err)
		return false
	}
	switch *res.SummaryStatus {
	case pb.IsEnabledResponse_ENABLED,
		pb.IsEnabledResponse_SCHEDULED_FUTURE,
		pb.IsEnabledResponse_SCHEDULED_NOW:
		return true
	case pb.IsEnabledResponse_UNKNOWN:
		log.Errorf(ctx, "capability.Enabled: unknown API capability %s/%s", api, capability)
		return false
	default:
		return false
	}
}


text:
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

/*
Package xmpp provides the means to send and receive instant messages
to and from users of XMPP-compatible services.

To send a message,
	m := &xmpp.Message{
		To:   []string{"kaylee@example.com"},
		Body: `Hi! How's the carrot?`,
	}
	err := m.Send(c)

To receive messages,
	func init() {
		xmpp.Handle(handleChat)
	}

	func handleChat(c context.Context, m *xmpp.Message) {
		// ...
	}
*/
package xmpp // import "google.golang.org/appengine/xmpp"

import (
	"errors"
	"fmt"
	"net/http"

	"golang.org/x/net/context"

	"google.golang.org/appengine"
	"google.golang.org/appengine/internal"
	pb "google.golang.org/appengine/internal/xmpp"
)

// Message represents an incoming chat message.
type Message struct {
	// Sender is the JID of the sender.
	// Optional for outgoing messages.
	Sender string

	// To is the intended recipients of the message.
	// Incoming messages will have exactly one element.
	To []string

	// Body is the body of the message.
	Body string

	// Type is the message type, per RFC 3921.
	// It defaults to "chat".
	Type string

	// RawXML is whether the body contains raw XML.
	RawXML bool
}

// Presence represents an outgoing presence update.
type Presence struct {
	// Sender is the JID (optional).
	Sender string

	// The intended recipient of the presence update.
	To string

	// Type, per RFC 3921 (optional). Defaults to "available".
	Type string

	// State of presence (optional).
	// Valid values: "away", "chat", "xa", "dnd" (RFC 3921).
	State string

	// Free text status message (optional).
	Status string
}

var (
	ErrPresenceUnavailable = errors.New("xmpp: presence unavailable")
	ErrInvalidJID          = errors.New("xmpp: invalid JID")
)

// Handle arranges for f to be called for incoming XMPP messages.
// Only messages of type "chat" or "normal" will be handled.
func Handle(f func(c context.Context, m *Message)) {
	http.HandleFunc("/_ah/xmpp/message/chat/", func(_ http.ResponseWriter, r *http.Request) {
		f(appengine.NewContext(r), &Message{
			Sender: r.FormValue("from"),
			To:     []string{r.FormValue("to")},
			Body:   r.FormValue("body"),
		})
	})
}

// Send sends a message.
// If any failures occur with specific recipients, the error will be an appengine.MultiError.
func (m *Message) Send(c context.Context) error {
	req := &pb.XmppMessageRequest{
		Jid:    m.To,
		Body:   &m.Body,
		RawXml: &m.RawXML,
	}
	if m.Type != "" && m.Type != "chat" {
		req.Type = &m.Type
	}
	if m.Sender != "" {
		req.FromJid = &m.Sender
	}
	res := &pb.XmppMessageResponse{}
	if err := internal.Call(c, "xmpp", "SendMessage", req, res); err != nil {
		return err
	}

	if len(res.Status) != len(req.Jid) {
		return fmt.Errorf("xmpp: sent message to %d JIDs, but only got %d statuses back", len(req.Jid), len(res.Status))
	}
	me, any := make(appengine.MultiError, len(req.Jid)), false
	for i, st := range res.Status {
		if st != pb.XmppMessageResponse_NO_ERROR {
			me[i] = errors.New(st.String())
			any = true
		}
	}
	if any {
		return me
	}
	return nil
}

// Invite sends an invitation. If the from address is an empty string
// the default (yourapp@appspot.com/bot) will be used.
func Invite(c context.Context, to, from string) error {
	req := &pb.XmppInviteRequest{
		Jid: &to,
	}
	if from != "" {
		req.FromJid = &from
	}
	res := &pb.XmppInviteResponse{}
	return internal.Call(c, "xmpp", "SendInvite", req, res)
}

// Send sends a presence update.
func (p *Presence) Send(c context.Context) error {
	req := &pb.XmppSendPresenceRequest{
		Jid: &p.To,
	}
	if p.State != "" {
		req.Show = &p.State
	}
	if p.Type != "" {
		req.Type = &p.Type
	}
	if p.Sender != "" {
		req.FromJid = &p.Sender
	}
	if p.Status != "" {
		req.Status = &p.Status
	}
	res := &pb.XmppSendPresenceResponse{}
	return internal.Call(c, "xmpp", "SendPresence", req, res)
}

var presenceMap = map[pb.PresenceResponse_SHOW]string{
	pb.PresenceResponse_NORMAL:         "",
	pb.PresenceResponse_AWAY:           "away",
	pb.PresenceResponse_DO_NOT_DISTURB: "dnd",
	pb.PresenceResponse_CHAT:           "chat",
	pb.PresenceResponse_EXTENDED_AWAY:  "xa",
}

// GetPresence retrieves a user's presence.
// If the from address is an empty string the default
// (yourapp@appspot.com/bot) will be used.
// Possible return values are "", "away", "dnd", "chat", "xa".
// ErrPresenceUnavailable is returned if the presence is unavailable.
func GetPresence(c context.Context, to string, from string) (string, error) {
	req := &pb.PresenceRequest{
		Jid: &to,
	}
	if from != "" {
		req.FromJid = &from
	}
	res := &pb.PresenceResponse{}
	if err := internal.Call(c, "xmpp", "GetPresence", req, res); err != nil {
		return "", err
	}
	if !*res.IsAvailable || res.Presence == nil {
		return "", ErrPresenceUnavailable
	}
	presence, ok := presenceMap[*res.Presence]
	if ok {
		return presence, nil
	}
	return "", fmt.Errorf("xmpp: unknown presence %v", *res.Presence)
}

// GetPresenceMulti retrieves multiple users' presence.
// If the from address is an empty string the default
// (yourapp@appspot.com/bot) will be used.
// Possible return values are "", "away", "dnd", "chat", "xa".
// If any presence is unavailable, an appengine.MultiError is returned
func GetPresenceMulti(c context.Context, to []string, from string) ([]string, error) {
	req := &pb.BulkPresenceRequest{
		Jid: to,
	}
	if from != "" {
		req.FromJid = &from
	}
	res := &pb.BulkPresenceResponse{}

	if err := internal.Call(c, "xmpp", "BulkGetPresence", req, res); err != nil {
		return nil, err
	}

	presences := make([]string, 0, len(res.PresenceResponse))
	errs := appengine.MultiError{}

	addResult := func(presence string, err error) {
		presences = append(presences, presence)
		errs = append(errs, err)
	}

	anyErr := false
	for _, subres := range res.PresenceResponse {
		if !subres.GetValid() {
			anyErr = true
			addResult("", ErrInvalidJID)
			continue
		}
		if !*subres.IsAvailable || subres.Presence == nil {
			anyErr = true
			addResult("", ErrPresenceUnavailable)
			continue
		}
		presence, ok := presenceMap[*subres.Presence]
		if ok {
			addResult(presence, nil)
		} else {
			anyErr = true
			addResult("", fmt.Errorf("xmpp: unknown presence %q", *subres.Presence))
		}
	}
	if anyErr {
		return presences, errs
	}
	return presences, nil
}

func init() {
	internal.RegisterErrorCodeMap("xmpp", pb.XmppServiceError_ErrorCode_name)
}


text:
// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

package xmpp

import (
	"fmt"
	"reflect"
	"testing"

	"github.com/golang/protobuf/proto"

	"google.golang.org/appengine"
	"google.golang.org/appengine/internal/aetesting"
	pb "google.golang.org/appengine/internal/xmpp"
)

func newPresenceResponse(isAvailable bool, presence pb.PresenceResponse_SHOW, valid bool) *pb.PresenceResponse {
	return &pb.PresenceResponse{
		IsAvailable: proto.Bool(isAvailable),
		Presence:    presence.Enum(),
		Valid:       proto.Bool(valid),
	}
}

func setPresenceResponse(m *pb.PresenceResponse, isAvailable bool, presence pb.PresenceResponse_SHOW, valid bool) {
	m.IsAvailable = &isAvailable
	m.Presence = presence.Enum()
	m.Valid = &valid
}

func TestGetPresence(t *testing.T) {
	c := aetesting.FakeSingleContext(t, "xmpp", "GetPresence", func(in *pb.PresenceRequest, out *pb.PresenceResponse) error {
		if jid := in.GetJid(); jid != "user@example.com" {
			return fmt.Errorf("bad jid %q", jid)
		}
		setPresenceResponse(out, true, pb.PresenceResponse_CHAT, true)
		return nil
	})

	presence, err := GetPresence(c, "user@example.com", "")
	if err != nil {
		t.Fatalf("GetPresence: %v", err)
	}

	if presence != "chat" {
		t.Errorf("GetPresence: got %#v, want %#v", presence, pb.PresenceResponse_CHAT)
	}
}

func TestGetPresenceMultiSingleJID(t *testing.T) {
	c := aetesting.FakeSingleContext(t, "xmpp", "BulkGetPresence", func(in *pb.BulkPresenceRequest, out *pb.BulkPresenceResponse) error {
		if !reflect.DeepEqual(in.Jid, []string{"user@example.com"}) {
			return fmt.Errorf("bad request jids %#v", in.Jid)
		}
		out.PresenceResponse = []*pb.PresenceResponse{
			newPresenceResponse(true, pb.PresenceResponse_NORMAL, true),
		}
		return nil
	})

	presence, err := GetPresenceMulti(c, []string{"user@example.com"}, "")
	if err != nil {
		t.Fatalf("GetPresenceMulti: %v", err)
	}
	if !reflect.DeepEqual(presence, []string{""}) {
		t.Errorf("GetPresenceMulti: got %s, want %s", presence, []string{""})
	}
}

func TestGetPresenceMultiJID(t *testing.T) {
	c := aetesting.FakeSingleContext(t, "xmpp", "BulkGetPresence", func(in *pb.BulkPresenceRequest, out *pb.BulkPresenceResponse) error {
		if !reflect.DeepEqual(in.Jid, []string{"user@example.com", "user2@example.com"}) {
			return fmt.Errorf("bad request jids %#v", in.Jid)
		}
		out.PresenceResponse = []*pb.PresenceResponse{
			newPresenceResponse(true, pb.PresenceResponse_NORMAL, true),
			newPresenceResponse(true, pb.PresenceResponse_AWAY, true),
		}
		return nil
	})

	jids := []string{"user@example.com", "user2@example.com"}
	presence, err := GetPresenceMulti(c, jids, "")
	if err != nil {
		t.Fatalf("GetPresenceMulti: %v", err)
	}
	want := []string{"", "away"}
	if !reflect.DeepEqual(presence, want) {
		t.Errorf("GetPresenceMulti: got %v, want %v", presence, want)
	}
}

func TestGetPresenceMultiFromJID(t *testing.T) {
	c := aetesting.FakeSingleContext(t, "xmpp", "BulkGetPresence", func(in *pb.BulkPresenceRequest, out *pb.BulkPresenceResponse) error {
		if !reflect.DeepEqual(in.Jid, []string{"user@example.com", "user2@example.com"}) {
			return fmt.Errorf("bad request jids %#v", in.Jid)
		}
		if jid := in.GetFromJid(); jid != "bot@appspot.com" {
			return fmt.Errorf("bad from jid %q", jid)
		}
		out.PresenceResponse = []*pb.PresenceResponse{
			newPresenceResponse(true, pb.PresenceResponse_NORMAL, true),
			newPresenceResponse(true, pb.PresenceResponse_CHAT, true),
		}
		return nil
	})

	jids := []string{"user@example.com", "user2@example.com"}
	presence, err := GetPresenceMulti(c, jids, "bot@appspot.com")
	if err != nil {
		t.Fatalf("GetPresenceMulti: %v", err)
	}
	want := []string{"", "chat"}
	if !reflect.DeepEqual(presence, want) {
		t.Errorf("GetPresenceMulti: got %v, want %v", presence, want)
	}
}

func TestGetPresenceMultiInvalid(t *testing.T) {
	c := aetesting.FakeSingleContext(t, "xmpp", "BulkGetPresence", func(in *pb.BulkPresenceRequest, out *pb.BulkPresenceResponse) error {
		if !reflect.DeepEqual(in.Jid, []string{"user@example.com", "user2@example.com"}) {
			return fmt.Errorf("bad request jids %#v", in.Jid)
		}
		out.PresenceResponse = []*pb.PresenceResponse{
			newPresenceResponse(true, pb.PresenceResponse_EXTENDED_AWAY, true),
			newPresenceResponse(true, pb.PresenceResponse_CHAT, false),
		}
		return nil
	})

	jids := []string{"user@example.com", "user2@example.com"}
	presence, err := GetPresenceMulti(c, jids, "")

	wantErr := appengine.MultiError{nil, ErrInvalidJID}
	if !reflect.DeepEqual(err, wantErr) {
		t.Fatalf("GetPresenceMulti: got %#v, want %#v", err, wantErr)
	}

	want := []string{"xa", ""}
	if !reflect.DeepEqual(presence, want) {
		t.Errorf("GetPresenceMulti: got %#v, want %#v", presence, want)
	}
}

func TestGetPresenceMultiUnavailable(t *testing.T) {
	c := aetesting.FakeSingleContext(t, "xmpp", "BulkGetPresence", func(in *pb.BulkPresenceRequest, out *pb.BulkPresenceResponse) error {
		if !reflect.DeepEqual(in.Jid, []string{"user@example.com", "user2@example.com"}) {
			return fmt.Errorf("bad request jids %#v", in.Jid)
		}
		out.PresenceResponse = []*pb.PresenceResponse{
			newPresenceResponse(false, pb.PresenceResponse_AWAY, true),
			newPresenceResponse(false, pb.PresenceResponse_DO_NOT_DISTURB, true),
		}
		return nil
	})

	jids := []string{"user@example.com", "user2@example.com"}
	presence, err := GetPresenceMulti(c, jids, "")

	wantErr := appengine.MultiError{
		ErrPresenceUnavailable,
		ErrPresenceUnavailable,
	}
	if !reflect.DeepEqual(err, wantErr) {
		t.Fatalf("GetPresenceMulti: got %#v, want %#v", err, wantErr)
	}
	want := []string{"", ""}
	if !reflect.DeepEqual(presence, want) {
		t.Errorf("GetPresenceMulti: got %#v, want %#v", presence, want)
	}
}


text: issuerepo: golang/go


text:
# Contributing to Go

Go is an open source project.

It is the work of hundreds of contributors. We appreciate your help!

## Filing issues

When [filing an issue](https://golang.org/issue/new), make sure to answer these five questions:

1.  What version of Go are you using (`go version`)?
2.  What operating system and processor architecture are you using?
3.  What did you do?
4.  What did you expect to see?
5.  What did you see instead?

General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker.
The gophers there will answer or ask you to file an issue if you've tripped over a bug.

## Contributing code

Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html)
before sending patches.

Unless otherwise noted, the Go source files are distributed under
the BSD-style license found in the LICENSE file.


text:
# This source code refers to The Go Authors for copyright purposes.
# The master list of authors is in the main Go distribution,
# visible at https://tip.golang.org/AUTHORS.


text:
Additional IP Rights Grant (Patents)

"This implementation" means the copyrightable works distributed by
Google as part of the Go project.

Google hereby grants to You a perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable (except as stated in this section)
patent license to make, have made, use, offer to sell, sell, import,
transfer and otherwise run, modify and propagate the contents of this
implementation of Go, where such license applies only to those patent
claims, both currently owned or controlled by Google and acquired in
the future, licensable by Google that are necessarily infringed by this
implementation of Go.  This grant does not include claims that would be
infringed only as a consequence of further modification of this
implementation.  If you or your agent or exclusive licensee institute or
order or agree to the institution of patent litigation against any
entity (including a cross-claim or counterclaim in a lawsuit) alleging
that this implementation of Go or any code incorporated within this
implementation of Go constitutes direct or contributory patent
infringement, or inducement of patent infringement, then any patent
rights granted to you under this License for this implementation of Go
shall terminate as of the date such litigation is filed.


text:
# This source code was written by the Go contributors.
# The master list of contributors is in the main Go distribution,
# visible at https://tip.golang.org/CONTRIBUTORS.


text:
# Go Cryptography

This repository holds supplementary Go cryptography libraries.

## Download/Install

The easiest way to install is to run `go get -u golang.org/x/crypto/...`. You
can also manually git clone the repository to `$GOPATH/src/golang.org/x/crypto`.

## Report Issues / Send Patches

This repository uses Gerrit for code changes. To learn how to submit changes to
this repository, see https://golang.org/doc/contribute.html.

The main issue tracker for the crypto repository is located at
https://github.com/golang/go/issues. Prefix your issue with "x/crypto:" in the
subject line, so it is easy to find.

Note that contributions to the cryptography package receive additional scrutiny
due to their sensitive nature. Patches may take longer than normal to receive
feedback.


text:
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package bcrypt

import (
	"bytes"
	"fmt"
	"testing"
)

func TestBcryptingIsEasy(t *testing.T) {
	pass := []byte("mypassword")
	hp, err := GenerateFromPassword(pass, 0)
	if err != nil {
		t.Fatalf("GenerateFromPassword error: %s", err)
	}

	if CompareHashAndPassword(hp, pass) != nil {
		t.Errorf("%v should hash %s correctly", hp, pass)
	}

	notPass := "notthepass"
	err = CompareHashAndPassword(hp, []byte(notPass))
	if err != ErrMismatchedHashAndPassword {
		t.Errorf("%v and %s should be mismatched", hp, notPass)
	}
}

func TestBcryptingIsCorrect(t *testing.T) {
	pass := []byte("allmine")
	salt := []byte("XajjQvNhvvRt5GSeFk1xFe")
	expectedHash := []byte("$2a$10$XajjQvNhvvRt5GSeFk1xFeyqRrsxkhBkUiQeg0dt.wU1qD4aFDcga")

	hash, err := bcrypt(pass, 10, salt)
	if err != nil {
		t.Fatalf("bcrypt blew up: %v", err)
	}
	if !bytes.HasSuffix(expectedHash, hash) {
		t.Errorf("%v should be the suffix of %v", hash, expectedHash)
	}

	h, err := newFromHash(expectedHash)
	if err != nil {
		t.Errorf("Unable to parse %s: %v", string(expectedHash), err)
	}

	// This is not the safe way to compare these hashes. We do this only for
	// testing clarity. Use bcrypt.CompareHashAndPassword()
	if err == nil && !bytes.Equal(expectedHash, h.Hash()) {
		t.Errorf("Parsed hash %v should equal %v", h.Hash(), expectedHash)
	}
}

func TestVeryShortPasswords(t *testing.T) {
	key := []byte("k")
	salt := []byte("XajjQvNhvvRt5GSeFk1xFe")
	_, err := bcrypt(key, 10, salt)
	if err != nil {
		t.Errorf("One byte key resulted in error: %s", err)
	}
}

func TestTooLongPasswordsWork(t *testing.T) {
	salt := []byte("XajjQvNhvvRt5GSeFk1xFe")
	// One byte over the usual 56 byte limit that blowfish has
	tooLongPass := []byte("012345678901234567890123456789012345678901234567890123456")
	tooLongExpected := []byte("$2a$10$XajjQvNhvvRt5GSeFk1xFe5l47dONXg781AmZtd869sO8zfsHuw7C")
	hash, err := bcrypt(tooLongPass, 10, salt)
	if err != nil {
		t.Fatalf("bcrypt blew up on long password: %v", err)
	}
	if !bytes.HasSuffix(tooLongExpected, hash) {
		t.Errorf("%v should be the suffix of %v", hash, tooLongExpected)
	}
}

type InvalidHashTest struct {
	err  error
	hash []byte
}

var invalidTests = []InvalidHashTest{
	{ErrHashTooShort, []byte("$2a$10$fooo")},
	{ErrHashTooShort, []byte("$2a")},
	{HashVersionTooNewError('3'), []byte("$3a$10$sssssssssssssssssssssshhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh")},
	{InvalidHashPrefixError('%'), []byte("%2a$10$sssssssssssssssssssssshhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh")},
	{InvalidCostError(32), []byte("$2a$32$sssssssssssssssssssssshhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh")},
}

func TestInvalidHashErrors(t *testing.T) {
	check := func(name string, expected, err error) {
		if err == nil {
			t.Errorf("%s: Should have returned an error", name)
		}
		if err != nil && err != expected {
			t.Errorf("%s gave err %v but should have given %v", name, err, expected)
		}
	}
	for _, iht := range invalidTests {
		_, err := newFromHash(iht.hash)
		check("newFromHash", iht.err, err)
		err = CompareHashAndPassword(iht.hash, []byte("anything"))
		check("CompareHashAndPassword", iht.err, err)
	}
}

func TestUnpaddedBase64Encoding(t *testing.T) {
	original := []byte{101, 201, 101, 75, 19, 227, 199, 20, 239, 236, 133, 32, 30, 109, 243, 30}
	encodedOriginal := []byte("XajjQvNhvvRt5GSeFk1xFe")

	encoded := base64Encode(original)

	if !bytes.Equal(encodedOriginal, encoded) {
		t.Errorf("Encoded %v should have equaled %v", encoded, encodedOriginal)
	}

	decoded, err := base64Decode(encodedOriginal)
	if err != nil {
		t.Fatalf("base64Decode blew up: %s", err)
	}

	if !bytes.Equal(decoded, original) {
		t.Errorf("Decoded %v should have equaled %v", decoded, original)
	}
}

func TestCost(t *testing.T) {
	suffix := "XajjQvNhvvRt5GSeFk1xFe5l47dONXg781AmZtd869sO8zfsHuw7C"
	for _, vers := range []string{"2a", "2"} {
		for _, cost := range []int{4, 10} {
			s := fmt.Sprintf("$%s$%02d$%s", vers, cost, suffix)
			h := []byte(s)
			actual, err := Cost(h)
			if err != nil {
				t.Errorf("Cost, error: %s", err)
				continue
			}
			if actual != cost {
				t.Errorf("Cost, expected: %d, actual: %d", cost, actual)
			}
		}
	}
	_, err := Cost([]byte("$a$a$" + suffix))
	if err == nil {
		t.Errorf("Cost, malformed but no error returned")
	}
}

func TestCostValidationInHash(t *testing.T) {
	if testing.Short() {
		return
	}

	pass := []byte("mypassword")

	for c := 0; c < MinCost; c++ {
		p, _ := newFromPassword(pass, c)
		if p.cost != DefaultCost {
			t.Errorf("newFromPassword should default costs below %d to %d, but was %d", MinCost, DefaultCost, p.cost)
		}
	}

	p, _ := newFromPassword(pass, 14)
	if p.cost != 14 {
		t.Errorf("newFromPassword should default cost to 14, but was %d", p.cost)
	}

	hp, _ := newFromHash(p.Hash())
	if p.cost != hp.cost {
		t.Errorf("newFromHash should maintain the cost at %d, but was %d", p.cost, hp.cost)
	}

	_, err := newFromPassword(pass, 32)
	if err == nil {
		t.Fatalf("newFromPassword: should return a cost error")
	}
	if err != InvalidCostError(32) {
		t.Errorf("newFromPassword: should return cost error, got %#v", err)
	}
}

func TestCostReturnsWithLeadingZeroes(t *testing.T) {
	hp, _ := newFromPassword([]byte("abcdefgh"), 7)
	cost := hp.Hash()[4:7]
	expected := []byte("07$")

	if !bytes.Equal(expected, cost) {
		t.Errorf("single digit costs in hash should have leading zeros: was %v instead of %v", cost, expected)
	}
}

func TestMinorNotRequired(t *testing.T) {
	noMinorHash := []byte("$2$10$XajjQvNhvvRt5GSeFk1xFeyqRrsxkhBkUiQeg0dt.wU1qD4aFDcga")
	h, err := newFromHash(noMinorHash)
	if err != nil {
		t.Fatalf("No minor hash blew up: %s", err)
	}
	if h.minor != 0 {
		t.Errorf("Should leave minor version at 0, but was %d", h.minor)
	}

	if !bytes.Equal(noMinorHash, h.Hash()) {
		t.Errorf("Should generate hash %v, but created %v", noMinorHash, h.Hash())
	}
}

func BenchmarkEqual(b *testing.B) {
	b.StopTimer()
	passwd := []byte("somepasswordyoulike")
	hash, _ := GenerateFromPassword(passwd, 10)
	b.StartTimer()
	for i := 0; i < b.N; i++ {
		CompareHashAndPassword(hash, passwd)
	}
}

func BenchmarkGeneration(b *testing.B) {
	b.StopTimer()
	passwd := []byte("mylongpassword1234")
	b.StartTimer()
	for i := 0; i < b.N; i++ {
		GenerateFromPassword(passwd, 10)
	}
}

// See Issue https://github.com/golang/go/issues/20425.
func TestNoSideEffectsFromCompare(t *testing.T) {
	source := []byte("passw0rd123456")
	password := source[:len(source)-6]
	token := source[len(source)-6:]
	want := make([]byte, len(source))
	copy(want, source)

	wantHash := []byte("$2a$10$LK9XRuhNxHHCvjX3tdkRKei1QiCDUKrJRhZv7WWZPuQGRUM92rOUa")
	_ = CompareHashAndPassword(wantHash, password)

	got := bytes.Join([][]byte{password, token}, []byte(""))
	if !bytes.Equal(got, want) {
		t.Errorf("got=%q want=%q", got, want)
	}
}


text:
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package bcrypt implements Provos and Mazières's bcrypt adaptive hashing
// algorithm. See http://www.usenix.org/event/usenix99/provos/provos.pdf
package bcrypt // import "golang.org/x/crypto/bcrypt"

// The code is a port of Provos and Mazières's C implementation.
import (
	"crypto/rand"
	"crypto/subtle"
	"errors"
	"fmt"
	"io"
	"strconv"

	"golang.org/x/crypto/blowfish"
)

const (
	MinCost     int = 4  // the minimum allowable cost as passed in to GenerateFromPassword
	MaxCost     int = 31 // the maximum allowable cost as passed in to GenerateFromPassword
	DefaultCost int = 10 // the cost that will actually be set if a cost below MinCost is passed into GenerateFromPassword
)

// The error returned from CompareHashAndPassword when a password and hash do
// not match.
var ErrMismatchedHashAndPassword = errors.New("crypto/bcrypt: hashedPassword is not the hash of the given password")

// The error returned from CompareHashAndPassword when a hash is too short to
// be a bcrypt hash.
var ErrHashTooShort = errors.New("crypto/bcrypt: hashedSecret too short to be a bcrypted password")

// The error returned from CompareHashAndPassword when a hash was created with
// a bcrypt algorithm newer than this implementation.
type HashVersionTooNewError byte

func (hv HashVersionTooNewError) Error() string {
	return fmt.Sprintf("crypto/bcrypt: bcrypt algorithm version '%c' requested is newer than current version '%c'", byte(hv), majorVersion)
}

// The error returned from CompareHashAndPassword when a hash starts with something other than '$'
type InvalidHashPrefixError byte

func (ih InvalidHashPrefixError) Error() string {
	return fmt.Sprintf("crypto/bcrypt: bcrypt hashes must start with '$', but hashedSecret started with '%c'", byte(ih))
}

type InvalidCostError int

func (ic InvalidCostError) Error() string {
	return fmt.Sprintf("crypto/bcrypt: cost %d is outside allowed range (%d,%d)", int(ic), int(MinCost), int(MaxCost))
}

const (
	majorVersion       = '2'
	minorVersion       = 'a'
	maxSaltSize        = 16
	maxCryptedHashSize = 23
	encodedSaltSize    = 22
	encodedHashSize    = 31
	minHashSize        = 59
)

// magicCipherData is an IV for the 64 Blowfish encryption calls in
// bcrypt(). It's the string "OrpheanBeholderScryDoubt" in big-endian bytes.
var magicCipherData = []byte{
	0x4f, 0x72, 0x70, 0x68,
	0x65, 0x61, 0x6e, 0x42,
	0x65, 0x68, 0x6f, 0x6c,
	0x64, 0x65, 0x72, 0x53,
	0x63, 0x72, 0x79, 0x44,
	0x6f, 0x75, 0x62, 0x74,
}

type hashed struct {
	hash  []byte
	salt  []byte
	cost  int // allowed range is MinCost to MaxCost
	major byte
	minor byte
}

// GenerateFromPassword returns the bcrypt hash of the password at the given
// cost. If the cost given is less than MinCost, the cost will be set to
// DefaultCost, instead. Use CompareHashAndPassword, as defined in this package,
// to compare the returned hashed password with its cleartext version.
func GenerateFromPassword(password []byte, cost int) ([]byte, error) {
	p, err := newFromPassword(password, cost)
	if err != nil {
		return nil, err
	}
	return p.Hash(), nil
}

// CompareHashAndPassword compares a bcrypt hashed password with its possible
// plaintext equivalent. Returns nil on success, or an error on failure.
func CompareHashAndPassword(hashedPassword, password []byte) error {
	p, err := newFromHash(hashedPassword)
	if err != nil {
		return err
	}

	otherHash, err := bcrypt(password, p.cost, p.salt)
	if err != nil {
		return err
	}

	otherP := &hashed{otherHash, p.salt, p.cost, p.major, p.minor}
	if subtle.ConstantTimeCompare(p.Hash(), otherP.Hash()) == 1 {
		return nil
	}

	return ErrMismatchedHashAndPassword
}

// Cost returns the hashing cost used to create the given hashed
// password. When, in the future, the hashing cost of a password system needs
// to be increased in order to adjust for greater computational power, this
// function allows one to establish which passwords need to be updated.
func Cost(hashedPassword []byte) (int, error) {
	p, err := newFromHash(hashedPassword)
	if err != nil {
		return 0, err
	}
	return p.cost, nil
}

func newFromPassword(password []byte, cost int) (*hashed, error) {
	if cost < MinCost {
		cost = DefaultCost
	}
	p := new(hashed)
	p.major = majorVersion
	p.minor = minorVersion

	err := checkCost(cost)
	if err != nil {
		return nil, err
	}
	p.cost = cost

	unencodedSalt := make([]byte, maxSaltSize)
	_, err = io.ReadFull(rand.Reader, unencodedSalt)
	if err != nil {
		return nil, err
	}

	p.salt = base64Encode(unencodedSalt)
	hash, err := bcrypt(password, p.cost, p.salt)
	if err != nil {
		return nil, err
	}
	p.hash = hash
	return p, err
}

func newFromHash(hashedSecret []byte) (*hashed, error) {
	if len(hashedSecret) < minHashSize {
		return nil, ErrHashTooShort
	}
	p := new(hashed)
	n, err := p.decodeVersion(hashedSecret)
	if err != nil {
		return nil, err
	}
	hashedSecret = hashedSecret[n:]
	n, err = p.decodeCost(hashedSecret)
	if err != nil {
		return nil, err
	}
	hashedSecret = hashedSecret[n:]

	// The "+2" is here because we'll have to append at most 2 '=' to the salt
	// when base64 decoding it in expensiveBlowfishSetup().
	p.salt = make([]byte, encodedSaltSize, encodedSaltSize+2)
	copy(p.salt, hashedSecret[:encodedSaltSize])

	hashedSecret = hashedSecret[encodedSaltSize:]
	p.hash = make([]byte, len(hashedSecret))
	copy(p.hash, hashedSecret)

	return p, nil
}

func bcrypt(password []byte, cost int, salt []byte) ([]byte, error) {
	cipherData := make([]byte, len(magicCipherData))
	copy(cipherData, magicCipherData)

	c, err := expensiveBlowfishSetup(password, uint32(cost), salt)
	if err != nil {
		return nil, err
	}

	for i := 0; i < 24; i += 8 {
		for j := 0; j < 64; j++ {
			c.Encrypt(cipherData[i:i+8], cipherData[i:i+8])
		}
	}

	// Bug compatibility with C bcrypt implementations. We only encode 23 of
	// the 24 bytes encrypted.
	hsh := base64Encode(cipherData[:maxCryptedHashSize])
	return hsh, nil
}

func expensiveBlowfishSetup(key []byte, cost uint32, salt []byte) (*blowfish.Cipher, error) {
	csalt, err := base64Decode(salt)
	if err != nil {
		return nil, err
	}

	// Bug compatibility with C bcrypt implementations. They use the trailing
	// NULL in the key string during expansion.
	// We copy the key to prevent changing the underlying array.
	ckey := append(key[:len(key):len(key)], 0)

	c, err := blowfish.NewSaltedCipher(ckey, csalt)
	if err != nil {
		return nil, err
	}

	var i, rounds uint64
	rounds = 1 << cost
	for i = 0; i < rounds; i++ {
		blowfish.ExpandKey(ckey, c)
		blowfish.ExpandKey(csalt, c)
	}

	return c, nil
}

func (p *hashed) Hash() []byte {
	arr := make([]byte, 60)
	arr[0] = '$'
	arr[1] = p.major
	n := 2
	if p.minor != 0 {
		arr[2] = p.minor
		n = 3
	}
	arr[n] = '$'
	n++
	copy(arr[n:], []byte(fmt.Sprintf("%02d", p.cost)))
	n += 2
	arr[n] = '$'
	n++
	copy(arr[n:], p.salt)
	n += encodedSaltSize
	copy(arr[n:], p.hash)
	n += encodedHashSize
	return arr[:n]
}

func (p *hashed) decodeVersion(sbytes []byte) (int, error) {
	if sbytes[0] != '$' {
		return -1, InvalidHashPrefixError(sbytes[0])
	}
	if sbytes[1] > majorVersion {
		return -1, HashVersionTooNewError(sbytes[1])
	}
	p.major = sbytes[1]
	n := 3
	if sbytes[2] != '$' {
		p.minor = sbytes[2]
		n++
	}
	return n, nil
}

// sbytes should begin where decodeVersion left off.
func (p *hashed) decodeCost(sbytes []byte) (int, error) {
	cost, err := strconv.Atoi(string(sbytes[0:2]))
	if err != nil {
		return -1, err
	}
	err = checkCost(cost)
	if err != nil {
		return -1, err
	}
	p.cost = cost
	return 3, nil
}

func (p *hashed) String() string {
	return fmt.Sprintf("&{hash: %#v, salt: %#v, cost: %d, major: %c, minor: %c}", string(p.hash), p.salt, p.cost, p.major, p.minor)
}

func checkCost(cost int) error {
	if cost < MinCost || cost > MaxCost {
		return InvalidCostError(cost)
	}
	return nil
}


text:
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package bcrypt

import "encoding/base64"

const alphabet = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"

var bcEncoding = base64.NewEncoding(alphabet)

func base64Encode(src []byte) []byte {
	n := bcEncoding.EncodedLen(len(src))
	dst := make([]byte, n)
	bcEncoding.Encode(dst, src)
	for dst[n-1] == '=' {
		n--
	}
	return dst[:n]
}

func base64Decode(src []byte) ([]byte, error) {
	numOfEquals := 4 - (len(src) % 4)
	for i := 0; i < numOfEquals; i++ {
		src = append(src, '=')
	}

	dst := make([]byte, bcEncoding.DecodedLen(len(src)))
	n, err := bcEncoding.Decode(dst, src)
	if err != nil {
		return nil, err
	}
	return dst[:n], nil
}


text:
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package md4 implements the MD4 hash algorithm as defined in RFC 1320.
package md4 // import "golang.org/x/crypto/md4"

import (
	"crypto"
	"hash"
)

func init() {
	crypto.RegisterHash(crypto.MD4, New)
}

// The size of an MD4 checksum in bytes.
const Size = 16

// The blocksize of MD4 in bytes.
const BlockSize = 64

const (
	_Chunk = 64
	_Init0 = 0x67452301
	_Init1 = 0xEFCDAB89
	_Init2 = 0x98BADCFE
	_Init3 = 0x10325476
)

// digest represents the partial evaluation of a checksum.
type digest struct {
	s   [4]uint32
	x   [_Chunk]byte
	nx  int
	len uint64
}

func (d *digest) Reset() {
	d.s[0] = _Init0
	d.s[1] = _Init1
	d.s[2] = _Init2
	d.s[3] = _Init3
	d.nx = 0
	d.len = 0
}

// New returns a new hash.Hash computing the MD4 checksum.
func New() hash.Hash {
	d := new(digest)
	d.Reset()
	return d
}

func (d *digest) Size() int { return Size }

func (d *digest) BlockSize() int { return BlockSize }

func (d *digest) Write(p []byte) (nn int, err error) {
	nn = len(p)
	d.len += uint64(nn)
	if d.nx > 0 {
		n := len(p)
		if n > _Chunk-d.nx {
			n = _Chunk - d.nx
		}
		for i := 0; i < n; i++ {
			d.x[d.nx+i] = p[i]
		}
		d.nx += n
		if d.nx == _Chunk {
			_Block(d, d.x[0:])
			d.nx = 0
		}
		p = p[n:]
	}
	n := _Block(d, p)
	p = p[n:]
	if len(p) > 0 {
		d.nx = copy(d.x[:], p)
	}
	return
}

func (d0 *digest) Sum(in []byte) []byte {
	// Make a copy of d0, so that caller can keep writing and summing.
	d := new(digest)
	*d = *d0

	// Padding.  Add a 1 bit and 0 bits until 56 bytes mod 64.
	len := d.len
	var tmp [64]byte
	tmp[0] = 0x80
	if len%64 < 56 {
		d.Write(tmp[0 : 56-len%64])
	} else {
		d.Write(tmp[0 : 64+56-len%64])
	}

	// Length in bits.
	len <<= 3
	for i := uint(0); i < 8; i++ {
		tmp[i] = byte(len >> (8 * i))
	}
	d.Write(tmp[0:8])

	if d.nx != 0 {
		panic("d.nx != 0")
	}

	for _, s := range d.s {
		in = append(in, byte(s>>0))
		in = append(in, byte(s>>8))
		in = append(in, byte(s>>16))
		in = append(in, byte(s>>24))
	}
	return in
}


text:
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package md4

import (
	"fmt"
	"io"
	"testing"
)

type md4Test struct {
	out string
	in  string
}

var golden = []md4Test{
	{"31d6cfe0d16ae931b73c59d7e0c089c0", ""},
	{"bde52cb31de33e46245e05fbdbd6fb24", "a"},
	{"ec388dd78999dfc7cf4632465693b6bf", "ab"},
	{"a448017aaf21d8525fc10ae87aa6729d", "abc"},
	{"41decd8f579255c5200f86a4bb3ba740", "abcd"},
	{"9803f4a34e8eb14f96adba49064a0c41", "abcde"},
	{"804e7f1c2586e50b49ac65db5b645131", "abcdef"},
	{"752f4adfe53d1da0241b5bc216d098fc", "abcdefg"},
	{"ad9daf8d49d81988590a6f0e745d15dd", "abcdefgh"},
	{"1e4e28b05464316b56402b3815ed2dfd", "abcdefghi"},
	{"dc959c6f5d6f9e04e4380777cc964b3d", "abcdefghij"},
	{"1b5701e265778898ef7de5623bbe7cc0", "Discard medicine more than two years old."},
	{"d7f087e090fe7ad4a01cb59dacc9a572", "He who has a shady past knows that nice guys finish last."},
	{"a6f8fd6df617c72837592fc3570595c9", "I wouldn't marry him with a ten foot pole."},
	{"c92a84a9526da8abc240c05d6b1a1ce0", "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave"},
	{"f6013160c4dcb00847069fee3bb09803", "The days of the digital watch are numbered.  -Tom Stoppard"},
	{"2c3bb64f50b9107ed57640fe94bec09f", "Nepal premier won't resign."},
	{"45b7d8a32c7806f2f7f897332774d6e4", "For every action there is an equal and opposite government program."},
	{"b5b4f9026b175c62d7654bdc3a1cd438", "His money is twice tainted: 'taint yours and 'taint mine."},
	{"caf44e80f2c20ce19b5ba1cab766e7bd", "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977"},
	{"191fae6707f496aa54a6bce9f2ecf74d", "It's a tiny change to the code and not completely disgusting. - Bob Manchek"},
	{"9ddc753e7a4ccee6081cd1b45b23a834", "size:  a.out:  bad magic"},
	{"8d050f55b1cadb9323474564be08a521", "The major problem is with sendmail.  -Mark Horton"},
	{"ad6e2587f74c3e3cc19146f6127fa2e3", "Give me a rock, paper and scissors and I will move the world.  CCFestoon"},
	{"1d616d60a5fabe85589c3f1566ca7fca", "If the enemy is within range, then so are you."},
	{"aec3326a4f496a2ced65a1963f84577f", "It's well we cannot hear the screams/That we create in others' dreams."},
	{"77b4fd762d6b9245e61c50bf6ebf118b", "You remind me of a TV show, but that's all right: I watch it anyway."},
	{"e8f48c726bae5e516f6ddb1a4fe62438", "C is as portable as Stonehedge!!"},
	{"a3a84366e7219e887423b01f9be7166e", "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley"},
	{"a6b7aa35157e984ef5d9b7f32e5fbb52", "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction.  Lewis-Randall Rule"},
	{"75661f0545955f8f9abeeb17845f3fd6", "How can you write a big system without C++?  -Paul Glick"},
}

func TestGolden(t *testing.T) {
	for i := 0; i < len(golden); i++ {
		g := golden[i]
		c := New()
		for j := 0; j < 3; j++ {
			if j < 2 {
				io.WriteString(c, g.in)
			} else {
				io.WriteString(c, g.in[0:len(g.in)/2])
				c.Sum(nil)
				io.WriteString(c, g.in[len(g.in)/2:])
			}
			s := fmt.Sprintf("%x", c.Sum(nil))
			if s != g.out {
				t.Fatalf("md4[%d](%s) = %s want %s", j, g.in, s, g.out)
			}
			c.Reset()
		}
	}
}


text:
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package md4_test

import (
	"fmt"
	"io"

	"golang.org/x/crypto/md4"
)

func ExampleNew() {
	h := md4.New()
	data := "These pretzels are making me thirsty."
	io.WriteString(h, data)
	fmt.Printf("%x", h.Sum(nil))
	// Output: 48c4e365090b30a32f084c4888deceaa
}


text:
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// MD4 block step.
// In its own file so that a faster assembly or C version
// can be substituted easily.

package md4

var shift1 = []uint{3, 7, 11, 19}
var shift2 = []uint{3, 5, 9, 13}
var shift3 = []uint{3, 9, 11, 15}

var xIndex2 = []uint{0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15}
var xIndex3 = []uint{0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15}

func _Block(dig *digest, p []byte) int {
	a := dig.s[0]
	b := dig.s[1]
	c := dig.s[2]
	d := dig.s[3]
	n := 0
	var X [16]uint32
	for len(p) >= _Chunk {
		aa, bb, cc, dd := a, b, c, d

		j := 0
		for i := 0; i < 16; i++ {
			X[i] = uint32(p[j]) | uint32(p[j+1])<<8 | uint32(p[j+2])<<16 | uint32(p[j+3])<<24
			j += 4
		}

		// If this needs to be made faster in the future,
		// the usual trick is to unroll each of these
		// loops by a factor of 4; that lets you replace
		// the shift[] lookups with constants and,
		// with suitable variable renaming in each
		// unrolled body, delete the a, b, c, d = d, a, b, c
		// (or you can let the optimizer do the renaming).
		//
		// The index variables are uint so that % by a power
		// of two can be optimized easily by a compiler.

		// Round 1.
		for i := uint(0); i < 16; i++ {
			x := i
			s := shift1[i%4]
			f := ((c ^ d) & b) ^ d
			a += f + X[x]
			a = a<<s | a>>(32-s)
			a, b, c, d = d, a, b, c
		}

		// Round 2.
		for i := uint(0); i < 16; i++ {
			x := xIndex2[i]
			s := shift2[i%4]
			g := (b & c) | (b & d) | (c & d)
			a += g + X[x] + 0x5a827999
			a = a<<s | a>>(32-s)
			a, b, c, d = d, a, b, c
		}

		// Round 3.
		for i := uint(0); i < 16; i++ {
			x := xIndex3[i]
			s := shift3[i%4]
			h := b ^ c ^ d
			a += h + X[x] + 0x6ed9eba1
			a = a<<s | a>>(32-s)
			a, b, c, d = d, a, b, c
		}

		a += aa
		b += bb
		c += cc
		d += dd

		p = p[_Chunk:]
		n += _Chunk
	}

	dig.s[0] = a
	dig.s[1] = b
	dig.s[2] = c
	dig.s[3] = d
	return n
}


text:
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package openpgp

import (
	"bytes"
	"io"
	"io/ioutil"
	"testing"
	"time"

	"golang.org/x/crypto/openpgp/packet"
)

func TestSignDetached(t *testing.T) {
	kring, _ := ReadKeyRing(readerFromHex(testKeys1And2PrivateHex))
	out := bytes.NewBuffer(nil)
	message := bytes.NewBufferString(signedInput)
	err := DetachSign(out, kring[0], message, nil)
	if err != nil {
		t.Error(err)
	}

	testDetachedSignature(t, kring, out, signedInput, "check", testKey1KeyId)
}

func TestSignTextDetached(t *testing.T) {
	kring, _ := ReadKeyRing(readerFromHex(testKeys1And2PrivateHex))
	out := bytes.NewBuffer(nil)
	message := bytes.NewBufferString(signedInput)
	err := DetachSignText(out, kring[0], message, nil)
	if err != nil {
		t.Error(err)
	}

	testDetachedSignature(t, kring, out, signedInput, "check", testKey1KeyId)
}

func TestSignDetachedDSA(t *testing.T) {
	kring, _ := ReadKeyRing(readerFromHex(dsaTestKeyPrivateHex))
	out := bytes.NewBuffer(nil)
	message := bytes.NewBufferString(signedInput)
	err := DetachSign(out, kring[0], message, nil)
	if err != nil {
		t.Error(err)
	}

	testDetachedSignature(t, kring, out, signedInput, "check", testKey3KeyId)
}

func TestSignDetachedP256(t *testing.T) {
	kring, _ := ReadKeyRing(readerFromHex(p256TestKeyPrivateHex))
	kring[0].PrivateKey.Decrypt([]byte("passphrase"))

	out := bytes.NewBuffer(nil)
	message := bytes.NewBufferString(signedInput)
	err := DetachSign(out, kring[0], message, nil)
	if err != nil {
		t.Error(err)
	}

	testDetachedSignature(t, kring, out, signedInput, "check", testKeyP256KeyId)
}

func TestNewEntity(t *testing.T) {
	if testing.Short() {
		return
	}

	// Check bit-length with no config.
	e, err := NewEntity("Test User", "test", "test@example.com", nil)
	if err != nil {
		t.Errorf("failed to create entity: %s", err)
		return
	}
	bl, err := e.PrimaryKey.BitLength()
	if err != nil {
		t.Errorf("failed to find bit length: %s", err)
	}
	if int(bl) != defaultRSAKeyBits {
		t.Errorf("BitLength %v, expected %v", int(bl), defaultRSAKeyBits)
	}

	// Check bit-length with a config.
	cfg := &packet.Config{RSABits: 1024}
	e, err = NewEntity("Test User", "test", "test@example.com", cfg)
	if err != nil {
		t.Errorf("failed to create entity: %s", err)
		return
	}
	bl, err = e.PrimaryKey.BitLength()
	if err != nil {
		t.Errorf("failed to find bit length: %s", err)
	}
	if int(bl) != cfg.RSABits {
		t.Errorf("BitLength %v, expected %v", bl, cfg.RSABits)
	}

	w := bytes.NewBuffer(nil)
	if err := e.SerializePrivate(w, nil); err != nil {
		t.Errorf("failed to serialize entity: %s", err)
		return
	}
	serialized := w.Bytes()

	el, err := ReadKeyRing(w)
	if err != nil {
		t.Errorf("failed to reparse entity: %s", err)
		return
	}

	if len(el) != 1 {
		t.Errorf("wrong number of entities found, got %d, want 1", len(el))
	}

	w = bytes.NewBuffer(nil)
	if err := e.SerializePrivate(w, nil); err != nil {
		t.Errorf("failed to serialize entity second time: %s", err)
		return
	}

	if !bytes.Equal(w.Bytes(), serialized) {
		t.Errorf("results differed")
	}
}

func TestSymmetricEncryption(t *testing.T) {
	buf := new(bytes.Buffer)
	plaintext, err := SymmetricallyEncrypt(buf, []byte("testing"), nil, nil)
	if err != nil {
		t.Errorf("error writing headers: %s", err)
		return
	}
	message := []byte("hello world\n")
	_, err = plaintext.Write(message)
	if err != nil {
		t.Errorf("error writing to plaintext writer: %s", err)
	}
	err = plaintext.Close()
	if err != nil {
		t.Errorf("error closing plaintext writer: %s", err)
	}

	md, err := ReadMessage(buf, nil, func(keys []Key, symmetric bool) ([]byte, error) {
		return []byte("testing"), nil
	}, nil)
	if err != nil {
		t.Errorf("error rereading message: %s", err)
	}
	messageBuf := bytes.NewBuffer(nil)
	_, err = io.Copy(messageBuf, md.UnverifiedBody)
	if err != nil {
		t.Errorf("error rereading message: %s", err)
	}
	if !bytes.Equal(message, messageBuf.Bytes()) {
		t.Errorf("recovered message incorrect got '%s', want '%s'", messageBuf.Bytes(), message)
	}
}

var testEncryptionTests = []struct {
	keyRingHex string
	isSigned   bool
}{
	{
		testKeys1And2PrivateHex,
		false,
	},
	{
		testKeys1And2PrivateHex,
		true,
	},
	{
		dsaElGamalTestKeysHex,
		false,
	},
	{
		dsaElGamalTestKeysHex,
		true,
	},
}

func TestEncryption(t *testing.T) {
	for i, test := range testEncryptionTests {
		kring, _ := ReadKeyRing(readerFromHex(test.keyRingHex))

		passphrase := []byte("passphrase")
		for _, entity := range kring {
			if entity.PrivateKey != nil && entity.PrivateKey.Encrypted {
				err := entity.PrivateKey.Decrypt(passphrase)
				if err != nil {
					t.Errorf("#%d: failed to decrypt key", i)
				}
			}
			for _, subkey := range entity.Subkeys {
				if subkey.PrivateKey != nil && subkey.PrivateKey.Encrypted {
					err := subkey.PrivateKey.Decrypt(passphrase)
					if err != nil {
						t.Errorf("#%d: failed to decrypt subkey", i)
					}
				}
			}
		}

		var signed *Entity
		if test.isSigned {
			signed = kring[0]
		}

		buf := new(bytes.Buffer)
		w, err := Encrypt(buf, kring[:1], signed, nil /* no hints */, nil)
		if err != nil {
			t.Errorf("#%d: error in Encrypt: %s", i, err)
			continue
		}

		const message = "testing"
		_, err = w.Write([]byte(message))
		if err != nil {
			t.Errorf("#%d: error writing plaintext: %s", i, err)
			continue
		}
		err = w.Close()
		if err != nil {
			t.Errorf("#%d: error closing WriteCloser: %s", i, err)
			continue
		}

		md, err := ReadMessage(buf, kring, nil /* no prompt */, nil)
		if err != nil {
			t.Errorf("#%d: error reading message: %s", i, err)
			continue
		}

		testTime, _ := time.Parse("2006-01-02", "2013-07-01")
		if test.isSigned {
			signKey, _ := kring[0].signingKey(testTime)
			expectedKeyId := signKey.PublicKey.KeyId
			if md.SignedByKeyId != expectedKeyId {
				t.Errorf("#%d: message signed by wrong key id, got: %v, want: %v", i, *md.SignedBy, expectedKeyId)
			}
			if md.SignedBy == nil {
				t.Errorf("#%d: failed to find the signing Entity", i)
			}
		}

		plaintext, err := ioutil.ReadAll(md.UnverifiedBody)
		if err != nil {
			t.Errorf("#%d: error reading encrypted contents: %s", i, err)
			continue
		}

		encryptKey, _ := kring[0].encryptionKey(testTime)
		expectedKeyId := encryptKey.PublicKey.KeyId
		if len(md.EncryptedToKeyIds) != 1 || md.EncryptedToKeyIds[0] != expectedKeyId {
			t.Errorf("#%d: expected message to be encrypted to %v, but got %#v", i, expectedKeyId, md.EncryptedToKeyIds)
		}

		if string(plaintext) != message {
			t.Errorf("#%d: got: %s, want: %s", i, string(plaintext), message)
		}

		if test.isSigned {
			if md.SignatureError != nil {
				t.Errorf("#%d: signature error: %s", i, md.SignatureError)
			}
			if md.Signature == nil {
				t.Error("signature missing")
			}
		}
	}
}