<commit_before>package main

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"os"
)

func main() {
	fmt.Println("Initializing Octave CPU...")
	cpu := &CPU{running: true, sp: 65535}

	file, err := os.Open(os.Args[1])

	if err != nil {
		return
	}

	defer file.Close()

	cpu.memory, err = ioutil.ReadAll(file)

	cpu.devices[0] = stack{cpu}
	cpu.devices[1] = tty{bufio.NewReader(os.Stdin)}

	if err != nil {
		return
	}

	for cpu.running {
		inst_byte := fetch(cpu)
		inst_func := decode(inst_byte)
		inst_func(inst_byte, cpu)
	}
}

type CPU struct {
	memory    []uint8
	registers [4]uint8
	pc        uint16
	sp        uint16
	running   bool
	result    uint8
	devices   [8]Device
}

type instruction func(uint8, *CPU)

type Device interface {
	read() uint8
	write(uint8)
}

type tty struct {
	reader *bufio.Reader
}

func (t tty) read() uint8 {
	b, _ := t.reader.ReadByte()
	return b
}

func (t tty) write(char uint8) {
	fmt.Printf("%c", char)
}

type stack struct {
	cpu *CPU
}

func (s stack) read() uint8 {
	value := s.cpu.memory[s.cpu.sp]
	s.cpu.sp++
	return value
}

func (s stack) write(char uint8) {
	s.cpu.memory[s.cpu.sp] = char
	s.cpu.sp--
}

func fetch(cpu *CPU) uint8 {
	inst := cpu.memory[cpu.pc]
	cpu.pc = cpu.pc + 1
	return inst
}

func decode(i uint8) instruction {
	inst := illegal

	switch i >> 5 {
	case 0:
		fmt.Fprint(os.Stderr, "jmp\n")
		inst = jmp
	case 1:
		fmt.Fprint(os.Stderr, "loadi\n")
		inst = loadi
	case 2:
		fmt.Fprint(os.Stderr, "math\n")
		inst = math
	case 3:
		fmt.Fprint(os.Stderr, "logic\n")
		inst = logic
	case 4:
		fmt.Fprint(os.Stderr, "mem\n")
		inst = mem
	case 5:
		fmt.Fprint(os.Stderr, "stack\n")
		inst = stacki
	case 6:
		fmt.Fprint(os.Stderr, "in\n")
		inst = in
	case 7:
		fmt.Fprint(os.Stderr, "out\n")
		inst = out
	}

	return inst
}

func jmp(i uint8, cpu *CPU) {
	if i == 0 {
		cpu.running = false
	}

	register := i << 3 >> 6
	n := i << 5 >> 7
	z := i << 6 >> 7
	p := i << 7 >> 7

	if (n == 1 && cpu.result < 0) || (z == 1 && cpu.result == 0) || (p == 1 && cpu.result > 0) {
		offset := int8(cpu.registers[register])
		fmt.Fprintf(os.Stderr, "Taking jump to %v\n", offset)
		cpu.pc = uint16(int32(cpu.pc) + int32(offset))
	}
}

func loadi(i uint8, cpu *CPU) {
	location := i << 3 >> 7

	if location == 0 {
		cpu.registers[0] = (i << 4) | (cpu.registers[0] << 4 >> 4)
	} else {
		cpu.registers[0] = (i << 4 >> 4) | (cpu.registers[0] >> 4 << 4)
	}
}

func math(i uint8, cpu *CPU) {
	operation := i << 3 >> 7
	destination := i << 4 >> 6
	source := i << 6 >> 6

	if operation == 0 {
		cpu.registers[destination] = cpu.registers[destination] + cpu.registers[source]
	} else {
		cpu.registers[destination] = cpu.registers[destination] / cpu.registers[source]
	}

	cpu.result = cpu.registers[destination]
}

func logic(i uint8, cpu *CPU) {
	operation := i << 3 >> 7
	destination := i << 4 >> 6
	source := i << 6 >> 6

	if operation == 0 {
		cpu.registers[destination] = cpu.registers[destination] & cpu.registers[source]
	} else {
		cpu.registers[destination] = cpu.registers[destination] ^ cpu.registers[source]
	}

	cpu.result = cpu.registers[destination]
}

func mem(i uint8, cpu *CPU) {
	operation := i << 3 >> 7
	address_high := i << 4 >> 6
	address_low := i << 6 >> 6
	address := uint16(cpu.registers[address_high])<<8 + uint16(cpu.registers[address_low])

	if operation == 0 {
		// LOAD
		fmt.Fprintf(os.Stderr, "Loading %v\n to R0", address)
		cpu.registers[0] = cpu.memory[address]
	} else {
		// STORE
		fmt.Fprintf(os.Stderr, "Storing R0 to %v\n", address)
		cpu.memory[address] = cpu.registers[0]
	}
}

func stacki(i uint8, cpu *CPU) {
	stacki := i << 3 >> 3

	switch stacki {
	case 0:
		// add16
	case 1:
		// sub16
	case 2:
		// mul16
	case 3:
		// div16
	case 4:
		// mod16
	case 5:
		// neg16
	case 6:
		// and16
	case 7:
		// or16
	case 8:
		// xor16
	case 9:
		// not16
	case 10:
		// add32
	case 11:
		// sub32
	case 12:
		// mul32
	case 13:
		// div32
	case 14:
		// mod32
	case 15:
		// neg32
	case 16:
		// and32
	case 17:
		// or32
	case 18:
		// xor32
	case 19:
		// not32
	case 20:
		// Get jump address off the stack
		new_pc_high := cpu.devices[0].read()
		new_pc_low := cpu.devices[0].read()
		new_pc := uint16(new_pc_high)<<8 + uint16(new_pc_low)

		// Push next address to the stack
		pc_high := cpu.pc >> 8
		pc_low := cpu.pc << 8 >> 8
		cpu.devices[0].write(uint8(pc_high))
		cpu.devices[0].write(uint8(pc_low))

		// Jump
		cpu.pc = new_pc
	case 21:
		// trap
	case 22:
		// Get return address off the stack
		pc_high := cpu.devices[0].read()
		pc_low := cpu.devices[0].read()
		pc := uint16(pc_high)<<8 + uint16(pc_low)

		// Jump
		cpu.pc = pc
	case 23:
		// iret
	default:
		// device := stacki - 24
		// TODO: enable device
	}
}

func in(i uint8, cpu *CPU) {
	device := i << 5 >> 5
	destination := i << 3 >> 6
	cpu.registers[destination] = cpu.devices[device].read()
}

func out(i uint8, cpu *CPU) {
	device := i << 3 >> 5
	source := i << 6 >> 6
	cpu.devices[device].write(cpu.registers[source])
}

func illegal(i uint8, cpu *CPU) {
}
<commit_msg>Call stack order<commit_after>package main

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"os"
)

func main() {
	fmt.Println("Initializing Octave CPU...")
	cpu := &CPU{running: true, sp: 65535}

	file, err := os.Open(os.Args[1])

	if err != nil {
		return
	}

	defer file.Close()

	cpu.memory, err = ioutil.ReadAll(file)

	cpu.devices[0] = stack{cpu}
	cpu.devices[1] = tty{bufio.NewReader(os.Stdin)}

	if err != nil {
		return
	}

	for cpu.running {
		inst_byte := fetch(cpu)
		inst_func := decode(inst_byte)
		inst_func(inst_byte, cpu)
	}
}

type CPU struct {
	memory    []uint8
	registers [4]uint8
	pc        uint16
	sp        uint16
	running   bool
	result    uint8
	devices   [8]Device
}

type instruction func(uint8, *CPU)

type Device interface {
	read() uint8
	write(uint8)
}

type tty struct {
	reader *bufio.Reader
}

func (t tty) read() uint8 {
	b, _ := t.reader.ReadByte()
	return b
}

func (t tty) write(char uint8) {
	fmt.Printf("%c", char)
}

type stack struct {
	cpu *CPU
}

func (s stack) read() uint8 {
	value := s.cpu.memory[s.cpu.sp]
	s.cpu.sp++
	return value
}

func (s stack) write(char uint8) {
	s.cpu.memory[s.cpu.sp] = char
	s.cpu.sp--
}

func fetch(cpu *CPU) uint8 {
	inst := cpu.memory[cpu.pc]
	cpu.pc = cpu.pc + 1
	return inst
}

func decode(i uint8) instruction {
	inst := illegal

	switch i >> 5 {
	case 0:
		fmt.Fprint(os.Stderr, "jmp\n")
		inst = jmp
	case 1:
		fmt.Fprint(os.Stderr, "loadi\n")
		inst = loadi
	case 2:
		fmt.Fprint(os.Stderr, "math\n")
		inst = math
	case 3:
		fmt.Fprint(os.Stderr, "logic\n")
		inst = logic
	case 4:
		fmt.Fprint(os.Stderr, "mem\n")
		inst = mem
	case 5:
		fmt.Fprint(os.Stderr, "stack\n")
		inst = stacki
	case 6:
		fmt.Fprint(os.Stderr, "in\n")
		inst = in
	case 7:
		fmt.Fprint(os.Stderr, "out\n")
		inst = out
	}

	return inst
}

func jmp(i uint8, cpu *CPU) {
	if i == 0 {
		cpu.running = false
	}

	register := i << 3 >> 6
	n := i << 5 >> 7
	z := i << 6 >> 7
	p := i << 7 >> 7

	if (n == 1 && cpu.result < 0) || (z == 1 && cpu.result == 0) || (p == 1 && cpu.result > 0) {
		offset := int8(cpu.registers[register])
		fmt.Fprintf(os.Stderr, "Taking jump to %v\n", offset)
		cpu.pc = uint16(int32(cpu.pc) + int32(offset))
	}
}

func loadi(i uint8, cpu *CPU) {
	location := i << 3 >> 7

	if location == 0 {
		cpu.registers[0] = (i << 4) | (cpu.registers[0] << 4 >> 4)
	} else {
		cpu.registers[0] = (i << 4 >> 4) | (cpu.registers[0] >> 4 << 4)
	}
}

func math(i uint8, cpu *CPU) {
	operation := i << 3 >> 7
	destination := i << 4 >> 6
	source := i << 6 >> 6

	if operation == 0 {
		cpu.registers[destination] = cpu.registers[destination] + cpu.registers[source]
	} else {
		cpu.registers[destination] = cpu.registers[destination] / cpu.registers[source]
	}

	cpu.result = cpu.registers[destination]
}

func logic(i uint8, cpu *CPU) {
	operation := i << 3 >> 7
	destination := i << 4 >> 6
	source := i << 6 >> 6

	if operation == 0 {
		cpu.registers[destination] = cpu.registers[destination] & cpu.registers[source]
	} else {
		cpu.registers[destination] = cpu.registers[destination] ^ cpu.registers[source]
	}

	cpu.result = cpu.registers[destination]
}

func mem(i uint8, cpu *CPU) {
	operation := i << 3 >> 7
	address_high := i << 4 >> 6
	address_low := i << 6 >> 6
	address := uint16(cpu.registers[address_high])<<8 + uint16(cpu.registers[address_low])

	if operation == 0 {
		// LOAD
		fmt.Fprintf(os.Stderr, "Loading %v\n to R0", address)
		cpu.registers[0] = cpu.memory[address]
	} else {
		// STORE
		fmt.Fprintf(os.Stderr, "Storing R0 to %v\n", address)
		cpu.memory[address] = cpu.registers[0]
	}
}

func stacki(i uint8, cpu *CPU) {
	stacki := i << 3 >> 3

	switch stacki {
	case 0:
		// add16
	case 1:
		// sub16
	case 2:
		// mul16
	case 3:
		// div16
	case 4:
		// mod16
	case 5:
		// neg16
	case 6:
		// and16
	case 7:
		// or16
	case 8:
		// xor16
	case 9:
		// not16
	case 10:
		// add32
	case 11:
		// sub32
	case 12:
		// mul32
	case 13:
		// div32
	case 14:
		// mod32
	case 15:
		// neg32
	case 16:
		// and32
	case 17:
		// or32
	case 18:
		// xor32
	case 19:
		// not32
	case 20:
		// Get jump address off the stack
		new_pc_high := cpu.devices[0].read()
		new_pc_low := cpu.devices[0].read()
		new_pc := uint16(new_pc_high)<<8 + uint16(new_pc_low)

		// Push next address to the stack
		pc_high := cpu.pc >> 8
		pc_low := cpu.pc << 8 >> 8
		cpu.devices[0].write(uint8(pc_low))
		cpu.devices[0].write(uint8(pc_high))

		// Jump
		cpu.pc = new_pc
	case 21:
		// trap
	case 22:
		// Get return address off the stack
		pc_high := cpu.devices[0].read()
		pc_low := cpu.devices[0].read()
		pc := uint16(pc_high)<<8 + uint16(pc_low)

		// Jump
		cpu.pc = pc
	case 23:
		// iret
	default:
		// device := stacki - 24
		// TODO: enable device
	}
}

func in(i uint8, cpu *CPU) {
	device := i << 5 >> 5
	destination := i << 3 >> 6
	cpu.registers[destination] = cpu.devices[device].read()
}

func out(i uint8, cpu *CPU) {
	device := i << 3 >> 5
	source := i << 6 >> 6
	cpu.devices[device].write(cpu.registers[source])
}

func illegal(i uint8, cpu *CPU) {
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"encoding/hex"
	"errors"
	"fmt"
	"github.com/ethereum/eth-go"
	"github.com/ethereum/ethchain-go"
	"github.com/ethereum/ethdb-go"
	"github.com/ethereum/ethutil-go"
	"github.com/ethereum/ethwire-go"
	_ "math/big"
	"os"
	"strings"
)

type Console struct {
	db       *ethdb.MemDatabase
	trie     *ethutil.Trie
	ethereum *eth.Ethereum
}

func NewConsole(s *eth.Ethereum) *Console {
	db, _ := ethdb.NewMemDatabase()
	trie := ethutil.NewTrie(db, "")

	return &Console{db: db, trie: trie, ethereum: s}
}

func (i *Console) ValidateInput(action string, argumentLength int) error {
	err := false
	var expArgCount int

	switch {
	case action == "update" && argumentLength != 2:
		err = true
		expArgCount = 2
	case action == "get" && argumentLength != 1:
		err = true
		expArgCount = 1
	case action == "dag" && argumentLength != 2:
		err = true
		expArgCount = 2
	case action == "decode" && argumentLength != 1:
		err = true
		expArgCount = 1
	case action == "encode" && argumentLength != 1:
		err = true
		expArgCount = 1
	case action == "gettx" && argumentLength != 1:
		err = true
		expArgCount = 1
	case action == "tx" && argumentLength != 2:
		err = true
		expArgCount = 2
	case action == "getaddr" && argumentLength != 1:
		err = true
		expArgCount = 1
	case action == "contract" && argumentLength != 1:
		err = true
		expArgCount = 1
	case action == "say" && argumentLength != 1:
		err = true
		expArgCount = 1
	case action == "addp" && argumentLength != 1:
		err = true
		expArgCount = 1
	}

	if err {
		return errors.New(fmt.Sprintf("'%s' requires %d args, got %d", action, expArgCount, argumentLength))
	} else {
		return nil
	}
}

