aboutsummaryrefslogtreecommitdiffstats
path: root/conf/dmarc_whitelist.inc
Commit message (Expand)AuthorAgeFilesLines
* domain addedAndrey Igoshin2018-07-031-0/+1
* domains addedAndrey Igoshin2018-06-231-0/+2
* [Minor] domains addedAndrey Igoshin2018-05-101-0/+1
* [Minor] domains addedAndrey Igoshin2018-05-011-0/+2
* [Minor] domains addedAndrey Igoshin2018-04-261-0/+13
* [Feature] Allow to disable specific workers in the configVsevolod Stakhov2017-06-191-0/+1
* [Minor] Add some entries to dmarc whitelistVsevolod Stakhov2017-06-161-0/+6
* [Minor] Sort & clean up spf-dkim/dmarc whitelistsAndrew Lewis2016-08-201-2/+0
* [Minor] Remove google.com from whitelist because of spam abuseVsevolod Stakhov2016-08-171-43/+0
* [Minor] Add alibaba domains to whitelistVsevolod Stakhov2016-08-101-0/+3
* [Fix] Remove some bad domains from whitelistsVsevolod Stakhov2016-04-211-3/+1
* Add facebookmail.com to dmarc whitelist.Vsevolod Stakhov2015-09-161-0/+1
* Add whitelist configuration.Vsevolod Stakhov2015-09-161-0/+85
light .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package git

import (
	"bufio"
	"bytes"
	"context"
	"fmt"
	"io"
	"os"

	"code.gitea.io/gitea/modules/log"
	"code.gitea.io/gitea/modules/util"
)

// BlamePart represents block of blame - continuous lines with one sha
type BlamePart struct {
	Sha          string
	Lines        []string
	PreviousSha  string
	PreviousPath string
}

// BlameReader returns part of file blame one by one
type BlameReader struct {
	output         io.WriteCloser
	reader         io.ReadCloser
	bufferedReader *bufio.Reader
	done           chan error
	lastSha        *string
	ignoreRevsFile *string
	objectFormat   ObjectFormat
}

func (r *BlameReader) UsesIgnoreRevs() bool {
	return r.ignoreRevsFile != nil
}

// NextPart returns next part of blame (sequential code lines with the same commit)
func (r *BlameReader) NextPart() (*BlamePart, error) {
	var blamePart *BlamePart

	if r.lastSha != nil {
		blamePart = &BlamePart{
			Sha:   *r.lastSha,
			Lines: make([]string, 0),
		}
	}

	const previousHeader = "previous "
	var lineBytes []byte
	var isPrefix bool
	var err error

	for err != io.EOF {
		lineBytes, isPrefix, err = r.bufferedReader.ReadLine()
		if err != nil && err != io.EOF {
			return blamePart, err
		}

		if len(lineBytes) == 0 {
			// isPrefix will be false
			continue
		}

		var objectID string
		objectFormatLength := r.objectFormat.FullLength()

		if len(lineBytes) > objectFormatLength && lineBytes[objectFormatLength] == ' ' && r.objectFormat.IsValid(string(lineBytes[0:objectFormatLength])) {
			objectID = string(lineBytes[0:objectFormatLength])
		}
		if len(objectID) > 0 {
			if blamePart == nil {
				blamePart = &BlamePart{
					Sha:   objectID,
					Lines: make([]string, 0),
				}
			}

			if blamePart.Sha != objectID {
				r.lastSha = &objectID
				// need to munch to end of line...
				for isPrefix {
					_, isPrefix, err = r.bufferedReader.ReadLine()
					if err != nil && err != io.EOF {
						return blamePart, err
					}
				}
				return blamePart, nil
			}
		} else if lineBytes[0] == '\t' {
			blamePart.Lines = append(blamePart.Lines, string(lineBytes[1:]))
		} else if bytes.HasPrefix(lineBytes, []byte(previousHeader)) {
			offset := len(previousHeader) // already includes a space
			blamePart.PreviousSha = string(lineBytes[offset : offset+objectFormatLength])
			offset += objectFormatLength + 1 // +1 for space
			blamePart.PreviousPath = string(lineBytes[offset:])
		}

		// need to munch to end of line...
		for isPrefix {
			_, isPrefix, err = r.bufferedReader.ReadLine()
			if err != nil && err != io.EOF {
				return blamePart, err
			}
		}
	}

	r.lastSha = nil

	return blamePart, nil
}

// Close BlameReader - don't run NextPart after invoking that
func (r *BlameReader) Close() error {
	err := <-r.done
	r.bufferedReader = nil
	_ = r.reader.Close()
	_ = r.output.Close()
	if r.ignoreRevsFile != nil {
		_ = util.Remove(*r.ignoreRevsFile)
	}
	return err
}

// CreateBlameReader creates reader for given repository, commit and file
func CreateBlameReader(ctx context.Context, objectFormat ObjectFormat, repoPath string, commit *Commit, file string, bypassBlameIgnore bool) (*BlameReader, error) {
	var ignoreRevsFile *string
	if CheckGitVersionAtLeast("2.23") == nil && !bypassBlameIgnore {
		ignoreRevsFile = tryCreateBlameIgnoreRevsFile(commit)
	}

	cmd := NewCommandContextNoGlobals(ctx, "blame", "--porcelain")
	if ignoreRevsFile != nil {
		// Possible improvement: use --ignore-revs-file /dev/stdin on unix
		// There is no equivalent on Windows. May be implemented if Gitea uses an external git backend.
		cmd.AddOptionValues("--ignore-revs-file", *ignoreRevsFile)
	}
	cmd.AddDynamicArguments(commit.ID.String()).
		AddDashesAndList(file).
		SetDescription(fmt.Sprintf("GetBlame [repo_path: %s]", repoPath))
	reader, stdout, err := os.Pipe()
	if err != nil {
		if ignoreRevsFile != nil {
			_ = util.Remove(*ignoreRevsFile)
		}
		return nil, err
	}

	done := make(chan error, 1)

	go func() {
		stderr := bytes.Buffer{}
		// TODO: it doesn't work for directories (the directories shouldn't be "blamed"), and the "err" should be returned by "Read" but not by "Close"
		err := cmd.Run(&RunOpts{
			UseContextTimeout: true,
			Dir:               repoPath,
			Stdout:            stdout,
			Stderr:            &stderr,
		})
		done <- err
		_ = stdout.Close()
		if err != nil {
			log.Error("Error running git blame (dir: %v): %v, stderr: %v", repoPath, err, stderr.String())
		}
	}()

	bufferedReader := bufio.NewReader(reader)

	return &BlameReader{
		output:         stdout,
		reader:         reader,
		bufferedReader: bufferedReader,
		done:           done,
		ignoreRevsFile: ignoreRevsFile,
		objectFormat:   objectFormat,
	}, nil
}

func tryCreateBlameIgnoreRevsFile(commit *Commit) *string {
	entry, err := commit.GetTreeEntryByPath(".git-blame-ignore-revs")
	if err != nil {
		return nil
	}

	r, err := entry.Blob().DataAsync()
	if err != nil {
		return nil
	}
	defer r.Close()

	f, err := os.CreateTemp("", "gitea_git-blame-ignore-revs")
	if err != nil {
		return nil
	}

	_, err = io.Copy(f, r)
	_ = f.Close()
	if err != nil {
		_ = util.Remove(f.Name())
		return nil
	}

	return util.ToPointer(f.Name())
}