func (i *Console) PrintRoot() {
	root := ethutil.Conv(i.trie.Root)
	if len(root.AsBytes()) != 0 {
		fmt.Println(hex.EncodeToString(root.AsBytes()))
	} else {
		fmt.Println(i.trie.Root)
	}
}

func (i *Console) ParseInput(input string) bool {
	scanner := bufio.NewScanner(strings.NewReader(input))
	scanner.Split(bufio.ScanWords)

	count := 0
	var tokens []string
	for scanner.Scan() {
		count++
		tokens = append(tokens, scanner.Text())
	}
	if err := scanner.Err(); err != nil {
		fmt.Fprintln(os.Stderr, "reading input:", err)
	}

	if len(tokens) == 0 {
		return true
	}

	err := i.ValidateInput(tokens[0], count-1)
	if err != nil {
		fmt.Println(err)
	} else {
		switch tokens[0] {
		case "update":
			i.trie.Update(tokens[1], tokens[2])

			i.PrintRoot()
		case "get":
			fmt.Println(i.trie.Get(tokens[1]))
		case "root":
			i.PrintRoot()
		case "rawroot":
			fmt.Println(i.trie.Root)
		case "print":
			i.db.Print()
		case "dag":
			fmt.Println(ethchain.DaggerVerify(ethutil.Big(tokens[1]), // hash
				ethutil.BigPow(2, 36),   // diff
				ethutil.Big(tokens[2]))) // nonce
		case "decode":
			value := ethutil.NewRlpValueFromBytes([]byte(tokens[1]))
			fmt.Println(value)
		case "getaddr":
			encoded, _ := hex.DecodeString(tokens[1])
			d := i.ethereum.BlockManager.BlockChain().CurrentBlock.State().Get(string(encoded))
			if d != "" {
				decoder := ethutil.NewRlpValueFromBytes([]byte(d))
				fmt.Println(decoder)
			} else {
				fmt.Println("getaddr: address unknown")
			}
		case "say":
			i.ethereum.Broadcast(ethwire.MsgTalkTy, []interface{}{tokens[1]})
		case "addp":
			i.ethereum.ConnectToPeer(tokens[1])
		case "pcount":
			fmt.Println("peers:", i.ethereum.Peers().Len())
		case "encode":
			fmt.Printf("%q\n", ethutil.Encode(tokens[1]))
		case "tx":
			recipient, err := hex.DecodeString(tokens[1])
			if err != nil {
				fmt.Println("recipient err:", err)
			} else {
				tx := ethchain.NewTransaction(recipient, ethutil.Big(tokens[2]), []string{""})
				data, _ := ethutil.Config.Db.Get([]byte("KeyRing"))
				keyRing := ethutil.NewValueFromBytes(data)
				tx.Sign(keyRing.Get(0).Bytes())
				fmt.Printf("%x\n", tx.Hash())
				i.ethereum.TxPool.QueueTransaction(tx)
			}

		case "gettx":
			addr, _ := hex.DecodeString(tokens[1])
			data, _ := ethutil.Config.Db.Get(addr)
			if len(data) != 0 {
				decoder := ethutil.NewRlpValueFromBytes(data)
				fmt.Println(decoder)
			} else {
				fmt.Println("gettx: tx not found")
			}
		case "contract":
			contract := ethchain.NewTransaction([]byte{}, ethutil.Big(tokens[1]), []string{"PUSH", "1234"})
			fmt.Printf("%x\n", contract.Hash())

			i.ethereum.TxPool.QueueTransaction(contract)
		case "exit", "quit", "q":
			return false
		case "help":
			fmt.Printf("COMMANDS:\n" +
				"\033[1m= DB =\033[0m\n" +
				"update KEY VALUE - Updates/Creates a new value for the given key\n" +
				"get KEY - Retrieves the given key\n" +
				"root - Prints the hex encoded merkle root\n" +
				"rawroot - Prints the raw merkle root\n" +
				"\033[1m= Dagger =\033[0m\n" +
				"dag HASH NONCE - Verifies a nonce with the given hash with dagger\n" +
				"\033[1m= Encoding =\033[0m\n" +
				"decode STR\n" +
				"encode STR\n" +
				"\033[1m= Other =\033[0m\n" +
				"addp HOST:PORT\n" +
				"tx TO AMOUNT\n" +
				"contract AMOUNT\n")

		default:
			fmt.Println("Unknown command:", tokens[0])
		}
	}

	return true
}

func (i *Console) Start() {
	fmt.Printf("Eth Console. Type (help) for help\n")
	reader := bufio.NewReader(os.Stdin)
	for {
		fmt.Printf("eth >>> ")
		str, _, err := reader.ReadLine()
		if err != nil {
			fmt.Println("Error reading input", err)
		} else {
			if !i.ParseInput(string(str)) {
				return
			}
		}
	}
}
<commit_msg>Added block retrieval<commit_after>package main

import (
	"bufio"
	"encoding/hex"
	"errors"
	"fmt"
	"github.com/ethereum/eth-go"
	"github.com/ethereum/ethchain-go"
	"github.com/ethereum/ethdb-go"
	"github.com/ethereum/ethutil-go"
	"github.com/ethereum/ethwire-go"
	_ "math/big"
	"os"
	"strings"
)

type Console struct {
	db       *ethdb.MemDatabase
	trie     *ethutil.Trie
	ethereum *eth.Ethereum
}

func NewConsole(s *eth.Ethereum) *Console {
	db, _ := ethdb.NewMemDatabase()
	trie := ethutil.NewTrie(db, "")

	return &Console{db: db, trie: trie, ethereum: s}
}

func (i *Console) ValidateInput(action string, argumentLength int) error {
	err := false
	var expArgCount int

	switch {
	case action == "update" && argumentLength != 2:
		err = true
		expArgCount = 2
	case action == "get" && argumentLength != 1:
		err = true
		expArgCount = 1
	case action == "dag" && argumentLength != 2:
		err = true
		expArgCount = 2
	case action == "decode" && argumentLength != 1:
		err = true
		expArgCount = 1
	case action == "encode" && argumentLength != 1:
		err = true
		expArgCount = 1
	case action == "gettx" && argumentLength != 1:
		err = true
		expArgCount = 1
	case action == "tx" && argumentLength != 2:
		err = true
		expArgCount = 2
	case action == "getaddr" && argumentLength != 1:
		err = true
		expArgCount = 1
	case action == "contract" && argumentLength != 1:
		err = true
		expArgCount = 1
	case action == "say" && argumentLength != 1:
		err = true
		expArgCount = 1
	case action == "addp" && argumentLength != 1:
		err = true
		expArgCount = 1
	case action == "block" && argumentLength != 1:
		err = true
		expArgCount = 1
	}

	if err {
		return errors.New(fmt.Sprintf("'%s' requires %d args, got %d", action, expArgCount, argumentLength))
	} else {
		return nil
	}
}

func (i *Console) PrintRoot() {
	root := ethutil.Conv(i.trie.Root)
	if len(root.AsBytes()) != 0 {
		fmt.Println(hex.EncodeToString(root.AsBytes()))
	} else {
		fmt.Println(i.trie.Root)
	}
}

func (i *Console) ParseInput(input string) bool {
	scanner := bufio.NewScanner(strings.NewReader(input))
	scanner.Split(bufio.ScanWords)

	count := 0
	var tokens []string
	for scanner.Scan() {
		count++
		tokens = append(tokens, scanner.Text())
	}
	if err := scanner.Err(); err != nil {
		fmt.Fprintln(os.Stderr, "reading input:", err)
	}

	if len(tokens) == 0 {
		return true
	}

	err := i.ValidateInput(tokens[0], count-1)
	if err != nil {
		fmt.Println(err)
	} else {
		switch tokens[0] {
		case "update":
			i.trie.Update(tokens[1], tokens[2])

			i.PrintRoot()
		case "get":
			fmt.Println(i.trie.Get(tokens[1]))
		case "root":
			i.PrintRoot()
		case "rawroot":
			fmt.Println(i.trie.Root)
		case "print":
			i.db.Print()
		case "dag":
			fmt.Println(ethchain.DaggerVerify(ethutil.Big(tokens[1]), // hash
				ethutil.BigPow(2, 36),   // diff
				ethutil.Big(tokens[2]))) // nonce
		case "decode":
			value := ethutil.NewRlpValueFromBytes([]byte(tokens[1]))
			fmt.Println(value)
		case "getaddr":
			encoded, _ := hex.DecodeString(tokens[1])
			addr := i.ethereum.BlockManager.BlockChain().CurrentBlock.GetAddr(encoded)
			fmt.Println("addr:", addr)
		case "block":
			encoded, _ := hex.DecodeString(tokens[1])
			block := i.ethereum.BlockManager.BlockChain().GetBlock(encoded)
			fmt.Println(block)
		case "say":
			i.ethereum.Broadcast(ethwire.MsgTalkTy, []interface{}{tokens[1]})
		case "addp":
			i.ethereum.ConnectToPeer(tokens[1])
		case "pcount":
			fmt.Println("peers:", i.ethereum.Peers().Len())
		case "encode":
			fmt.Printf("%q\n", ethutil.Encode(tokens[1]))
		case "tx":
			recipient, err := hex.DecodeString(tokens[1])
			if err != nil {
				fmt.Println("recipient err:", err)
			} else {
				tx := ethchain.NewTransaction(recipient, ethutil.Big(tokens[2]), []string{""})
				data, _ := ethutil.Config.Db.Get([]byte("KeyRing"))
				keyRing := ethutil.NewValueFromBytes(data)
				tx.Sign(keyRing.Get(0).Bytes())
				fmt.Printf("%x\n", tx.Hash())
				i.ethereum.TxPool.QueueTransaction(tx)
			}

		case "gettx":
			addr, _ := hex.DecodeString(tokens[1])
			data, _ := ethutil.Config.Db.Get(addr)
			if len(data) != 0 {
				decoder := ethutil.NewRlpValueFromBytes(data)
				fmt.Println(decoder)
			} else {
				fmt.Println("gettx: tx not found")
			}
		case "contract":
			contract := ethchain.NewTransaction([]byte{}, ethutil.Big(tokens[1]), []string{"PUSH", "1234"})
			fmt.Printf("%x\n", contract.Hash())

			i.ethereum.TxPool.QueueTransaction(contract)
		case "exit", "quit", "q":
			return false
		case "help":
			fmt.Printf("COMMANDS:\n" +
				"\033[1m= DB =\033[0m\n" +
				"update KEY VALUE - Updates/Creates a new value for the given key\n" +
				"get KEY - Retrieves the given key\n" +
				"root - Prints the hex encoded merkle root\n" +
				"rawroot - Prints the raw merkle root\n" +
				"block HASH - Prints the block\n" +
				"getaddr ADDR - Prints the account associated with the address\n" +
				"\033[1m= Dagger =\033[0m\n" +
				"dag HASH NONCE - Verifies a nonce with the given hash with dagger\n" +
				"\033[1m= Encoding =\033[0m\n" +
				"decode STR\n" +
				"encode STR\n" +
				"\033[1m= Other =\033[0m\n" +
				"addp HOST:PORT\n" +
				"tx TO AMOUNT\n" +
				"contract AMOUNT\n")

		default:
			fmt.Println("Unknown command:", tokens[0])
		}
	}

	return true
}

func (i *Console) Start() {
	fmt.Printf("Eth Console. Type (help) for help\n")
	reader := bufio.NewReader(os.Stdin)
	for {
		fmt.Printf("eth >>> ")
		str, _, err := reader.ReadLine()
		if err != nil {
			fmt.Println("Error reading input", err)
		} else {
			if !i.ParseInput(string(str)) {
				return
			}
		}
	}
}
<|endoftext|>


<commit_before>// Copyright 2014 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"
	"os"
	"regexp"
	"sort"
	"strings"
)

func cmdMail(args []string) {
	var (
		diff   = flags.Bool("diff", false, "show change commit diff and don't upload or mail")
		force  = flags.Bool("f", false, "mail even if there are staged changes")
		topic  = flags.String("topic", "", "set Gerrit topic")
		rList  = new(stringList) // installed below
		ccList = new(stringList) // installed below
	)
	flags.Var(rList, "r", "comma-separated list of reviewers")
	flags.Var(ccList, "cc", "comma-separated list of people to CC:")

	flags.Usage = func() {
		fmt.Fprintf(stderr(), "Usage: %s mail %s [-r reviewer,...] [-cc mail,...] [-topic topic] [commit-hash]\n", os.Args[0], globalFlags)
	}
	flags.Parse(args)
	if len(flags.Args()) > 1 {
		flags.Usage()
		os.Exit(2)
	}

	b := CurrentBranch()

	var c *Commit
	if len(flags.Args()) == 1 {
		c = b.CommitByHash("mail", flags.Arg(0))
	} else {
		c = b.DefaultCommit("mail")
	}

	if *diff {
		run("git", "diff", b.Branchpoint()[:7]+".."+c.ShortHash, "--")
		return
	}

	if !*force && HasStagedChanges() {
		dief("there are staged changes; aborting.\n"+
			"Use '%s change' to include them or '%s mail -f' to force it.", os.Args[0], os.Args[0])
	}

	// for side effect of dying with a good message if origin is GitHub
	loadGerritOrigin()

	refSpec := b.PushSpec(c)
	start := "%"
	if *rList != "" {
		refSpec += mailList(start, "r", string(*rList))
		start = ","
	}
	if *ccList != "" {
		refSpec += mailList(start, "cc", string(*ccList))
		start = ","
	}
	if *topic != "" {
		// There's no way to escape the topic, but the only
		// ambiguous character is ',' (though other characters
		// like ' ' will be rejected outright by git).
		if strings.Contains(*topic, ",") {
			dief("topic may not contain a comma")
		}
		refSpec += start + "topic=" + *topic
	}
	run("git", "push", "-q", "origin", refSpec)

	// Create local tag for mailed change.
	// If in the 'work' branch, this creates or updates work.mailed.
	// Older mailings are in the reflog, so work.mailed is newest,
	// work.mailed@{1} is the one before that, work.mailed@{2} before that,
	// and so on.
	// Git doesn't actually have a concept of a local tag,
	// but Gerrit won't let people push tags to it, so the tag
	// can't propagate out of the local client into the official repo.
	// There is no conflict with the branch names people are using
	// for work, because git change rejects any name containing a dot.
	// The space of names with dots is ours (the Go team's) to define.
	run("git", "tag", "-f", b.Name+".mailed")
}

// PushSpec returns the spec for a Gerrit push command to publish the change c in b.
// If c is nil, PushSpec returns a spec for pushing all changes in b.
func (b *Branch) PushSpec(c *Commit) string {
	local := "HEAD"
	if c != nil && (len(b.Pending()) == 0 || b.Pending()[0].Hash != c.Hash) {
		local = c.ShortHash
	}
	return local + ":refs/for/" + strings.TrimPrefix(b.OriginBranch(), "origin/")
}

// mailAddressRE matches the mail addresses we admit. It's restrictive but admits
// all the addresses in the Go CONTRIBUTORS file at time of writing (tested separately).
var mailAddressRE = regexp.MustCompile(`^([a-zA-Z0-9][-_.a-zA-Z0-9]*)(@[-_.a-zA-Z0-9]+)?$`)

// mailList turns the list of mail addresses from the flag value into the format
// expected by gerrit. The start argument is a % or , depending on where we
// are in the processing sequence.
func mailList(start, tag string, flagList string) string {
	errors := false
	spec := start
	short := ""
	long := ""
	for i, addr := range strings.Split(flagList, ",") {
		m := mailAddressRE.FindStringSubmatch(addr)
		if m == nil {
			printf("invalid reviewer mail address: %s", addr)
			errors = true
			continue
		}
		if m[2] == "" {
			email := mailLookup(addr)
			if email == "" {
				printf("unknown reviewer: %s", addr)
				errors = true
				continue
			}
			short += "," + addr
			long += "," + email
			addr = email
		}
		if i > 0 {
			spec += ","
		}
		spec += tag + "=" + addr
	}
	if short != "" {
		verbosef("expanded %s to %s", short[1:], long[1:])
	}
	if errors {
		die()
	}
	return spec
}

// reviewers is the list of reviewers for the current repository,
// sorted by how many reviews each has done.
var reviewers []reviewer

type reviewer struct {
	addr  string
	count int
}

// mailLookup translates the short name (like adg) into a full
// email address (like adg@golang.org).
// It returns "" if no translation is found.
// The algorithm for expanding short user names is as follows:
// Look at the git commit log for the current repository,
// extracting all the email addresses in Reviewed-By lines
// and sorting by how many times each address appears.
// For each short user name, walk the list, most common
// address first, and use the first address found that has
// the short user name on the left side of the @.
func mailLookup(short string) string {
	loadReviewers()

	short += "@"
	for _, r := range reviewers {
		if strings.HasPrefix(r.addr, short) {
			return r.addr
		}
	}
	return ""
}

// loadReviewers reads the reviewer list from the current git repo
// and leaves it in the global variable reviewers.
// See the comment on mailLookup for a description of how the
// list is generated and used.
func loadReviewers() {
	if reviewers != nil {
		return
	}
	countByAddr := map[string]int{}
	for _, line := range nonBlankLines(cmdOutput("git", "log", "--format=format:%B")) {
		if strings.HasPrefix(line, "Reviewed-by:") {
			f := strings.Fields(line)
			addr := f[len(f)-1]
			if strings.HasPrefix(addr, "<") && strings.Contains(addr, "@") && strings.HasSuffix(addr, ">") {
				countByAddr[addr[1:len(addr)-1]]++
			}
		}
	}

	reviewers = []reviewer{}
	for addr, count := range countByAddr {
		reviewers = append(reviewers, reviewer{addr, count})
	}
	sort.Sort(reviewersByCount(reviewers))
}

type reviewersByCount []reviewer

func (x reviewersByCount) Len() int      { return len(x) }
func (x reviewersByCount) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func (x reviewersByCount) Less(i, j int) bool {
	if x[i].count != x[j].count {
		return x[i].count > x[j].count
	}
	return x[i].addr < x[j].addr
}

// stringList is a flag.Value that is like flag.String, but if repeated
// keeps appending to the old value, inserting commas as separators.
// This allows people to write -r rsc,adg (like the old hg command)
// but also -r rsc -r adg (like standard git commands).
// This does change the meaning of -r rsc -r adg (it used to mean just adg).
type stringList string

func (x *stringList) String() string {
	return string(*x)
}

func (x *stringList) Set(s string) error {
	if *x != "" && s != "" {
		*x += ","
	}
	*x += stringList(s)
	return nil
}
<commit_msg>git-codereview: set x.mailed tag to mailed commit instead of HEAD<commit_after>// Copyright 2014 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"
	"os"
	"regexp"
	"sort"
	"strings"
)

func cmdMail(args []string) {
	var (
		diff   = flags.Bool("diff", false, "show change commit diff and don't upload or mail")
		force  = flags.Bool("f", false, "mail even if there are staged changes")
		topic  = flags.String("topic", "", "set Gerrit topic")
		rList  = new(stringList) // installed below
		ccList = new(stringList) // installed below
	)
	flags.Var(rList, "r", "comma-separated list of reviewers")
	flags.Var(ccList, "cc", "comma-separated list of people to CC:")

	flags.Usage = func() {
		fmt.Fprintf(stderr(), "Usage: %s mail %s [-r reviewer,...] [-cc mail,...] [-topic topic] [commit-hash]\n", os.Args[0], globalFlags)
	}
	flags.Parse(args)
	if len(flags.Args()) > 1 {
		flags.Usage()
		os.Exit(2)
	}

	b := CurrentBranch()

	var c *Commit
	if len(flags.Args()) == 1 {
		c = b.CommitByHash("mail", flags.Arg(0))
	} else {
		c = b.DefaultCommit("mail")
	}

	if *diff {
		run("git", "diff", b.Branchpoint()[:7]+".."+c.ShortHash, "--")
		return
	}

	if !*force && HasStagedChanges() {
		dief("there are staged changes; aborting.\n"+
			"Use '%s change' to include them or '%s mail -f' to force it.", os.Args[0], os.Args[0])
	}

	// for side effect of dying with a good message if origin is GitHub
	loadGerritOrigin()

	refSpec := b.PushSpec(c)
	start := "%"
	if *rList != "" {
		refSpec += mailList(start, "r", string(*rList))
		start = ","
	}
	if *ccList != "" {
		refSpec += mailList(start, "cc", string(*ccList))
		start = ","
	}
	if *topic != "" {
		// There's no way to escape the topic, but the only
		// ambiguous character is ',' (though other characters
		// like ' ' will be rejected outright by git).
		if strings.Contains(*topic, ",") {
			dief("topic may not contain a comma")
		}
		refSpec += start + "topic=" + *topic
	}
	run("git", "push", "-q", "origin", refSpec)

	// Create local tag for mailed change.
	// If in the 'work' branch, this creates or updates work.mailed.
	// Older mailings are in the reflog, so work.mailed is newest,
	// work.mailed@{1} is the one before that, work.mailed@{2} before that,
	// and so on.
	// Git doesn't actually have a concept of a local tag,
	// but Gerrit won't let people push tags to it, so the tag
	// can't propagate out of the local client into the official repo.
	// There is no conflict with the branch names people are using
	// for work, because git change rejects any name containing a dot.
	// The space of names with dots is ours (the Go team's) to define.
	run("git", "tag", "-f", b.Name+".mailed", c.ShortHash)
}

// PushSpec returns the spec for a Gerrit push command to publish the change c in b.
// If c is nil, PushSpec returns a spec for pushing all changes in b.
func (b *Branch) PushSpec(c *Commit) string {
	local := "HEAD"
	if c != nil && (len(b.Pending()) == 0 || b.Pending()[0].Hash != c.Hash) {
		local = c.ShortHash
	}
	return local + ":refs/for/" + strings.TrimPrefix(b.OriginBranch(), "origin/")
}

// mailAddressRE matches the mail addresses we admit. It's restrictive but admits
// all the addresses in the Go CONTRIBUTORS file at time of writing (tested separately).
var mailAddressRE = regexp.MustCompile(`^([a-zA-Z0-9][-_.a-zA-Z0-9]*)(@[-_.a-zA-Z0-9]+)?$`)

// mailList turns the list of mail addresses from the flag value into the format
// expected by gerrit. The start argument is a % or , depending on where we
// are in the processing sequence.
func mailList(start, tag string, flagList string) string {
	errors := false
	spec := start
	short := ""
	long := ""
	for i, addr := range strings.Split(flagList, ",") {
		m := mailAddressRE.FindStringSubmatch(addr)
		if m == nil {
			printf("invalid reviewer mail address: %s", addr)
			errors = true
			continue
		}
		if m[2] == "" {
			email := mailLookup(addr)
			if email == "" {
				printf("unknown reviewer: %s", addr)
				errors = true
				continue
			}
			short += "," + addr
			long += "," + email
			addr = email
		}
		if i > 0 {
			spec += ","
		}
		spec += tag + "=" + addr
	}
	if short != "" {
		verbosef("expanded %s to %s", short[1:], long[1:])
	}
	if errors {
		die()
	}
	return spec
}

// reviewers is the list of reviewers for the current repository,
// sorted by how many reviews each has done.
var reviewers []reviewer

type reviewer struct {
	addr  string
	count int
}

// mailLookup translates the short name (like adg) into a full
// email address (like adg@golang.org).
// It returns "" if no translation is found.
// The algorithm for expanding short user names is as follows:
// Look at the git commit log for the current repository,
// extracting all the email addresses in Reviewed-By lines
// and sorting by how many times each address appears.
// For each short user name, walk the list, most common
// address first, and use the first address found that has
// the short user name on the left side of the @.
func mailLookup(short string) string {
	loadReviewers()

	short += "@"
	for _, r := range reviewers {
		if strings.HasPrefix(r.addr, short) {
			return r.addr
		}
	}
	return ""
}

// loadReviewers reads the reviewer list from the current git repo
// and leaves it in the global variable reviewers.
// See the comment on mailLookup for a description of how the
// list is generated and used.
func loadReviewers() {
	if reviewers != nil {
		return
	}
	countByAddr := map[string]int{}
	for _, line := range nonBlankLines(cmdOutput("git", "log", "--format=format:%B")) {
		if strings.HasPrefix(line, "Reviewed-by:") {
			f := strings.Fields(line)
			addr := f[len(f)-1]
			if strings.HasPrefix(addr, "<") && strings.Contains(addr, "@") && strings.HasSuffix(addr, ">") {
				countByAddr[addr[1:len(addr)-1]]++
			}
		}
	}

	reviewers = []reviewer{}
	for addr, count := range countByAddr {
		reviewers = append(reviewers, reviewer{addr, count})
	}
	sort.Sort(reviewersByCount(reviewers))
}

type reviewersByCount []reviewer

func (x reviewersByCount) Len() int      { return len(x) }
func (x reviewersByCount) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func (x reviewersByCount) Less(i, j int) bool {
	if x[i].count != x[j].count {
		return x[i].count > x[j].count
	}
	return x[i].addr < x[j].addr
}

// stringList is a flag.Value that is like flag.String, but if repeated
// keeps appending to the old value, inserting commas as separators.
// This allows people to write -r rsc,adg (like the old hg command)
// but also -r rsc -r adg (like standard git commands).
// This does change the meaning of -r rsc -r adg (it used to mean just adg).
type stringList string

func (x *stringList) String() string {
	return string(*x)
}

func (x *stringList) Set(s string) error {
	if *x != "" && s != "" {
		*x += ","
	}
	*x += stringList(s)
	return nil
}
<|endoftext|>


<commit_before>package github

import (
	"github.com/bmizerany/assert"
	"testing"
)

func TestWebURL(t *testing.T) {
	project := Project{"foo", "bar"}
	url := project.WebURL("", "", "baz")
	assert.Equal(t, "https://github.com/bar/foo/baz", url)

	url = project.WebURL("1", "2", "")
	assert.Equal(t, "https://github.com/2/1", url)
}

func TestParseNameAndOwner(t *testing.T) {
	owner, name := parseOwnerAndName()
	assert.Equal(t, "gh", name)

	ownerNotEmpty := len(owner) != 0
	assert.Equal(t, ownerNotEmpty, true)
}

func TestMustMatchGitHubURL(t *testing.T) {
	url, _ := mustMatchGitHubURL("git://github.com/jingweno/gh.git")
	assert.Equal(t, "git://github.com/jingweno/gh.git", url[0])

	url, _ = mustMatchGitHubURL("git@github.com:jingweno/gh.git")
	assert.Equal(t, "git@github.com:jingweno/gh.git", url[0])

	url, _ = mustMatchGitHubURL("https://github.com/jingweno/gh.git")
	assert.Equal(t, "https://github.com/jingweno/gh.git", url[0])
}
<commit_msg>Clean up TestParseNameAndOwner<commit_after>package github

import (
	"github.com/bmizerany/assert"
	"testing"
)

func TestWebURL(t *testing.T) {
	project := Project{"foo", "bar"}
	url := project.WebURL("", "", "baz")
	assert.Equal(t, "https://github.com/bar/foo/baz", url)

	url = project.WebURL("1", "2", "")
	assert.Equal(t, "https://github.com/2/1", url)
}

func TestParseNameAndOwner(t *testing.T) {
	owner, name := parseOwnerAndName()

	assert.Equal(t, "gh", name)
	assert.T(t, len(owner) > 0)
}

func TestMustMatchGitHubURL(t *testing.T) {
	url, _ := mustMatchGitHubURL("git://github.com/jingweno/gh.git")
	assert.Equal(t, "git://github.com/jingweno/gh.git", url[0])

	url, _ = mustMatchGitHubURL("git@github.com:jingweno/gh.git")
	assert.Equal(t, "git@github.com:jingweno/gh.git", url[0])

	url, _ = mustMatchGitHubURL("https://github.com/jingweno/gh.git")
	assert.Equal(t, "https://github.com/jingweno/gh.git", url[0])
}
<|endoftext|>


<commit_before>// Copyright 2015-present Oursky Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package migration

import (
	"fmt"

  "github.com/jmoiron/sqlx"
)

type ReservedColumnExistedError struct {
	table  string
	column string
}

func (e *ReservedColumnExistedError) Error() string {
	// TODO: put a link of guide here for those who failed to migrate
	return fmt.Sprintf(`Reserved column %s.%s has already been existed`, e.table, e.column)
}

type revision_f0c53134d25d struct {
}

func (r *revision_f0c53134d25d) Version() string {
	return "f0c53134d25d"
}

func (r *revision_f0c53134d25d) IsTableExisted(tx *sqlx.Tx, table string) (bool, error) {
	var exists bool
	err := tx.QueryRowx(`
SELECT EXISTS (
	SELECT 1
	FROM information_schema.tables
	WHERE
		table_schema = current_schema() AND
		table_name = $1
);
		`, table).Scan(&exists)
	return exists, err
}

func (r *revision_f0c53134d25d) IsColumnExisted(tx *sqlx.Tx, table string, column string) (bool, error) {
	var exists bool
	err := tx.QueryRowx(`
SELECT EXISTS (
	SELECT 1
	FROM information_schema.columns
	WHERE
		table_schema = current_schema() AND
		table_name = $1 AND
		column_name = $2
);
		`, table, column).Scan(&exists)
	return exists, err
}

func (r *revision_f0c53134d25d) EnsureReservedColumnsNotExisted(tx *sqlx.Tx) error {
	table := `user`
	columns := [2]string{`username`, `email`}

	for _, column := range columns {
		isExisted, err := r.IsColumnExisted(tx, table, column)
		if err != nil {
			return err
		}

		if isExisted {
			return &ReservedColumnExistedError{table: table, column: column}
		}
	}

	return nil
}

func (r *revision_f0c53134d25d) Up(tx *sqlx.Tx) error {
	migrateSkygearUserStmt := `
-- Migrate _user to _auth
ALTER TABLE _user_role DROP CONSTRAINT _user_role_user_id_fkey;
ALTER TABLE _device DROP CONSTRAINT _device_user_id_fkey;
ALTER TABLE _friend DROP CONSTRAINT _friend_right_id_fkey;
ALTER TABLE _follow DROP CONSTRAINT _follow_right_id_fkey;

ALTER TABLE _user_role RENAME TO _auth_role;

ALTER TABLE _user RENAME TO _auth;

ALTER TABLE _auth_role RENAME user_id TO auth_id;
ALTER TABLE _device RENAME user_id TO auth_id;
ALTER TABLE _subscription RENAME user_id TO auth_id;

ALTER TABLE _auth_role
	ADD CONSTRAINT _auth_role_auth_id_fkey FOREIGN KEY (auth_id) REFERENCES _auth (id);
ALTER TABLE _device
	ADD CONSTRAINT _device_auth_id_fkey FOREIGN KEY (auth_id) REFERENCES _auth (id);
ALTER TABLE _friend
	ADD CONSTRAINT _friend_right_id_fkey FOREIGN KEY (right_id) REFERENCES _auth (id);
ALTER TABLE _follow
	ADD CONSTRAINT _follow_right_id_fkey FOREIGN KEY (right_id) REFERENCES _auth (id);

CREATE VIEW _user AS
SELECT * FROM _auth;

ALTER TABLE _auth RENAME auth to provider_info;
	 `
	_, err := tx.Exec(migrateSkygearUserStmt)
	if err != nil {
		return err
	}

	if err = r.EnsureReservedColumnsNotExisted(tx); err != nil {
		return err
	}

	var userTableExists bool
	userTableExists, err = r.IsTableExisted(tx, `user`)
	if err != nil {
		return err
	}

	var migrateUserStmt string
	if userTableExists {
		migrateUserStmt = `
-- Migrate username and email to user table
ALTER TABLE user ADD COLUMN username citext UNIQUE;
ALTER TABLE user ADD COLUMN email citext UNIQUE;

UPDATE user
SET
	username = a.username,
	email = a.email
FROM _auth as a;

ALTER TABLE _auth DROP COLUMN username citext UNIQUE;
ALTER TABLE _auth DROP COLUMN email citext UNIQUE;
		`
	} else {
		migrateUserStmt = `
-- Create user table if not existed
CREATE TABLE user (
    _id text,
    _database_id text,
    _owner_id text,
    _access jsonb,
    _created_at timestamp without time zone NOT NULL,
    _created_by text,
    _updated_at timestamp without time zone NOT NULL,
    _updated_by text,
    username citext,
    email citext,
    PRIMARY KEY(_id, _database_id, _owner_id),
    UNIQUE (_id),
    UNIQUE (username),
    UNIQUE (email)
);
		`
	}

	_, err = tx.Exec(migrateUserStmt)
	if err != nil {
		return err
	}

	return nil
}

func (r *revision_f0c53134d25d) Down(tx *sqlx.Tx) error {
	migrateUserStmt := `
-- Migrate username and email to user table (backward)
ALTER TABLE _auth ADD COLUMN username citext UNIQUE;
ALTER TABLE _auth ADD COLUMN email citext UNIQUE;

UPDATE _auth
SET
	username = u.username,
	email = u.email
FROM user as u;

ALTER TABLE user DROP COLUMN username citext UNIQUE;
ALTER TABLE user DROP COLUMN email citext UNIQUE;
		`
	_, err := tx.Exec(migrateUserStmt)
	if err != nil {
		return err
	}

	migrateSkygearUserStmt := `
-- Migrate _user to _auth (backward)
ALTER TABLE _auth RENAME provider_info to auth;

DROP VIEW _user;

ALTER TABLE _auth_role DROP CONSTRAINT _auth_role_auth_id_fkey;
ALTER TABLE _device DROP CONSTRAINT _device_auth_id_fkey;
ALTER TABLE _friend DROP CONSTRAINT _friend_right_id_fkey;
ALTER TABLE _follow DROP CONSTRAINT _follow_right_id_fkey;

ALTER TABLE _auth_role RENAME auth_id TO user_id;
ALTER TABLE _device RENAME auth_id TO user_id;
ALTER TABLE _subscription RENAME auth_id TO user_id;

ALTER TABLE _auth RENAME TO _user;

ALTER TABLE _auth_role RENAME TO _user_role;

ALTER TABLE _user_role
	ADD CONSTRAINT _user_role_user_id_fkey FOREIGN KEY (user_id) REFERENCES _user (id);
ALTER TABLE _device
	ADD CONSTRAINT _device_user_id_fkey FOREIGN KEY (user_id) REFERENCES _user (id);
ALTER TABLE _friend
	ADD CONSTRAINT _friend_right_id_fkey FOREIGN KEY (right_id) REFERENCES _user (id);
ALTER TABLE _follow
	ADD CONSTRAINT _follow_right_id_fkey FOREIGN KEY (right_id) REFERENCES _user (id);
	`

	_, err = tx.Exec(migrateSkygearUserStmt)
	return err
}
<commit_msg>Fix sql syntax error<commit_after>// Copyright 2015-present Oursky Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package migration

import (
	"fmt"

  "github.com/jmoiron/sqlx"
)

type ReservedColumnExistedError struct {
	table  string
	column string
}

func (e *ReservedColumnExistedError) Error() string {
	// TODO: put a link of guide here for those who failed to migrate
	return fmt.Sprintf(`Reserved column %s.%s has already been existed`, e.table, e.column)
}

type revision_f0c53134d25d struct {
}

func (r *revision_f0c53134d25d) Version() string {
	return "f0c53134d25d"
}

func (r *revision_f0c53134d25d) IsTableExisted(tx *sqlx.Tx, table string) (bool, error) {
	var exists bool
	err := tx.QueryRowx(`
SELECT EXISTS (
	SELECT 1
	FROM information_schema.tables
	WHERE
		table_schema = current_schema() AND
		table_name = $1
);
		`, table).Scan(&exists)
	return exists, err
}

func (r *revision_f0c53134d25d) IsColumnExisted(tx *sqlx.Tx, table string, column string) (bool, error) {
	var exists bool
	err := tx.QueryRowx(`
SELECT EXISTS (
	SELECT 1
	FROM information_schema.columns
	WHERE
		table_schema = current_schema() AND
		table_name = $1 AND
		column_name = $2
);
		`, table, column).Scan(&exists)
	return exists, err
}

func (r *revision_f0c53134d25d) EnsureReservedColumnsNotExisted(tx *sqlx.Tx) error {
	table := `user`
	columns := [2]string{`username`, `email`}

	for _, column := range columns {
		isExisted, err := r.IsColumnExisted(tx, table, column)
		if err != nil {
			return err
		}

		if isExisted {
			return &ReservedColumnExistedError{table: table, column: column}
		}
	}

	return nil
}

func (r *revision_f0c53134d25d) Up(tx *sqlx.Tx) error {
	migrateSkygearUserStmt := `
-- Migrate _user to _auth
ALTER TABLE _user_role DROP CONSTRAINT _user_role_user_id_fkey;
ALTER TABLE _device DROP CONSTRAINT _device_user_id_fkey;
ALTER TABLE _friend DROP CONSTRAINT _friend_right_id_fkey;
ALTER TABLE _follow DROP CONSTRAINT _follow_right_id_fkey;

ALTER TABLE _user_role RENAME TO _auth_role;

ALTER TABLE _user RENAME TO _auth;

ALTER TABLE _auth_role RENAME user_id TO auth_id;
ALTER TABLE _device RENAME user_id TO auth_id;
ALTER TABLE _subscription RENAME user_id TO auth_id;

ALTER TABLE _auth_role
	ADD CONSTRAINT _auth_role_auth_id_fkey FOREIGN KEY (auth_id) REFERENCES _auth (id);
ALTER TABLE _device
	ADD CONSTRAINT _device_auth_id_fkey FOREIGN KEY (auth_id) REFERENCES _auth (id);
ALTER TABLE _friend
	ADD CONSTRAINT _friend_right_id_fkey FOREIGN KEY (right_id) REFERENCES _auth (id);
ALTER TABLE _follow
	ADD CONSTRAINT _follow_right_id_fkey FOREIGN KEY (right_id) REFERENCES _auth (id);

CREATE VIEW _user AS
SELECT * FROM _auth;

ALTER TABLE _auth RENAME auth to provider_info;
	 `
	_, err := tx.Exec(migrateSkygearUserStmt)
	if err != nil {
		return err
	}

	if err = r.EnsureReservedColumnsNotExisted(tx); err != nil {
		return err
	}

	var userTableExists bool
	userTableExists, err = r.IsTableExisted(tx, `user`)
	if err != nil {
		return err
	}

	var migrateUserStmt string
	if userTableExists {
		migrateUserStmt = `
-- Migrate username and email to user table
ALTER TABLE "user" ADD COLUMN username citext UNIQUE;
ALTER TABLE "user" ADD COLUMN email citext UNIQUE;

UPDATE "user"
SET
	username = a.username,
	email = a.email
FROM _auth as a
WHERE a.id = "user"._id;

ALTER TABLE _auth DROP COLUMN username;
ALTER TABLE _auth DROP COLUMN email;
		`
	} else {
		migrateUserStmt = `
-- Create user table if not existed
CREATE TABLE "user" (
    _id text,
    _database_id text,
    _owner_id text,
    _access jsonb,
    _created_at timestamp without time zone NOT NULL,
    _created_by text,
    _updated_at timestamp without time zone NOT NULL,
    _updated_by text,
    username citext,
    email citext,
    PRIMARY KEY(_id, _database_id, _owner_id),
    UNIQUE (_id),
    UNIQUE (username),
    UNIQUE (email)
);
		`
	}

	_, err = tx.Exec(migrateUserStmt)
	if err != nil {
		return err
	}

	return nil
}

func (r *revision_f0c53134d25d) Down(tx *sqlx.Tx) error {
	migrateUserStmt := `
-- Migrate username and email to user table (backward)
ALTER TABLE _auth ADD COLUMN username citext UNIQUE;
ALTER TABLE _auth ADD COLUMN email citext UNIQUE;

UPDATE _auth
SET
	username = u.username,
	email = u.email
FROM "user" as u
WHERE _auth.id = u._id;

ALTER TABLE "user" DROP COLUMN username;
ALTER TABLE "user" DROP COLUMN email;
		`
	_, err := tx.Exec(migrateUserStmt)
	if err != nil {
		return err
	}

	migrateSkygearUserStmt := `
-- Migrate _user to _auth (backward)
ALTER TABLE _auth RENAME provider_info to auth;

DROP VIEW _user;

ALTER TABLE _auth_role DROP CONSTRAINT _auth_role_auth_id_fkey;
ALTER TABLE _device DROP CONSTRAINT _device_auth_id_fkey;
ALTER TABLE _friend DROP CONSTRAINT _friend_right_id_fkey;
ALTER TABLE _follow DROP CONSTRAINT _follow_right_id_fkey;

ALTER TABLE _auth_role RENAME auth_id TO user_id;
ALTER TABLE _device RENAME auth_id TO user_id;
ALTER TABLE _subscription RENAME auth_id TO user_id;

ALTER TABLE _auth RENAME TO _user;

ALTER TABLE _auth_role RENAME TO _user_role;

ALTER TABLE _user_role
	ADD CONSTRAINT _user_role_user_id_fkey FOREIGN KEY (user_id) REFERENCES _user (id);
ALTER TABLE _device
	ADD CONSTRAINT _device_user_id_fkey FOREIGN KEY (user_id) REFERENCES _user (id);
ALTER TABLE _friend
	ADD CONSTRAINT _friend_right_id_fkey FOREIGN KEY (right_id) REFERENCES _user (id);
ALTER TABLE _follow
	ADD CONSTRAINT _follow_right_id_fkey FOREIGN KEY (right_id) REFERENCES _user (id);
	`

	_, err = tx.Exec(migrateSkygearUserStmt)
	return err
}
<|endoftext|>


<commit_before>package stardb

import (
	"encoding/json"
	"fmt"
	"io"
	"log"
	"time"

	"gopkg.in/mgo.v2"

	"gopkg.in/mgo.v2/bson"
)

type Farm struct {

	// Fields with  `json:"-"` are ommited for web display

	InternalID bson.ObjectId `bson:"_id,omitempty" json:"-"`
	ID         string        // Like InternalID, but in hex format. This can be exposed on the web.
	UniqueID   int           `json:"-"`
	Name       string
	Farmer     string
	Likes      int
	LastUpdate time.Time
	Thumbnail  string
}

func (f *Farm) ScreenshotPath() string {
	return fmt.Sprintf("/screenshot/%v/%d.png", f.InternalID.Hex(), f.LastUpdate.Unix())
}

func (f *Farm) saveGamePath() string {
	return SaveGamePath(f.InternalID.Hex(), f.LastUpdate)
}

func SaveGamePath(id string, ts time.Time) string {
	return fmt.Sprintf("/saveGames/%v/%d.xml", id, ts.Unix())
}

func FarmsJSON() ([]byte, error) {
	var farms []*Farm

	if err := FarmCollection.Find(nil).Sort("-lastupdate").Limit(20).All(&farms); err != nil {
		return nil, err
	}
	for _, farm := range farms {
		farm.Thumbnail = farm.ScreenshotPath()
		farm.ID = farm.InternalID.Hex()
	}
	return json.Marshal(farms)
}

func FarmJSON(id string) ([]byte, error) {
	if !bson.IsObjectIdHex(id) {
		return nil, fmt.Errorf("invalid farm id")
	}
	var farm *Farm
	if err := FarmCollection.Find(bson.M{"_id": bson.ObjectIdHex(id)}).One(&farm); err != nil {
		return nil, err
	}
	farm.Thumbnail = farm.ScreenshotPath()
	farm.ID = farm.InternalID.Hex()

	return json.Marshal(farm)
}

func LegacyMap(farmer string) (*Farm, error) {
	var farm *Farm
	if err := FarmCollection.Find(bson.M{"farmer": farmer}).One(&farm); err != nil {
		return nil, fmt.Errorf("error finding farm: %v", err)
	}
	farm.ID = farm.InternalID.Hex()
	return farm, nil
}

func SearchFarmsJSON(query string) ([]byte, error) {
	var farms []*Farm
	re := bson.RegEx{query, "i"}
	if err := FarmCollection.Find(
		bson.M{"$or": []interface{}{
			bson.M{"name": bson.M{"$regex": re}},
			bson.M{"farmer": bson.M{"$regex": re}},
		}}).Sort("-lastupdate").Limit(20).All(&farms); err != nil {
		return nil, err

	}
	for _, farm := range farms {
		farm.Thumbnail = farm.ScreenshotPath()
		farm.ID = farm.InternalID.Hex()
	}
	return json.Marshal(farms)
}

func UpdateFarmTime(id bson.ObjectId, ts time.Time) error {
	return FarmCollection.Update(bson.M{"_id": id}, bson.M{"$set": bson.M{"lastupdate": ts}})
}

func FindFarm(c *mgo.Collection, uniqueIDForThisGame int, playerName, farmName string) (ret *Farm, existing bool, err error) {
	ret = &Farm{}
	q := c.Find(bson.M{
		"name":     farmName,
		"farmer":   playerName,
		"uniqueid": uniqueIDForThisGame,
	})
	if err := q.One(&ret); err != nil {
		log.Println("not found", err)

		farm := &Farm{
			Name:       farmName,
			Farmer:     playerName,
			UniqueID:   uniqueIDForThisGame,
			InternalID: bson.NewObjectId(),
			LastUpdate: time.Now(),
		}
		if err := c.Insert(farm); err != nil {
			log.Println("could not insert", err)
			return nil, false, err
		}
		log.Println("insert ok", farm.InternalID.String())
		return farm, false, nil
	}
	log.Printf("found ok %v, %v, %v", ret.Name, ret.Farmer, ret.LastUpdate)

	return ret, true, nil
}

func WriteSaveFile(farm *Farm, body []byte, ts time.Time) error {
	farm.LastUpdate = ts
	saveFile := farm.saveGamePath()
	g, err := GFS.Create(saveFile)
	if err != nil {
		return fmt.Errorf("Error opening grid saveGames %v: %v", saveFile, err)

	}
	g.SetUploadDate(ts)
	defer g.Close()
	if _, err := g.Write(body); err != nil {
		return fmt.Errorf("Failed to write grid save file at %v: %v", saveFile, err)
	}

	log.Printf("Wrote grid saveGame file %v", saveFile)
	return nil
}

// NewScreenshotWriter saves a screenshot in GFS at screenshots/<hexid>.png
func NewScreenshotWriter(farm *Farm, ts time.Time) (io.WriteCloser, error) {
	if farm.LastUpdate.IsZero() {
		return nil, fmt.Errorf("error writing screenshot: unexpected zero save time")
	}
	g, err := GFS.Create(farm.ScreenshotPath())
	if err != nil {
		return nil, err
	}
	g.SetUploadDate(ts)
	return g, nil
}
<commit_msg>dont show LastUpdate on JSON for now<commit_after>package stardb

import (
	"encoding/json"
	"fmt"
	"io"
	"log"
	"time"

	"gopkg.in/mgo.v2"

	"gopkg.in/mgo.v2/bson"
)

type Farm struct {

	// Fields with  `json:"-"` are ommited for web display

	InternalID bson.ObjectId `bson:"_id,omitempty" json:"-"`
	ID         string        // Like InternalID, but in hex format. This can be exposed on the web.
	UniqueID   int           `json:"-"`
	Name       string
	Farmer     string
	Likes      int
	// TODO: stop omitting this once the web client understands it.
	LastUpdate time.Time `json:"-"`
	Thumbnail  string
}

func (f *Farm) ScreenshotPath() string {
	return fmt.Sprintf("/screenshot/%v/%d.png", f.InternalID.Hex(), f.LastUpdate.Unix())
}

func (f *Farm) saveGamePath() string {
	return SaveGamePath(f.InternalID.Hex(), f.LastUpdate)
}

func SaveGamePath(id string, ts time.Time) string {
	return fmt.Sprintf("/saveGames/%v/%d.xml", id, ts.Unix())
}

func FarmsJSON() ([]byte, error) {
	var farms []*Farm

	if err := FarmCollection.Find(nil).Sort("-lastupdate").Limit(20).All(&farms); err != nil {
		return nil, err
	}
	for _, farm := range farms {
		farm.Thumbnail = farm.ScreenshotPath()
		farm.ID = farm.InternalID.Hex()
	}
	return json.Marshal(farms)
}

func FarmJSON(id string) ([]byte, error) {
	if !bson.IsObjectIdHex(id) {
		return nil, fmt.Errorf("invalid farm id")
	}
	var farm *Farm
	if err := FarmCollection.Find(bson.M{"_id": bson.ObjectIdHex(id)}).One(&farm); err != nil {
		return nil, err
	}
	farm.Thumbnail = farm.ScreenshotPath()
	farm.ID = farm.InternalID.Hex()

	return json.Marshal(farm)
}

func LegacyMap(farmer string) (*Farm, error) {
	var farm *Farm
	if err := FarmCollection.Find(bson.M{"farmer": farmer}).One(&farm); err != nil {
		return nil, fmt.Errorf("error finding farm: %v", err)
	}
	farm.ID = farm.InternalID.Hex()
	return farm, nil
}

func SearchFarmsJSON(query string) ([]byte, error) {
	var farms []*Farm
	re := bson.RegEx{query, "i"}
	if err := FarmCollection.Find(
		bson.M{"$or": []interface{}{
			bson.M{"name": bson.M{"$regex": re}},
			bson.M{"farmer": bson.M{"$regex": re}},
		}}).Sort("-lastupdate").Limit(20).All(&farms); err != nil {
		return nil, err

	}
	for _, farm := range farms {
		farm.Thumbnail = farm.ScreenshotPath()
		farm.ID = farm.InternalID.Hex()
	}
	return json.Marshal(farms)
}

func UpdateFarmTime(id bson.ObjectId, ts time.Time) error {
	return FarmCollection.Update(bson.M{"_id": id}, bson.M{"$set": bson.M{"lastupdate": ts}})
}

func FindFarm(c *mgo.Collection, uniqueIDForThisGame int, playerName, farmName string) (ret *Farm, existing bool, err error) {
	ret = &Farm{}
	q := c.Find(bson.M{
		"name":     farmName,
		"farmer":   playerName,
		"uniqueid": uniqueIDForThisGame,
	})
	if err := q.One(&ret); err != nil {
		log.Println("not found", err)

		farm := &Farm{
			Name:       farmName,
			Farmer:     playerName,
			UniqueID:   uniqueIDForThisGame,
			InternalID: bson.NewObjectId(),
			LastUpdate: time.Now(),
		}
		if err := c.Insert(farm); err != nil {
			log.Println("could not insert", err)
			return nil, false, err
		}
		log.Println("insert ok", farm.InternalID.String())
		return farm, false, nil
	}
	log.Printf("found ok %v, %v, %v", ret.Name, ret.Farmer, ret.LastUpdate)

	return ret, true, nil
}

func WriteSaveFile(farm *Farm, body []byte, ts time.Time) error {
	farm.LastUpdate = ts
	saveFile := farm.saveGamePath()
	g, err := GFS.Create(saveFile)
	if err != nil {
		return fmt.Errorf("Error opening grid saveGames %v: %v", saveFile, err)

	}
	g.SetUploadDate(ts)
	defer g.Close()
	if _, err := g.Write(body); err != nil {
		return fmt.Errorf("Failed to write grid save file at %v: %v", saveFile, err)
	}

	log.Printf("Wrote grid saveGame file %v", saveFile)
	return nil
}

// NewScreenshotWriter saves a screenshot in GFS at screenshots/<hexid>.png
func NewScreenshotWriter(farm *Farm, ts time.Time) (io.WriteCloser, error) {
	if farm.LastUpdate.IsZero() {
		return nil, fmt.Errorf("error writing screenshot: unexpected zero save time")
	}
	g, err := GFS.Create(farm.ScreenshotPath())
	if err != nil {
		return nil, err
	}
	g.SetUploadDate(ts)
	return g, nil
}
<|endoftext|>


<commit_before>package account

import (
	"bytes"
	cryptorand "crypto/rand"
	"encoding/base64"
	"encoding/json"
	"io"
	"math/rand"
	"os"
	"testing"
	"time"

	"github.com/cozy/cozy-stack/pkg/config/config"
	"github.com/cozy/cozy-stack/pkg/crypto"
	"github.com/cozy/cozy-stack/pkg/utils"
	"github.com/stretchr/testify/assert"
)

func TestEncryptDecrytCredentials(t *testing.T) {
	encryptedCreds1, err := EncryptCredentials("me@mycozy.cloud", "fzEE6HFWsSp8jP")
	if !assert.NoError(t, err) {
		return
	}
	encryptedCreds2, err := EncryptCredentials("me@mycozy.cloud", "fzEE6HFWsSp8jP")
	if !assert.NoError(t, err) {
		return
	}
	encryptedCreds3, err := EncryptCredentials("", "fzEE6HFWsSp8jP")
	if !assert.NoError(t, err) {
		return
	}
	assert.NotEqual(t, encryptedCreds1, encryptedCreds2)

	{
		login, password, err := DecryptCredentials(encryptedCreds1)
		if !assert.NoError(t, err) {
			return
		}
		assert.Equal(t, "me@mycozy.cloud", login)
		assert.Equal(t, "fzEE6HFWsSp8jP", password)
	}
	{
		login, password, err := DecryptCredentials(encryptedCreds2)
		if !assert.NoError(t, err) {
			return
		}
		assert.Equal(t, "me@mycozy.cloud", login)
		assert.Equal(t, "fzEE6HFWsSp8jP", password)
	}
	{
		login, password, err := DecryptCredentials(encryptedCreds3)
		if !assert.NoError(t, err) {
			return
		}
		assert.Equal(t, "", login)
		assert.Equal(t, "fzEE6HFWsSp8jP", password)
	}
}

func TestEncryptDecrytUTF8Credentials(t *testing.T) {
	rng := rand.New(rand.NewSource(time.Now().UnixNano()))
	for i := 0; i < 1024; i++ {
		login := string(crypto.GenerateRandomBytes(rng.Intn(256)))
		password := string(crypto.GenerateRandomBytes(rng.Intn(256)))

		encryptedCreds, err := EncryptCredentials(login, password)
		if !assert.NoError(t, err) {
			return
		}

		loginDec, passwordDec, err := DecryptCredentials(encryptedCreds)
		if !assert.NoError(t, err) {
			return
		}

		assert.Equal(t, loginDec, login)
		assert.Equal(t, passwordDec, password)
	}

	for i := 0; i < 1024; i++ {
		login := utils.RandomString(rng.Intn(256))
		password := utils.RandomString(rng.Intn(256))

		encryptedCreds, err := EncryptCredentials(login, password)
		if !assert.NoError(t, err) {
			return
		}

		loginDec, passwordDec, err := DecryptCredentials(encryptedCreds)
		if !assert.NoError(t, err) {
			return
		}

		assert.Equal(t, loginDec, login)
		assert.Equal(t, passwordDec, password)
	}
}

func TestDecryptCredentialsRandom(t *testing.T) {
	rng := rand.New(rand.NewSource(time.Now().UnixNano()))
	for i := 0; i < 1024; i++ {
		encrypted := base64.StdEncoding.EncodeToString(crypto.GenerateRandomBytes(rng.Intn(256)))
		_, _, err := DecryptCredentials(encrypted)
		assert.Error(t, err)
	}
	for i := 0; i < 1024; i++ {
		encrypted := crypto.GenerateRandomBytes(rng.Intn(256))
		encryptedWithHeader := make([]byte, len(cipherHeader)+len(encrypted))
		copy(encryptedWithHeader[0:], cipherHeader)
		copy(encryptedWithHeader[len(cipherHeader):], encrypted)
		_, _, err := DecryptCredentials(base64.StdEncoding.EncodeToString(encryptedWithHeader))
		assert.Error(t, err)
	}
}

func TestRandomBitFlipsCredentials(t *testing.T) {
	original, err := EncryptCredentials("toto@titi.com", "X3hVYLJLRiUyCs")
	if !assert.NoError(t, err) {
		return
	}
	originalBuffer, err := base64.StdEncoding.DecodeString(original)
	if !assert.NoError(t, err) {
		return
	}

	flipped := make([]byte, len(originalBuffer))
	copy(flipped, originalBuffer)
	login, passwd, err := DecryptCredentials(base64.StdEncoding.EncodeToString(flipped))
	if !assert.NoError(t, err) {
		return
	}
	assert.Equal(t, "toto@titi.com", login)
	assert.Equal(t, "X3hVYLJLRiUyCs", passwd)

	rng := rand.New(rand.NewSource(time.Now().UnixNano()))
	for i := 0; i < 100000; i++ {
		copy(flipped, originalBuffer)
		flipsLen := rng.Intn(30) + 1
		flipsSet := make([]int, 0, flipsLen)
		for len(flipsSet) < flipsLen {
			flipValue := rng.Intn(len(originalBuffer) * 8)
			flipFound := false
			for j := 0; j < len(flipsSet); j++ {
				if flipsSet[j] == flipValue {
					flipFound = true
					break
				}
			}
			if !flipFound {
				flipsSet = append(flipsSet, flipValue)
			}
		}
		for _, flipValue := range flipsSet {
			mask := byte(0x1 << uint(flipValue%8))
			flipped[flipValue/8] ^= mask
		}
		_, _, err := DecryptCredentials(base64.StdEncoding.EncodeToString(flipped))
		if !assert.Error(t, err) {
			t.Fatalf("Failed with flips %v", flipsSet)
			return
		}
	}
}

func TestEncryptDecryptData(t *testing.T) {
	var data interface{}
	err := json.Unmarshal([]byte(`{"foo":"bar","baz":{"quz": "quuz"}}`), &data)
	if !assert.NoError(t, err) {
		return
	}
	encBuffer, err := EncryptCredentialsData(data)
	if !assert.NoError(t, err) {
		return
	}
	decData, err := DecryptCredentialsData(encBuffer)
	if !assert.NoError(t, err) {
		return
	}
	assert.EqualValues(t, data, decData)
}

func TestRandomBitFlipsBuffer(t *testing.T) {
	plainBuffer := make([]byte, 256)
	_, err := io.ReadFull(cryptorand.Reader, plainBuffer)
	if !assert.NoError(t, err) {
		return
	}

	original, err := EncryptBufferWithKey(config.GetVault().CredentialsEncryptorKey(), plainBuffer)
	if !assert.NoError(t, err) {
		return
	}

	flipped := make([]byte, len(original))
	copy(flipped, original)
	testBuffer, err := DecryptBufferWithKey(config.GetVault().CredentialsDecryptorKey(), flipped)
	if !assert.NoError(t, err) {
		return
	}
	assert.True(t, bytes.Equal(plainBuffer, testBuffer))

	rng := rand.New(rand.NewSource(time.Now().UnixNano()))
	for i := 0; i < 100000; i++ {
		copy(flipped, original)
		flipsLen := rng.Intn(30) + 1
		flipsSet := make([]int, 0, flipsLen)
		for len(flipsSet) < flipsLen {
			flipValue := rng.Intn(len(original) * 8)
			flipFound := false
			for j := 0; j < len(flipsSet); j++ {
				if flipsSet[j] == flipValue {
					flipFound = true
					break
				}
			}
			if !flipFound {
				flipsSet = append(flipsSet, flipValue)
			}
		}
		for _, flipValue := range flipsSet {
			mask := byte(0x1 << uint(flipValue%8))
			flipped[flipValue/8] ^= mask
		}
		_, err := DecryptBufferWithKey(config.GetVault().CredentialsDecryptorKey(), flipped)
		if !assert.Error(t, err) {
			t.Fatalf("Failed with flips %v", flipsSet)
			return
		}
	}
}

func TestMain(m *testing.M) {
	config.UseTestFile()
	os.Exit(m.Run())
}
<commit_msg>Make model/account tests faster<commit_after>package account

import (
	"bytes"
	cryptorand "crypto/rand"
	"encoding/base64"
	"encoding/json"
	"io"
	"math/rand"
	"os"
	"testing"
	"time"

	"github.com/cozy/cozy-stack/pkg/config/config"
	"github.com/cozy/cozy-stack/pkg/crypto"
	"github.com/cozy/cozy-stack/pkg/utils"
	"github.com/stretchr/testify/assert"
)

func TestEncryptDecrytCredentials(t *testing.T) {
	encryptedCreds1, err := EncryptCredentials("me@mycozy.cloud", "fzEE6HFWsSp8jP")
	if !assert.NoError(t, err) {
		return
	}
	encryptedCreds2, err := EncryptCredentials("me@mycozy.cloud", "fzEE6HFWsSp8jP")
	if !assert.NoError(t, err) {
		return
	}
	encryptedCreds3, err := EncryptCredentials("", "fzEE6HFWsSp8jP")
	if !assert.NoError(t, err) {
		return
	}
	assert.NotEqual(t, encryptedCreds1, encryptedCreds2)

	{
		login, password, err := DecryptCredentials(encryptedCreds1)
		if !assert.NoError(t, err) {
			return
		}
		assert.Equal(t, "me@mycozy.cloud", login)
		assert.Equal(t, "fzEE6HFWsSp8jP", password)
	}
	{
		login, password, err := DecryptCredentials(encryptedCreds2)
		if !assert.NoError(t, err) {
			return
		}
		assert.Equal(t, "me@mycozy.cloud", login)
		assert.Equal(t, "fzEE6HFWsSp8jP", password)
	}
	{
		login, password, err := DecryptCredentials(encryptedCreds3)
		if !assert.NoError(t, err) {
			return
		}
		assert.Equal(t, "", login)
		assert.Equal(t, "fzEE6HFWsSp8jP", password)
	}
}

func TestEncryptDecrytUTF8Credentials(t *testing.T) {
	rng := rand.New(rand.NewSource(time.Now().UnixNano()))
	for i := 0; i < 1024; i++ {
		login := string(crypto.GenerateRandomBytes(rng.Intn(256)))
		password := string(crypto.GenerateRandomBytes(rng.Intn(256)))

		encryptedCreds, err := EncryptCredentials(login, password)
		if !assert.NoError(t, err) {
			return
		}

		loginDec, passwordDec, err := DecryptCredentials(encryptedCreds)
		if !assert.NoError(t, err) {
			return
		}

		assert.Equal(t, loginDec, login)
		assert.Equal(t, passwordDec, password)
	}

	for i := 0; i < 1024; i++ {
		login := utils.RandomString(rng.Intn(256))
		password := utils.RandomString(rng.Intn(256))

		encryptedCreds, err := EncryptCredentials(login, password)
		if !assert.NoError(t, err) {
			return
		}

		loginDec, passwordDec, err := DecryptCredentials(encryptedCreds)
		if !assert.NoError(t, err) {
			return
		}

		assert.Equal(t, loginDec, login)
		assert.Equal(t, passwordDec, password)
	}
}

func TestDecryptCredentialsRandom(t *testing.T) {
	rng := rand.New(rand.NewSource(time.Now().UnixNano()))
	for i := 0; i < 1024; i++ {
		encrypted := base64.StdEncoding.EncodeToString(crypto.GenerateRandomBytes(rng.Intn(256)))
		_, _, err := DecryptCredentials(encrypted)
		assert.Error(t, err)
	}
	for i := 0; i < 1024; i++ {
		encrypted := crypto.GenerateRandomBytes(rng.Intn(256))
		encryptedWithHeader := make([]byte, len(cipherHeader)+len(encrypted))
		copy(encryptedWithHeader[0:], cipherHeader)
		copy(encryptedWithHeader[len(cipherHeader):], encrypted)
		_, _, err := DecryptCredentials(base64.StdEncoding.EncodeToString(encryptedWithHeader))
		assert.Error(t, err)
	}
}

func TestRandomBitFlipsCredentials(t *testing.T) {
	original, err := EncryptCredentials("toto@titi.com", "X3hVYLJLRiUyCs")
	if !assert.NoError(t, err) {
		return
	}
	originalBuffer, err := base64.StdEncoding.DecodeString(original)
	if !assert.NoError(t, err) {
		return
	}

	flipped := make([]byte, len(originalBuffer))
	copy(flipped, originalBuffer)
	login, passwd, err := DecryptCredentials(base64.StdEncoding.EncodeToString(flipped))
	if !assert.NoError(t, err) {
		return
	}
	assert.Equal(t, "toto@titi.com", login)
	assert.Equal(t, "X3hVYLJLRiUyCs", passwd)

	rng := rand.New(rand.NewSource(time.Now().UnixNano()))
	for i := 0; i < 1000; i++ {
		copy(flipped, originalBuffer)
		flipsLen := rng.Intn(30) + 1
		flipsSet := make([]int, 0, flipsLen)
		for len(flipsSet) < flipsLen {
			flipValue := rng.Intn(len(originalBuffer) * 8)
			flipFound := false
			for j := 0; j < len(flipsSet); j++ {
				if flipsSet[j] == flipValue {
					flipFound = true
					break
				}
			}
			if !flipFound {
				flipsSet = append(flipsSet, flipValue)
			}
		}
		for _, flipValue := range flipsSet {
			mask := byte(0x1 << uint(flipValue%8))
			flipped[flipValue/8] ^= mask
		}
		_, _, err := DecryptCredentials(base64.StdEncoding.EncodeToString(flipped))
		if !assert.Error(t, err) {
			t.Fatalf("Failed with flips %v", flipsSet)
			return
		}
	}
}

func TestEncryptDecryptData(t *testing.T) {
	var data interface{}
	err := json.Unmarshal([]byte(`{"foo":"bar","baz":{"quz": "quuz"}}`), &data)
	if !assert.NoError(t, err) {
		return
	}
	encBuffer, err := EncryptCredentialsData(data)
	if !assert.NoError(t, err) {
		return
	}
	decData, err := DecryptCredentialsData(encBuffer)
	if !assert.NoError(t, err) {
		return
	}
	assert.EqualValues(t, data, decData)
}

func TestRandomBitFlipsBuffer(t *testing.T) {
	plainBuffer := make([]byte, 256)
	_, err := io.ReadFull(cryptorand.Reader, plainBuffer)
	if !assert.NoError(t, err) {
		return
	}

	original, err := EncryptBufferWithKey(config.GetVault().CredentialsEncryptorKey(), plainBuffer)
	if !assert.NoError(t, err) {
		return
	}

	flipped := make([]byte, len(original))
	copy(flipped, original)
	testBuffer, err := DecryptBufferWithKey(config.GetVault().CredentialsDecryptorKey(), flipped)
	if !assert.NoError(t, err) {
		return
	}
	assert.True(t, bytes.Equal(plainBuffer, testBuffer))

	rng := rand.New(rand.NewSource(time.Now().UnixNano()))
	for i := 0; i < 1000; i++ {
		copy(flipped, original)
		flipsLen := rng.Intn(30) + 1
		flipsSet := make([]int, 0, flipsLen)
		for len(flipsSet) < flipsLen {
			flipValue := rng.Intn(len(original) * 8)
			flipFound := false
			for j := 0; j < len(flipsSet); j++ {
				if flipsSet[j] == flipValue {
					flipFound = true
					break
				}
			}
			if !flipFound {
				flipsSet = append(flipsSet, flipValue)
			}
		}
		for _, flipValue := range flipsSet {
			mask := byte(0x1 << uint(flipValue%8))
			flipped[flipValue/8] ^= mask
		}
		_, err := DecryptBufferWithKey(config.GetVault().CredentialsDecryptorKey(), flipped)
		if !assert.Error(t, err) {
			t.Fatalf("Failed with flips %v", flipsSet)
			return
		}
	}
}

func TestMain(m *testing.M) {
	config.UseTestFile()
	os.Exit(m.Run())
}
<|endoftext|>


<commit_before>//   Copyright 2009 Joubin Houshyar
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//
package redis

import (
	"time";
)

// ----------------------------------------------------------------------------
// synchronization utilities.
// ----------------------------------------------------------------------------

// Timer
//
// start a new time that will signal on the returned
// channel when the specified ns (timeout in nanoseconds)
// have passsed.  If ns < 0, function returns immediately
// with nil.  Otherwise, the call can select on the channel
// and will recieve an item after timeout.  If the timer
// itself was interrupted during sleep, the value in channel
// will be 0-time-elapsed.  Otherwise, for normal operation,
// it will return time elapsed in ns (which hopefully is very
// close to the specified ns.
//

func NewTimer (ns int64) (signal <-chan int64) {
    if ns <= 0 {
        return nil
    }
    c := make(chan int64);
    go func() {
    	t := time.Nanoseconds();
    	e := time.Sleep(ns);
    	if e != nil {
    		t = 0 - (time.Nanoseconds() - t);
    	}
    	t = time.Nanoseconds() - t;
    	c<- t;
    }();
    return c;
}
<commit_msg>usage example in sync doc.<commit_after>//   Copyright 2009 Joubin Houshyar
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//
package redis

import (
	"time";
)

// ----------------------------------------------------------------------------
// synchronization utilities.
// ----------------------------------------------------------------------------

// Timer
//
// start a new timer that will signal on the returned
// channel when the specified ns (timeout in nanoseconds)
// have passsed.  If ns < 0, function returns immediately
// with nil.  Otherwise, the caller can select on the channel
// and will recieve an item after timeout.  If the timer
// itself was interrupted during sleep, the value in channel
// will be 0-time-elapsed.  Otherwise, for normal operation,
// it will return time elapsed in ns (which hopefully is very
// close to the specified ns.
//

func NewTimer (ns int64) (signal <-chan int64) {
    if ns <= 0 {
        return nil
    }
    c := make(chan int64);
    go func() {
    	t := time.Nanoseconds();
    	e := time.Sleep(ns);
    	if e != nil {
    		t = 0 - (time.Nanoseconds() - t);
    	}
    	t = time.Nanoseconds() - t;
    	c<- t;
    }();
    return c;
}
<|endoftext|>


<commit_before>package astutil

import (
	"fmt"
	"go/ast"
	"go/token"
	"reflect"
	"strings"
)

func IsIdent(expr ast.Expr, ident string) bool {
	id, ok := expr.(*ast.Ident)
	return ok && id.Name == ident
}

// isBlank returns whether id is the blank identifier "_".
// If id == nil, the answer is false.
func IsBlank(id ast.Expr) bool {
	ident, _ := id.(*ast.Ident)
	return ident != nil && ident.Name == "_"
}

// Deprecated: use code.IsIntegerLiteral instead.
func IsIntLiteral(expr ast.Expr, literal string) bool {
	lit, ok := expr.(*ast.BasicLit)
	return ok && lit.Kind == token.INT && lit.Value == literal
}

// Deprecated: use IsIntLiteral instead
func IsZero(expr ast.Expr) bool {
	return IsIntLiteral(expr, "0")
}

func Preamble(f *ast.File) string {
	cutoff := f.Package
	if f.Doc != nil {
		cutoff = f.Doc.Pos()
	}
	var out []string
	for _, cmt := range f.Comments {
		if cmt.Pos() >= cutoff {
			break
		}
		out = append(out, cmt.Text())
	}
	return strings.Join(out, "\n")
}

func GroupSpecs(fset *token.FileSet, specs []ast.Spec) [][]ast.Spec {
	if len(specs) == 0 {
		return nil
	}
	groups := make([][]ast.Spec, 1)
	groups[0] = append(groups[0], specs[0])

	for _, spec := range specs[1:] {
		g := groups[len(groups)-1]
		if fset.PositionFor(spec.Pos(), false).Line-1 !=
			fset.PositionFor(g[len(g)-1].End(), false).Line {

			groups = append(groups, nil)
		}

		groups[len(groups)-1] = append(groups[len(groups)-1], spec)
	}

	return groups
}

// Unparen returns e with any enclosing parentheses stripped.
func Unparen(e ast.Expr) ast.Expr {
	for {
		p, ok := e.(*ast.ParenExpr)
		if !ok {
			return e
		}
		e = p.X
	}
}

// CopyExpr creates a deep copy of an expression.
// It doesn't support copying FuncLits and returns ok == false when encountering one.
func CopyExpr(node ast.Expr) (ast.Expr, bool) {
	switch node := node.(type) {
	case *ast.BasicLit:
		cp := *node
		return &cp, true
	case *ast.BinaryExpr:
		cp := *node
		var ok1, ok2 bool
		cp.X, ok1 = CopyExpr(cp.X)
		cp.Y, ok2 = CopyExpr(cp.Y)
		return &cp, ok1 && ok2
	case *ast.CallExpr:
		var ok bool
		cp := *node
		cp.Fun, ok = CopyExpr(cp.Fun)
		if !ok {
			return nil, false
		}
		cp.Args = make([]ast.Expr, len(node.Args))
		for i, v := range node.Args {
			cp.Args[i], ok = CopyExpr(v)
			if !ok {
				return nil, false
			}
		}
		return &cp, true
	case *ast.CompositeLit:
		var ok bool
		cp := *node
		cp.Type, ok = CopyExpr(cp.Type)
		if !ok {
			return nil, false
		}
		cp.Elts = make([]ast.Expr, len(node.Elts))
		for i, v := range node.Elts {
			cp.Elts[i], ok = CopyExpr(v)
			if !ok {
				return nil, false
			}
		}
		return &cp, true
	case *ast.Ident:
		cp := *node
		return &cp, true
	case *ast.IndexExpr:
		var ok1, ok2 bool
		cp := *node
		cp.X, ok1 = CopyExpr(cp.X)
		cp.Index, ok2 = CopyExpr(cp.Index)
		return &cp, ok1 && ok2
	case *ast.IndexListExpr:
		var ok bool
		cp := *node
		cp.X, ok = CopyExpr(cp.X)
		if !ok {
			return nil, false
		}
		for i, v := range node.Indices {
			cp.Indices[i], ok = CopyExpr(v)
			if !ok {
				return nil, false
			}
		}
		return &cp, true
	case *ast.KeyValueExpr:
		var ok1, ok2 bool
		cp := *node
		cp.Key, ok1 = CopyExpr(cp.Key)
		cp.Value, ok2 = CopyExpr(cp.Value)
		return &cp, ok1 && ok2
	case *ast.ParenExpr:
		var ok bool
		cp := *node
		cp.X, ok = CopyExpr(cp.X)
		return &cp, ok
	case *ast.SelectorExpr:
		var ok bool
		cp := *node
		cp.X, ok = CopyExpr(cp.X)
		if !ok {
			return nil, false
		}
		sel, ok := CopyExpr(cp.Sel)
		if !ok {
			// this is impossible
			return nil, false
		}
		cp.Sel = sel.(*ast.Ident)
		return &cp, true
	case *ast.SliceExpr:
		var ok1, ok2, ok3, ok4 bool
		cp := *node
		cp.X, ok1 = CopyExpr(cp.X)
		cp.Low, ok2 = CopyExpr(cp.Low)
		cp.High, ok3 = CopyExpr(cp.High)
		cp.Max, ok4 = CopyExpr(cp.Max)
		return &cp, ok1 && ok2 && ok3 && ok4
	case *ast.StarExpr:
		var ok bool
		cp := *node
		cp.X, ok = CopyExpr(cp.X)
		return &cp, ok
	case *ast.TypeAssertExpr:
		var ok1, ok2 bool
		cp := *node
		cp.X, ok1 = CopyExpr(cp.X)
		cp.Type, ok2 = CopyExpr(cp.Type)
		return &cp, ok1 && ok2
	case *ast.UnaryExpr:
		var ok bool
		cp := *node
		cp.X, ok = CopyExpr(cp.X)
		return &cp, ok
	case *ast.MapType:
		var ok1, ok2 bool
		cp := *node
		cp.Key, ok1 = CopyExpr(cp.Key)
		cp.Value, ok2 = CopyExpr(cp.Value)
		return &cp, ok1 && ok2
	case *ast.ArrayType:
		var ok1, ok2 bool
		cp := *node
		cp.Len, ok1 = CopyExpr(cp.Len)
		cp.Elt, ok2 = CopyExpr(cp.Elt)
		return &cp, ok1 && ok2
	case *ast.Ellipsis:
		var ok bool
		cp := *node
		cp.Elt, ok = CopyExpr(cp.Elt)
		return &cp, ok
	case *ast.InterfaceType:
		cp := *node
		return &cp, true
	case *ast.StructType:
		cp := *node
		return &cp, true
	case *ast.FuncLit:
		// TODO(dh): implement copying of function literals.
		return nil, false
	case *ast.ChanType:
		var ok bool
		cp := *node
		cp.Value, ok = CopyExpr(cp.Value)
		return &cp, ok
	case nil:
		return nil, true
	default:
		panic(fmt.Sprintf("unreachable: %T", node))
	}
}

func Equal(a, b ast.Node) bool {
	if a == b {
		return true
	}
	if a == nil || b == nil {
		return false
	}
	if reflect.TypeOf(a) != reflect.TypeOf(b) {
		return false
	}

	switch a := a.(type) {
	case *ast.BasicLit:
		b := b.(*ast.BasicLit)
		return a.Kind == b.Kind && a.Value == b.Value
	case *ast.BinaryExpr:
		b := b.(*ast.BinaryExpr)
		return Equal(a.X, b.X) && a.Op == b.Op && Equal(a.Y, b.Y)
	case *ast.CallExpr:
		b := b.(*ast.CallExpr)
		if len(a.Args) != len(b.Args) {
			return false
		}
		for i, arg := range a.Args {
			if !Equal(arg, b.Args[i]) {
				return false
			}
		}
		return Equal(a.Fun, b.Fun) &&
			(a.Ellipsis == token.NoPos && b.Ellipsis == token.NoPos || a.Ellipsis != token.NoPos && b.Ellipsis != token.NoPos)
	case *ast.CompositeLit:
		b := b.(*ast.CompositeLit)
		if len(a.Elts) != len(b.Elts) {
			return false
		}
		for i, elt := range b.Elts {
			if !Equal(elt, b.Elts[i]) {
				return false
			}
		}
		return Equal(a.Type, b.Type) && a.Incomplete == b.Incomplete
	case *ast.Ident:
		b := b.(*ast.Ident)
		return a.Name == b.Name
	case *ast.IndexExpr:
		b := b.(*ast.IndexExpr)
		return Equal(a.X, b.X) && Equal(a.Index, b.Index)
	case *ast.IndexListExpr:
		b := b.(*ast.IndexListExpr)
		if len(a.Indices) != len(b.Indices) {
			return false
		}
		for i, v := range a.Indices {
			if !Equal(v, b.Indices[i]) {
				return false
			}
		}
		return Equal(a.X, b.X)
	case *ast.KeyValueExpr:
		b := b.(*ast.KeyValueExpr)
		return Equal(a.Key, b.Key) && Equal(a.Value, b.Value)
	case *ast.ParenExpr:
		b := b.(*ast.ParenExpr)
		return Equal(a.X, b.X)
	case *ast.SelectorExpr:
		b := b.(*ast.SelectorExpr)
		return Equal(a.X, b.X) && Equal(a.Sel, b.Sel)
	case *ast.SliceExpr:
		b := b.(*ast.SliceExpr)
		return Equal(a.X, b.X) && Equal(a.Low, b.Low) && Equal(a.High, b.High) && Equal(a.Max, b.Max) && a.Slice3 == b.Slice3
	case *ast.StarExpr:
		b := b.(*ast.StarExpr)
		return Equal(a.X, b.X)
	case *ast.TypeAssertExpr:
		b := b.(*ast.TypeAssertExpr)
		return Equal(a.X, b.X) && Equal(a.Type, b.Type)
	case *ast.UnaryExpr:
		b := b.(*ast.UnaryExpr)
		return a.Op == b.Op && Equal(a.X, b.X)
	case *ast.MapType:
		b := b.(*ast.MapType)
		return Equal(a.Key, b.Key) && Equal(a.Value, b.Value)
	case *ast.ArrayType:
		b := b.(*ast.ArrayType)
		return Equal(a.Len, b.Len) && Equal(a.Elt, b.Elt)
	case *ast.Ellipsis:
		b := b.(*ast.Ellipsis)
		return Equal(a.Elt, b.Elt)
	case *ast.InterfaceType:
		b := b.(*ast.InterfaceType)
		return a.Incomplete == b.Incomplete && Equal(a.Methods, b.Methods)
	case *ast.StructType:
		b := b.(*ast.StructType)
		return a.Incomplete == b.Incomplete && Equal(a.Fields, b.Fields)
	case *ast.FuncLit:
		// TODO(dh): support function literals
		return false
	case *ast.ChanType:
		b := b.(*ast.ChanType)
		return a.Dir == b.Dir && (a.Arrow == token.NoPos && b.Arrow == token.NoPos || a.Arrow != token.NoPos && b.Arrow != token.NoPos)
	case *ast.FieldList:
		b := b.(*ast.FieldList)
		if len(a.List) != len(b.List) {
			return false
		}
		for i, fieldA := range a.List {
			if !Equal(fieldA, b.List[i]) {
				return false
			}
		}
		return true
	case *ast.Field:
		b := b.(*ast.Field)
		if len(a.Names) != len(b.Names) {
			return false
		}
		for j, name := range a.Names {
			if !Equal(name, b.Names[j]) {
				return false
			}
		}
		if !Equal(a.Type, b.Type) || !Equal(a.Tag, b.Tag) {
			return false
		}
		return true
	default:
		panic(fmt.Sprintf("unreachable: %T", a))
	}
}
<commit_msg>go/ast/astutil: restore compatibility with Go 1.17<commit_after>package astutil

import (
	"fmt"
	"go/ast"
	"go/token"
	"reflect"
	"strings"

	"golang.org/x/exp/typeparams"
)

func IsIdent(expr ast.Expr, ident string) bool {
	id, ok := expr.(*ast.Ident)
	return ok && id.Name == ident
}

// isBlank returns whether id is the blank identifier "_".
// If id == nil, the answer is false.
func IsBlank(id ast.Expr) bool {
	ident, _ := id.(*ast.Ident)
	return ident != nil && ident.Name == "_"
}

// Deprecated: use code.IsIntegerLiteral instead.
func IsIntLiteral(expr ast.Expr, literal string) bool {
	lit, ok := expr.(*ast.BasicLit)
	return ok && lit.Kind == token.INT && lit.Value == literal
}

// Deprecated: use IsIntLiteral instead
func IsZero(expr ast.Expr) bool {
	return IsIntLiteral(expr, "0")
}

func Preamble(f *ast.File) string {
	cutoff := f.Package
	if f.Doc != nil {
		cutoff = f.Doc.Pos()
	}
	var out []string
	for _, cmt := range f.Comments {
		if cmt.Pos() >= cutoff {
			break
		}
		out = append(out, cmt.Text())
	}
	return strings.Join(out, "\n")
}

func GroupSpecs(fset *token.FileSet, specs []ast.Spec) [][]ast.Spec {
	if len(specs) == 0 {
		return nil
	}
	groups := make([][]ast.Spec, 1)
	groups[0] = append(groups[0], specs[0])

	for _, spec := range specs[1:] {
		g := groups[len(groups)-1]
		if fset.PositionFor(spec.Pos(), false).Line-1 !=
			fset.PositionFor(g[len(g)-1].End(), false).Line {

			groups = append(groups, nil)
		}

		groups[len(groups)-1] = append(groups[len(groups)-1], spec)
	}

	return groups
}

// Unparen returns e with any enclosing parentheses stripped.
func Unparen(e ast.Expr) ast.Expr {
	for {
		p, ok := e.(*ast.ParenExpr)
		if !ok {
			return e
		}
		e = p.X
	}
}

// CopyExpr creates a deep copy of an expression.
// It doesn't support copying FuncLits and returns ok == false when encountering one.
func CopyExpr(node ast.Expr) (ast.Expr, bool) {
	switch node := node.(type) {
	case *ast.BasicLit:
		cp := *node
		return &cp, true
	case *ast.BinaryExpr:
		cp := *node
		var ok1, ok2 bool
		cp.X, ok1 = CopyExpr(cp.X)
		cp.Y, ok2 = CopyExpr(cp.Y)
		return &cp, ok1 && ok2
	case *ast.CallExpr:
		var ok bool
		cp := *node
		cp.Fun, ok = CopyExpr(cp.Fun)
		if !ok {
			return nil, false
		}
		cp.Args = make([]ast.Expr, len(node.Args))
		for i, v := range node.Args {
			cp.Args[i], ok = CopyExpr(v)
			if !ok {
				return nil, false
			}
		}
		return &cp, true
	case *ast.CompositeLit:
		var ok bool
		cp := *node
		cp.Type, ok = CopyExpr(cp.Type)
		if !ok {
			return nil, false
		}
		cp.Elts = make([]ast.Expr, len(node.Elts))
		for i, v := range node.Elts {
			cp.Elts[i], ok = CopyExpr(v)
			if !ok {
				return nil, false
			}
		}
		return &cp, true
	case *ast.Ident:
		cp := *node
		return &cp, true
	case *ast.IndexExpr:
		var ok1, ok2 bool
		cp := *node
		cp.X, ok1 = CopyExpr(cp.X)
		cp.Index, ok2 = CopyExpr(cp.Index)
		return &cp, ok1 && ok2
	case *typeparams.IndexListExpr:
		var ok bool
		cp := *node
		cp.X, ok = CopyExpr(cp.X)
		if !ok {
			return nil, false
		}
		for i, v := range node.Indices {
			cp.Indices[i], ok = CopyExpr(v)
			if !ok {
				return nil, false
			}
		}
		return &cp, true
	case *ast.KeyValueExpr:
		var ok1, ok2 bool
		cp := *node
		cp.Key, ok1 = CopyExpr(cp.Key)
		cp.Value, ok2 = CopyExpr(cp.Value)
		return &cp, ok1 && ok2
	case *ast.ParenExpr:
		var ok bool
		cp := *node
		cp.X, ok = CopyExpr(cp.X)
		return &cp, ok
	case *ast.SelectorExpr:
		var ok bool
		cp := *node
		cp.X, ok = CopyExpr(cp.X)
		if !ok {
			return nil, false
		}
		sel, ok := CopyExpr(cp.Sel)
		if !ok {
			// this is impossible
			return nil, false
		}
		cp.Sel = sel.(*ast.Ident)
		return &cp, true
	case *ast.SliceExpr:
		var ok1, ok2, ok3, ok4 bool
		cp := *node
		cp.X, ok1 = CopyExpr(cp.X)
		cp.Low, ok2 = CopyExpr(cp.Low)
		cp.High, ok3 = CopyExpr(cp.High)
		cp.Max, ok4 = CopyExpr(cp.Max)
		return &cp, ok1 && ok2 && ok3 && ok4
	case *ast.StarExpr:
		var ok bool
		cp := *node
		cp.X, ok = CopyExpr(cp.X)
		return &cp, ok
	case *ast.TypeAssertExpr:
		var ok1, ok2 bool
		cp := *node
		cp.X, ok1 = CopyExpr(cp.X)
		cp.Type, ok2 = CopyExpr(cp.Type)
		return &cp, ok1 && ok2
	case *ast.UnaryExpr:
		var ok bool
		cp := *node
		cp.X, ok = CopyExpr(cp.X)
		return &cp, ok
	case *ast.MapType:
		var ok1, ok2 bool
		cp := *node
		cp.Key, ok1 = CopyExpr(cp.Key)
		cp.Value, ok2 = CopyExpr(cp.Value)
		return &cp, ok1 && ok2
	case *ast.ArrayType:
		var ok1, ok2 bool
		cp := *node
		cp.Len, ok1 = CopyExpr(cp.Len)
		cp.Elt, ok2 = CopyExpr(cp.Elt)
		return &cp, ok1 && ok2
	case *ast.Ellipsis:
		var ok bool
		cp := *node
		cp.Elt, ok = CopyExpr(cp.Elt)
		return &cp, ok
	case *ast.InterfaceType:
		cp := *node
		return &cp, true
	case *ast.StructType:
		cp := *node
		return &cp, true
	case *ast.FuncLit:
		// TODO(dh): implement copying of function literals.
		return nil, false
	case *ast.ChanType:
		var ok bool
		cp := *node
		cp.Value, ok = CopyExpr(cp.Value)
		return &cp, ok
	case nil:
		return nil, true
	default:
		panic(fmt.Sprintf("unreachable: %T", node))
	}
}

func Equal(a, b ast.Node) bool {
	if a == b {
		return true
	}
	if a == nil || b == nil {
		return false
	}
	if reflect.TypeOf(a) != reflect.TypeOf(b) {
		return false
	}

	switch a := a.(type) {
	case *ast.BasicLit:
		b := b.(*ast.BasicLit)
		return a.Kind == b.Kind && a.Value == b.Value
	case *ast.BinaryExpr:
		b := b.(*ast.BinaryExpr)
		return Equal(a.X, b.X) && a.Op == b.Op && Equal(a.Y, b.Y)
	case *ast.CallExpr:
		b := b.(*ast.CallExpr)
		if len(a.Args) != len(b.Args) {
			return false
		}
		for i, arg := range a.Args {
			if !Equal(arg, b.Args[i]) {
				return false
			}
		}
		return Equal(a.Fun, b.Fun) &&
			(a.Ellipsis == token.NoPos && b.Ellipsis == token.NoPos || a.Ellipsis != token.NoPos && b.Ellipsis != token.NoPos)
	case *ast.CompositeLit:
		b := b.(*ast.CompositeLit)
		if len(a.Elts) != len(b.Elts) {
			return false
		}
		for i, elt := range b.Elts {
			if !Equal(elt, b.Elts[i]) {
				return false
			}
		}
		return Equal(a.Type, b.Type) && a.Incomplete == b.Incomplete
	case *ast.Ident:
		b := b.(*ast.Ident)
		return a.Name == b.Name
	case *ast.IndexExpr:
		b := b.(*ast.IndexExpr)
		return Equal(a.X, b.X) && Equal(a.Index, b.Index)
	case *typeparams.IndexListExpr:
		b := b.(*typeparams.IndexListExpr)
		if len(a.Indices) != len(b.Indices) {
			return false
		}
		for i, v := range a.Indices {
			if !Equal(v, b.Indices[i]) {
				return false
			}
		}
		return Equal(a.X, b.X)
	case *ast.KeyValueExpr:
		b := b.(*ast.KeyValueExpr)
		return Equal(a.Key, b.Key) && Equal(a.Value, b.Value)
	case *ast.ParenExpr:
		b := b.(*ast.ParenExpr)
		return Equal(a.X, b.X)
	case *ast.SelectorExpr:
		b := b.(*ast.SelectorExpr)
		return Equal(a.X, b.X) && Equal(a.Sel, b.Sel)
	case *ast.SliceExpr:
		b := b.(*ast.SliceExpr)
		return Equal(a.X, b.X) && Equal(a.Low, b.Low) && Equal(a.High, b.High) && Equal(a.Max, b.Max) && a.Slice3 == b.Slice3
	case *ast.StarExpr:
		b := b.(*ast.StarExpr)
		return Equal(a.X, b.X)
	case *ast.TypeAssertExpr:
		b := b.(*ast.TypeAssertExpr)
		return Equal(a.X, b.X) && Equal(a.Type, b.Type)
	case *ast.UnaryExpr:
		b := b.(*ast.UnaryExpr)
		return a.Op == b.Op && Equal(a.X, b.X)
	case *ast.MapType:
		b := b.(*ast.MapType)
		return Equal(a.Key, b.Key) && Equal(a.Value, b.Value)
	case *ast.ArrayType:
		b := b.(*ast.ArrayType)
		return Equal(a.Len, b.Len) && Equal(a.Elt, b.Elt)
	case *ast.Ellipsis:
		b := b.(*ast.Ellipsis)
		return Equal(a.Elt, b.Elt)
	case *ast.InterfaceType:
		b := b.(*ast.InterfaceType)
		return a.Incomplete == b.Incomplete && Equal(a.Methods, b.Methods)
	case *ast.StructType:
		b := b.(*ast.StructType)
		return a.Incomplete == b.Incomplete && Equal(a.Fields, b.Fields)
	case *ast.FuncLit:
		// TODO(dh): support function literals
		return false
	case *ast.ChanType:
		b := b.(*ast.ChanType)
		return a.Dir == b.Dir && (a.Arrow == token.NoPos && b.Arrow == token.NoPos || a.Arrow != token.NoPos && b.Arrow != token.NoPos)
	case *ast.FieldList:
		b := b.(*ast.FieldList)
		if len(a.List) != len(b.List) {
			return false
		}
		for i, fieldA := range a.List {
			if !Equal(fieldA, b.List[i]) {
				return false
			}
		}
		return true
	case *ast.Field:
		b := b.(*ast.Field)
		if len(a.Names) != len(b.Names) {
			return false
		}
		for j, name := range a.Names {
			if !Equal(name, b.Names[j]) {
				return false
			}
		}
		if !Equal(a.Type, b.Type) || !Equal(a.Tag, b.Tag) {
			return false
		}
		return true
	default:
		panic(fmt.Sprintf("unreachable: %T", a))
	}
}
<|endoftext|>


<commit_before>// Package dnsimple/webhook provides the support for reading and parsing the events
// sent from DNSimple via webhook.
package webhook

import (
	"encoding/json"
)

// Actor represents the entity that triggered the event. It can be either an user,
// a DNSimple support representative or the DNSimple system.
type Actor struct {
	ID     int    `json:"id"`
	Entity string `json:"entity"`
	Pretty string `json:"pretty"`
}

// Event is an event generated in the DNSimple application.
type Event interface {
	EventName() string
	EventHeader() *Event_Header
	Payload() []byte
	parse([]byte) error
}

type Event_Header struct {
	APIVersion string `json:"api_version"`
	RequestID  string `json:"request_identifier"`
	Actor      *Actor `json:"actor"`
	Name       string `json:"name"`
	payload    []byte
}

type eventName struct {
	Name string `json:"name"`
}

// Event returns the event name as defined in the name field of the payload.
func (e *Event_Header) EventHeader() *Event_Header {
	return e
}

// EventName returns the event name as defined in the name field of the payload.
func (e *Event_Header) EventName() string {
	return e.Name
}

// Payload returns the binary payload the event was deserialized from.
func (e *Event_Header) Payload() []byte {
	return e.payload
}

func (e *Event_Header) parse(payload []byte) error {
	e.payload = payload
	return unmashalEvent(payload, e)
}

// Parse takes a payload and attempts to deserialize the payload into an event type
// that matches the event action in the payload. If no direct match is found, then a DefaultEvent is returned.
//
// Parse returns type is an Event interface. Therefore, you must perform typecasting
// to access any event-specific field.
func Parse(payload []byte) (Event, error) {
	action, err := ParseName(payload)
	if err != nil {
		return nil, err
	}

	return switchEvent(action, payload)
}

func ParseName(data []byte) (string, error) {
	eventName := &eventName{}
	err := json.Unmarshal(data, eventName)
	return eventName.Name, err
}

func unmashalEvent(data []byte, v interface{}) error {
	return json.Unmarshal(data, v)
}
<commit_msg>Fixed warning: package comment should be of the form "Package webhook ..."<commit_after>// Package webhook provides the support for reading and parsing the events
// sent from DNSimple via webhook.
package webhook

import (
	"encoding/json"
)

// Actor represents the entity that triggered the event. It can be either an user,
// a DNSimple support representative or the DNSimple system.
type Actor struct {
	ID     int    `json:"id"`
	Entity string `json:"entity"`
	Pretty string `json:"pretty"`
}

// Event is an event generated in the DNSimple application.
type Event interface {
	EventName() string
	EventHeader() *Event_Header
	Payload() []byte
	parse([]byte) error
}

type Event_Header struct {
	APIVersion string `json:"api_version"`
	RequestID  string `json:"request_identifier"`
	Actor      *Actor `json:"actor"`
	Name       string `json:"name"`
	payload    []byte
}

type eventName struct {
	Name string `json:"name"`
}

// Event returns the event name as defined in the name field of the payload.
func (e *Event_Header) EventHeader() *Event_Header {
	return e
}

// EventName returns the event name as defined in the name field of the payload.
func (e *Event_Header) EventName() string {
	return e.Name
}

// Payload returns the binary payload the event was deserialized from.
func (e *Event_Header) Payload() []byte {
	return e.payload
}

func (e *Event_Header) parse(payload []byte) error {
	e.payload = payload
	return unmashalEvent(payload, e)
}

// Parse takes a payload and attempts to deserialize the payload into an event type
// that matches the event action in the payload. If no direct match is found, then a DefaultEvent is returned.
//
// Parse returns type is an Event interface. Therefore, you must perform typecasting
// to access any event-specific field.
func Parse(payload []byte) (Event, error) {
	action, err := ParseName(payload)
	if err != nil {
		return nil, err
	}

	return switchEvent(action, payload)
}

func ParseName(data []byte) (string, error) {
	eventName := &eventName{}
	err := json.Unmarshal(data, eventName)
	return eventName.Name, err
}

func unmashalEvent(data []byte, v interface{}) error {
	return json.Unmarshal(data, v)
}
<|endoftext|>


<commit_before>// This is the main package for the `packer` application.
package main

import (
	"bytes"
	"fmt"
	"github.com/mitchellh/packer/packer"
	"github.com/mitchellh/packer/packer/plugin"
	"io/ioutil"
	"log"
	"os"
	"runtime"
)

func main() {
	if os.Getenv("PACKER_LOG") == "" {
		// If we don't have logging explicitly enabled, then disable it
		log.SetOutput(ioutil.Discard)
	} else {
		// Logging is enabled, make sure it goes to stderr
		log.SetOutput(os.Stderr)
	}

	// If there is no explicit number of Go threads to use, then set it
	if os.Getenv("GOMAXPROCS") == "" {
		runtime.GOMAXPROCS(runtime.NumCPU())
	}

	config, err := loadConfig()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error loading configuration: \n\n%s\n", err)
		os.Exit(1)
	}

	log.Printf("Packer config: %+v", config)

	defer plugin.CleanupClients()

	var cache packer.Cache
	if cacheDir := os.Getenv("PACKER_CACHE_DIR"); cacheDir != "" {
		if err := os.MkdirAll(cacheDir, 0755); err != nil {
			fmt.Fprintf(os.Stderr, "Error preparing cache directory: \n\n%s\n", err)
			os.Exit(1)
		}

		log.Printf("Setting cache directory: %s", cacheDir)
		cache = &packer.FileCache{CacheDir: cacheDir}
	}

	envConfig := packer.DefaultEnvironmentConfig()
	envConfig.Cache = cache
	envConfig.Commands = config.CommandNames()
	envConfig.Components.Builder = config.LoadBuilder
	envConfig.Components.Command = config.LoadCommand
	envConfig.Components.Hook = config.LoadHook
	envConfig.Components.PostProcessor = config.LoadPostProcessor
	envConfig.Components.Provisioner = config.LoadProvisioner

	env, err := packer.NewEnvironment(envConfig)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Packer initialization error: \n\n%s\n", err)
		os.Exit(1)
	}

	setupSignalHandlers(env)

	exitCode, err := env.Cli(os.Args[1:])
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error executing CLI: %s\n", err.Error())
		os.Exit(1)
	}

	plugin.CleanupClients()
	os.Exit(exitCode)
}

func loadConfig() (*config, error) {
	var config config
	if err := decodeConfig(bytes.NewBufferString(defaultConfig), &config); err != nil {
		return nil, err
	}

	mustExist := true
	configFilePath := os.Getenv("PACKER_CONFIG")
	if configFilePath == "" {
		var err error
		configFilePath, err = configFile()
		mustExist = false

		if err != nil {
			log.Printf("Error detecing default config file path: %s", err)
		}
	}

	if configFilePath == "" {
		return &config, nil
	}

	log.Printf("Attempting to open config file: %s", configFilePath)
	f, err := os.Open(configFilePath)
	if err != nil {
		if !os.IsNotExist(err) {
			return nil, err
		}

		if mustExist {
			return nil, err
		}

		log.Println("File doesn't exist, but doesn't need to. Ignoring.")
		return &config, nil
	}
	defer f.Close()

	if err := decodeConfig(f, &config); err != nil {
		return nil, err
	}

	return &config, nil
}
<commit_msg>Default cache to "packer_cache" in CWD<commit_after>// This is the main package for the `packer` application.
package main

import (
	"bytes"
	"fmt"
	"github.com/mitchellh/packer/packer"
	"github.com/mitchellh/packer/packer/plugin"
	"io/ioutil"
	"log"
	"os"
	"runtime"
)

func main() {
	if os.Getenv("PACKER_LOG") == "" {
		// If we don't have logging explicitly enabled, then disable it
		log.SetOutput(ioutil.Discard)
	} else {
		// Logging is enabled, make sure it goes to stderr
		log.SetOutput(os.Stderr)
	}

	// If there is no explicit number of Go threads to use, then set it
	if os.Getenv("GOMAXPROCS") == "" {
		runtime.GOMAXPROCS(runtime.NumCPU())
	}

	config, err := loadConfig()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error loading configuration: \n\n%s\n", err)
		os.Exit(1)
	}

	log.Printf("Packer config: %+v", config)

	defer plugin.CleanupClients()

	cacheDir := os.Getenv("PACKER_CACHE_DIR")
	if cacheDir == "" {
		cacheDir = "packer_cache"
	}

	if err := os.MkdirAll(cacheDir, 0755); err != nil {
		fmt.Fprintf(os.Stderr, "Error preparing cache directory: \n\n%s\n", err)
		os.Exit(1)
	}

	log.Printf("Setting cache directory: %s", cacheDir)
	cache := &packer.FileCache{CacheDir: cacheDir}

	envConfig := packer.DefaultEnvironmentConfig()
	envConfig.Cache = cache
	envConfig.Commands = config.CommandNames()
	envConfig.Components.Builder = config.LoadBuilder
	envConfig.Components.Command = config.LoadCommand
	envConfig.Components.Hook = config.LoadHook
	envConfig.Components.PostProcessor = config.LoadPostProcessor
	envConfig.Components.Provisioner = config.LoadProvisioner

	env, err := packer.NewEnvironment(envConfig)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Packer initialization error: \n\n%s\n", err)
		os.Exit(1)
	}

	setupSignalHandlers(env)

	exitCode, err := env.Cli(os.Args[1:])
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error executing CLI: %s\n", err.Error())
		os.Exit(1)
	}

	plugin.CleanupClients()
	os.Exit(exitCode)
}

func loadConfig() (*config, error) {
	var config config
	if err := decodeConfig(bytes.NewBufferString(defaultConfig), &config); err != nil {
		return nil, err
	}

	mustExist := true
	configFilePath := os.Getenv("PACKER_CONFIG")
	if configFilePath == "" {
		var err error
		configFilePath, err = configFile()
		mustExist = false

		if err != nil {
			log.Printf("Error detecing default config file path: %s", err)
		}
	}

	if configFilePath == "" {
		return &config, nil
	}

	log.Printf("Attempting to open config file: %s", configFilePath)
	f, err := os.Open(configFilePath)
	if err != nil {
		if !os.IsNotExist(err) {
			return nil, err
		}

		if mustExist {
			return nil, err
		}

		log.Println("File doesn't exist, but doesn't need to. Ignoring.")
		return &config, nil
	}
	defer f.Close()

	if err := decodeConfig(f, &config); err != nil {
		return nil, err
	}

	return &config, nil
}
<|endoftext|>