@@ -51,12 +51,12 @@ static void send_chunk(h2o_ostream_t *_self, h2o_req_t *req, h2o_iovec_t *inbufs
         outbufcnt += inbufcnt;
         if (state != H2O_SEND_STATE_ERROR) {
             outbufs[outbufcnt].base = "\r\n0\r\n\r\n";
-            outbufs[outbufcnt].len = state == H2O_SEND_STATE_FINAL ? (req->send_server_timing ? 5 : 7) : 2;
+            outbufs[outbufcnt].len = state == H2O_SEND_STATE_FINAL ? (req->send_server_timing_trailer ? 5 : 7) : 2;
             outbufcnt++;
         }
     } else if (state == H2O_SEND_STATE_FINAL) {
         outbufs[outbufcnt].base = "0\r\n\r\n";
-        outbufs[outbufcnt].len = req->send_server_timing ? 3 : 5;
+        outbufs[outbufcnt].len = req->send_server_timing_trailer ? 3 : 5;
         outbufcnt++;
     }

/*
 * Copyright (c) 2014 DeNA Co., Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "h2o.h"

typedef struct st_chunked_encoder_t {
    h2o_ostream_t super;
    char buf[64];
} chunked_encoder_t;

static void send_chunk(h2o_ostream_t *_self, h2o_req_t *req, h2o_iovec_t *inbufs, size_t inbufcnt, h2o_send_state_t state)
{
    chunked_encoder_t *self = (void *)_self;
    h2o_iovec_t *outbufs = alloca(sizeof(h2o_iovec_t) * (inbufcnt + 2));
    size_t chunk_size, outbufcnt = 0, i;

    /* calc chunk size */
    chunk_size = 0;
    for (i = 0; i != inbufcnt; ++i)
        chunk_size += inbufs[i].len;
    req->bytes_sent += chunk_size;

    /* create chunk header and output data */
    if (chunk_size != 0) {
        outbufs[outbufcnt].base = self->buf;
        outbufs[outbufcnt].len = sprintf(self->buf, "%zx\r\n", chunk_size);
        assert(outbufs[outbufcnt].len < sizeof(self->buf));
        outbufcnt++;
        memcpy(outbufs + outbufcnt, inbufs, sizeof(h2o_iovec_t) * inbufcnt);
        outbufcnt += inbufcnt;
        if (state != H2O_SEND_STATE_ERROR) {
            outbufs[outbufcnt].base = "\r\n0\r\n\r\n";
            outbufs[outbufcnt].len = state == H2O_SEND_STATE_FINAL ? (req->send_server_timing ? 5 : 7) : 2;
            outbufcnt++;
        }
    } else if (state == H2O_SEND_STATE_FINAL) {
        outbufs[outbufcnt].base = "0\r\n\r\n";
        outbufs[outbufcnt].len = req->send_server_timing ? 3 : 5;
        outbufcnt++;
    }

    /* if state is error, send a broken chunk to pass the error down to the browser */
    if (state == H2O_SEND_STATE_ERROR) {
        outbufs[outbufcnt].base = "\r\n1\r\n";
        outbufs[outbufcnt].len = 5;
        outbufcnt++;
    }

    h2o_ostream_send_next(&self->super, req, outbufs, outbufcnt, state);
}

static void on_setup_ostream(h2o_filter_t *self, h2o_req_t *req, h2o_ostream_t **slot)
{
    chunked_encoder_t *encoder;

    /* TODO: make chunked filter a submodule of lib/http1.c so that we could eliminate this flag, protocol version checks, etc. */
    if (req->is_subrequest)
        goto Next;

    /* do nothing if not HTTP/1.1 or content-length is known */
    if (req->res.content_length != SIZE_MAX || req->version != 0x101)
        goto Next;
    /* RFC 2616 4.4 states that the following status codes (and response to a HEAD method) should not include message body */
    if ((100 <= req->res.status && req->res.status <= 199) || req->res.status == 204 || req->res.status == 304)
        goto Next;
    else if (h2o_memis(req->input.method.base, req->input.method.len, H2O_STRLIT("HEAD")))
        goto Next;
    /* we cannot handle certain responses (like 101 switching protocols) */
    if (req->res.status != 200) {
        req->http1_is_persistent = 0;
        goto Next;
    }
    /* skip if content-encoding header is being set */
    if (h2o_find_header(&req->res.headers, H2O_TOKEN_TRANSFER_ENCODING, -1) != -1)
        goto Next;

    /* set content-encoding header */
    h2o_add_header(&req->pool, &req->res.headers, H2O_TOKEN_TRANSFER_ENCODING, NULL, H2O_STRLIT("chunked"));

    /* set the flag that tells finalostream that req->bytes_sent is already counted */
    req->bytes_counted_by_ostream = 1;

    /* setup filter */
    encoder = (void *)h2o_add_ostream(req, H2O_ALIGNOF(*encoder), sizeof(*encoder), slot);
    encoder->super.do_send = send_chunk;
    slot = &encoder->super.next;

Next:
    h2o_setup_next_ostream(req, slot);
}

void h2o_chunked_register(h2o_pathconf_t *pathconf)
{
    h2o_filter_t *self = h2o_create_filter(pathconf, sizeof(*self));
    self->on_setup_ostream = on_setup_ostream;
}


@@ -139,22 +139,30 @@ class TestSuppress(unittest.TestCase):
                                                    'status': rw_status}

         run_results = get_all_run_results(self._cc_client, runid)
+        logging.debug("Run results:")
+        [logging.debug(x) for x in run_results]
         self.assertIsNotNone(run_results)
         self.assertNotEqual(len(run_results), 0)

         for bug_hash in hash_to_suppress_msgs:
-            expected = hash_to_suppress_msgs[bug_hash]
-            report = [x for x in run_results if x.bugHash == bug_hash][0]
+            expected_data = hash_to_suppress_msgs[bug_hash]
+            report_data_of_bug = [
+                report_data for report_data in run_results
+                if report_data.bugHash == bug_hash]
+            self.assertEqual(len(report_data_of_bug), 1)
+            report_data = report_data_of_bug[0]

             # Check the stored suppress comment
-            self.assertEqual(report.reviewData.comment, expected['message'])
-            self.assertEqual(report.reviewData.status, expected['status'])
+            self.assertEqual(report_data.reviewData.comment,
+                             expected_data['message'])
+            self.assertEqual(report_data.reviewData.status,
+                             expected_data['status'])

             # Change review status to confirmed bug.
             review_comment = "This is really a bug"
             status = ReviewStatus.CONFIRMED
             success = self._cc_client.changeReviewStatus(
-                report.reportId, status, review_comment)
+                report_data.reportId, status, review_comment)

             self.assertTrue(success)
             logging.debug("Bug review status changed successfully")

# -------------------------------------------------------------------------
#
#  Part of the CodeChecker project, under the Apache License v2.0 with
#  LLVM Exceptions. See LICENSE for license information.
#  SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# -------------------------------------------------------------------------
"""
Test source-code level suppression data writing to suppress file.
"""

import logging
import os
import shlex
import sys
import subprocess
from subprocess import CalledProcessError
import unittest

from codechecker_api.codeCheckerDBAccess_v6.ttypes import ReviewStatus

from libtest import env
from libtest import codechecker
from libtest.thrift_client_to_db import get_all_run_results

def call_cmd(command, cwd, env):
    try:
        print(' '.join(command))
        proc = subprocess.Popen(
            shlex.split(' '.join(command)),
            cwd=cwd,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            env=env, encoding="utf-8", errors="ignore")
        out, err = proc.communicate()
        print(out)
        print(err)
        return proc.returncode
    except CalledProcessError as cerr:
        print("Failed to call:\n" + ' '.join(cerr.cmd))
        return cerr.returncode

class TestSuppress(unittest.TestCase):
    """
    Test source-code level suppression data writing to suppress file.
    """

    def setUp(self):
        self._test_workspace = os.environ['TEST_WORKSPACE']

        self._testproject_data = env.setup_test_proj_cfg(self._test_workspace)
        self.assertIsNotNone(self._testproject_data)

        self._test_project_path = self._testproject_data['project_path']

        self._cc_client = env.setup_viewer_client(self._test_workspace)
        self.assertIsNotNone(self._cc_client)

        # Get the run names which belong to this test
        run_names = env.get_run_names(self._test_workspace)

        runs = self._cc_client.getRunData(None, None, 0, None)

        test_runs = [run for run in runs if run.name in run_names]

        self.assertEqual(len(test_runs), 1,
                         'There should be only one run for this test.')
        self._runid = test_runs[0].runId
        self._run_name = test_runs[0].name

    def test_suppress_import(self):
        """
        Test the suppress file importing.
        """

        generated_file = os.path.join(self._test_workspace,
                                      "generated.suppress")

        extract_cmd = ['CodeChecker', 'parse',
                       os.path.join(self._test_workspace, "reports"),
                       "--suppress", generated_file,
                       "--export-source-suppress"
                       ]

        ret = call_cmd(extract_cmd,
                       self._test_project_path,
                       env.test_env(self._test_workspace))
        self.assertEqual(ret, 2, "Failed to generate suppress file.")

        codechecker_cfg = env.import_test_cfg(
            self._test_workspace)['codechecker_cfg']

        product_url = env.parts_to_url(codechecker_cfg)
        import_cmd = ['CodeChecker', 'cmd', 'suppress', '-i', generated_file,
                      '--url', product_url, self._run_name]

        print(import_cmd)
        ret = call_cmd(import_cmd,
                       self._test_project_path,
                       env.test_env(self._test_workspace))
        self.assertEqual(ret, 0, "Failed to import suppress file.")

    def test_suppress_comment_in_db(self):
        """
        Exported source suppress comment stored as a review status in the db.
        """
        runid = self._runid
        logging.debug("Get all run results from the db for runid: " +
                      str(runid))

        hash_to_suppress_msgs = {}
        with open(os.path.join(self._test_project_path, "suppress.expected"),
                  'r', encoding="utf-8", errors="ignore") as expected:
            for line in expected:
                src_code_info = line.strip().split('||')

                status = None
                if len(src_code_info) == 4:
                    # Newest source code comment format where status is given.
                    bug_hash, _, msg, status = src_code_info
                elif len(src_code_info) == 3:
                    # Old format where review status is not given.
                    bug_hash, _, msg = src_code_info
                else:
                    # Oldest source code comment format where status and file
                    # name are not given.
                    bug_hash, msg = src_code_info

                rw_status = ReviewStatus.FALSE_POSITIVE
                if status == 'confirmed':
                    rw_status = ReviewStatus.CONFIRMED
                elif status == 'intentional':
                    rw_status = ReviewStatus.INTENTIONAL

                hash_to_suppress_msgs[bug_hash] = {'message': msg,
                                                   'status': rw_status}

        run_results = get_all_run_results(self._cc_client, runid)
        self.assertIsNotNone(run_results)
        self.assertNotEqual(len(run_results), 0)

        for bug_hash in hash_to_suppress_msgs:
            expected = hash_to_suppress_msgs[bug_hash]
            report = [x for x in run_results if x.bugHash == bug_hash][0]

            # Check the stored suppress comment
            self.assertEqual(report.reviewData.comment, expected['message'])
            self.assertEqual(report.reviewData.status, expected['status'])

            # Change review status to confirmed bug.
            review_comment = "This is really a bug"
            status = ReviewStatus.CONFIRMED
            success = self._cc_client.changeReviewStatus(
                report.reportId, status, review_comment)

            self.assertTrue(success)
            logging.debug("Bug review status changed successfully")

        # Get the results to compare.
        updated_results = get_all_run_results(self._cc_client, self._runid)
        self.assertIsNotNone(updated_results)
        self.assertNotEqual(len(updated_results), 0)

        for bug_hash in hash_to_suppress_msgs:
            report = [x for x in updated_results if x.bugHash == bug_hash][0]

            # Check the stored suppress comment
            self.assertEqual(report.reviewData.comment, "This is really a bug")
            self.assertEqual(report.reviewData.status, ReviewStatus.CONFIRMED)

        # Check the same project again.
        codechecker_cfg = env.import_test_cfg(
            self._test_workspace)['codechecker_cfg']

        initial_test_project_name = self._run_name

        ret = codechecker.check_and_store(codechecker_cfg,
                                          initial_test_project_name,
                                          self._test_project_path)
        if ret:
            sys.exit(1)

        # Get the results to compare.
        updated_results = get_all_run_results(self._cc_client, self._runid)
        self.assertIsNotNone(updated_results)
        self.assertNotEqual(len(updated_results), 0)

        for bug_hash in hash_to_suppress_msgs:
            expected = hash_to_suppress_msgs[bug_hash]
            report = [x for x in updated_results if x.bugHash == bug_hash][0]

            # Check that source code comments in the database are changed back
            # after storage.
            self.assertEqual(report.reviewData.comment, expected['message'])
            self.assertEqual(report.reviewData.status, expected['status'])


@@ -43,6 +43,9 @@ const (

 	IPSetIDAllHostIPs = "all-hosts"

+	ChainFipDnat = ChainNamePrefix + "-fip-dnat"
+	ChainFipSnat = ChainNamePrefix + "-fip-snat"
+
 	PolicyInboundPfx  = ChainNamePrefix + "pi-"
 	PolicyOutboundPfx = ChainNamePrefix + "po-"

// Copyright (c) 2016-2017 Tigera, Inc. All rights reserved.
//
// 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 rules

import (
	log "github.com/Sirupsen/logrus"
	"github.com/projectcalico/felix/go/felix/ipsets"
	"github.com/projectcalico/felix/go/felix/iptables"
	"github.com/projectcalico/felix/go/felix/proto"
	"net"
	"strings"
)

const (
	ChainNamePrefix = "cali"
	IPSetNamePrefix = "cali"

	ChainFilterInput   = ChainNamePrefix + "-INPUT"
	ChainFilterForward = ChainNamePrefix + "-FORWARD"
	ChainFilterOutput  = ChainNamePrefix + "-OUTPUT"

	ChainFailsafeIn  = ChainNamePrefix + "-failsafe-in"
	ChainFailsafeOut = ChainNamePrefix + "-failsafe-out"

	ChainNATPrerouting  = ChainNamePrefix + "-PREROUTING"
	ChainNATPostrouting = ChainNamePrefix + "-POSTROUTING"
	ChainNATOutgoing    = ChainNamePrefix + "-nat-outgoing"

	IPSetIDNATOutgoingAllPools  = "all-ipam-pools"
	IPSetIDNATOutgoingMasqPools = "masq-ipam-pools"

	IPSetIDAllHostIPs = "all-hosts"

	PolicyInboundPfx  = ChainNamePrefix + "pi-"
	PolicyOutboundPfx = ChainNamePrefix + "po-"

	ChainWorkloadToHost       = ChainNamePrefix + "-wl-to-host"
	ChainFromWorkloadDispatch = ChainNamePrefix + "-from-wl-dispatch"
	ChainToWorkloadDispatch   = ChainNamePrefix + "-to-wl-dispatch"

	ChainDispatchToHostEndpoint   = ChainNamePrefix + "-to-host-endpoint"
	ChainDispatchFromHostEndpoint = ChainNamePrefix + "-from-host-endpoint"

	WorkloadToEndpointPfx   = ChainNamePrefix + "tw-"
	WorkloadFromEndpointPfx = ChainNamePrefix + "fw-"

	HostToEndpointPfx   = ChainNamePrefix + "th-"
	HostFromEndpointPfx = ChainNamePrefix + "fh-"

	RuleHashPrefix = "cali:"

	// HistoricNATRuleInsertRegex is a regex pattern to match to match
	// special-case rules inserted by old versions of felix.  Specifically,
	// Python felix used to insert a masquerade rule directly into the
	// POSTROUTING chain.
	//
	// Note: this regex depends on the output format of iptables-save so,
	// where possible, it's best to match only on part of the rule that
	// we're sure can't change (such as the ipset name in the masquerade
	// rule).
	HistoricInsertedNATRuleRegex = `-A POSTROUTING .* felix-masq-ipam-pools .*|` +
		`-A POSTROUTING -o tunl0 -m addrtype ! --src-type LOCAL --limit-iface-out -m addrtype --src-type LOCAL -j MASQUERADE`
)

var (
	// AllHistoricChainNamePrefixes lists all the prefixes that we've used for chains.  Keeping
	// track of the old names lets us clean them up.
	AllHistoricChainNamePrefixes = []string{"felix-", "cali"}
	// AllHistoricIPSetNamePrefixes, similarly contains all the prefixes we've ever used for IP
	// sets.
	AllHistoricIPSetNamePrefixes = []string{"felix-", "cali"}
	// LegacyV4IPSetNames contains some extra IP set names that were used in older versions of
	// Felix and don't fit our versioned pattern.
	LegacyV4IPSetNames = []string{"felix-masq-ipam-pools", "felix-all-ipam-pools"}
)

type RuleRenderer interface {
	StaticFilterTableChains(ipVersion uint8) []*iptables.Chain
	StaticNATTableChains(ipVersion uint8) []*iptables.Chain

	WorkloadDispatchChains(map[proto.WorkloadEndpointID]*proto.WorkloadEndpoint) []*iptables.Chain
	WorkloadEndpointToIptablesChains(epID *proto.WorkloadEndpointID, endpoint *proto.WorkloadEndpoint) []*iptables.Chain

	HostDispatchChains(map[string]proto.HostEndpointID) []*iptables.Chain
	HostEndpointToIptablesChains(ifaceName string, endpoint *proto.HostEndpoint) []*iptables.Chain

	PolicyToIptablesChains(policyID *proto.PolicyID, policy *proto.Policy, ipVersion uint8) []*iptables.Chain
	ProfileToIptablesChains(profileID *proto.ProfileID, policy *proto.Profile, ipVersion uint8) []*iptables.Chain
	ProtoRuleToIptablesRules(pRule *proto.Rule, ipVersion uint8) []iptables.Rule

	NATOutgoingChain(active bool, ipVersion uint8) *iptables.Chain
}

type DefaultRuleRenderer struct {
	Config

	dropActions        []iptables.Action
	inputAcceptActions []iptables.Action
}

func (r *DefaultRuleRenderer) ipSetConfig(ipVersion uint8) *ipsets.IPVersionConfig {
	if ipVersion == 4 {
		return r.IPSetConfigV4
	} else if ipVersion == 6 {
		return r.IPSetConfigV6
	} else {
		log.WithField("version", ipVersion).Panic("Unknown IP version")
		return nil
	}
}

type Config struct {
	IPSetConfigV4 *ipsets.IPVersionConfig
	IPSetConfigV6 *ipsets.IPVersionConfig

	WorkloadIfacePrefixes []string

	IptablesMarkAccept   uint32
	IptablesMarkNextTier uint32

	OpenStackMetadataIP          net.IP
	OpenStackMetadataPort        uint16
	OpenStackSpecialCasesEnabled bool

	IPIPEnabled       bool
	IPIPTunnelAddress net.IP

	DropLogPrefix        string
	ActionOnDrop         string
	EndpointToHostAction string

	FailsafeInboundHostPorts  []uint16
	FailsafeOutboundHostPorts []uint16
}

func NewRenderer(config Config) RuleRenderer {
	log.WithField("config", config).Info("Creating rule renderer.")
	// Convert configured actions to rule slices.  First, what should we actually do when we'd
	// normally drop a packet?  For sandbox mode, we support allowing the packet instead, or
	// logging it.
	var dropActions []iptables.Action
	if strings.HasPrefix(config.ActionOnDrop, "LOG-") {
		log.Warn("Action on drop includes LOG.  All dropped packets will be logged.")
		logPrefix := "calico-drop"
		if config.DropLogPrefix != "" {
			logPrefix = config.DropLogPrefix
		}
		dropActions = append(dropActions, iptables.LogAction{Prefix: logPrefix})
	}
	if strings.HasSuffix(config.ActionOnDrop, "ACCEPT") {
		log.Warn("Action on drop set to ACCEPT.  Calico security is disabled!")
		dropActions = append(dropActions, iptables.AcceptAction{})
	} else {
		dropActions = append(dropActions, iptables.DropAction{})
	}

	// Second, what should we do with packets that come from workloads to the host itself.
	var inputAcceptActions []iptables.Action
	switch config.EndpointToHostAction {
	case "DROP":
		log.Info("Workload to host packets will be dropped.")
		inputAcceptActions = dropActions
	case "ACCEPT":
		log.Info("Workload to host packets will be accepted.")
		inputAcceptActions = []iptables.Action{iptables.AcceptAction{}}
	default:
		log.Info("Workload to host packets will be returned to INPUT chain.")
		inputAcceptActions = []iptables.Action{iptables.ReturnAction{}}
	}

	return &DefaultRuleRenderer{
		Config:             config,
		dropActions:        dropActions,
		inputAcceptActions: inputAcceptActions,
	}
}


@@ -176,7 +176,7 @@ class PlistToDB(ResultHandler):

             assert self.analyzer_returncode == 0

-            plist_file = self.get_analyzer_result_file()
+            plist_file = self.analyzer_result_file

             try:
                 files, bugs = plist_parser.parse_plist(plist_file)

# -------------------------------------------------------------------------
#                     The CodeChecker Infrastructure
#   This file is distributed under the University of Illinois Open Source
#   License. See LICENSE.TXT for details.
# -------------------------------------------------------------------------

import ntpath
import os
import zlib
from abc import ABCMeta

import shared

from codechecker_lib import client
from codechecker_lib import plist_parser
from codechecker_lib import suppress_handler
from codechecker_lib.logger import LoggerFactory
from codechecker_lib.analyzers.result_handler_base import ResultHandler

LOG = LoggerFactory.get_new_logger('PLIST TO DB')

class PlistToDB(ResultHandler):
    """
    Result handler for processing a plist file with the
    analysis results and stores them to the database.
    """

    __metaclass__ = ABCMeta

    def __init__(self, buildaction, workspace, run_id):
        super(PlistToDB, self).__init__(buildaction, workspace)
        self.__run_id = run_id

    def __store_bugs(self, files, bugs, connection, analisys_id):
        file_ids = {}
        # Send content of file to the server if needed.
        for file_name in files:
            file_descriptor = connection.need_file_content(self.__run_id,
                                                           file_name)
            file_ids[file_name] = file_descriptor.fileId

            # Sometimes the file doesn't exist, e.g. when the input of the
            # analysis is pure plist files.
            if not os.path.isfile(file_name):
                LOG.debug(file_name + ' not found, and will not be stored.')
                continue

            if file_descriptor.needed:
                with open(file_name, 'r') as source_file:
                    file_content = source_file.read()
                compressed_file = zlib.compress(file_content,
                                                zlib.Z_BEST_COMPRESSION)
                # TODO: we may not use the file content in the end
                # depending on skippaths.
                LOG.debug('storing file content to the database')
                connection.add_file_content(file_descriptor.fileId,
                                            compressed_file)

        # Skipping bugs in header files handled here.
        report_ids = []
        for bug in bugs:
            events = bug.events()

            # Skip list handler can be None if no config file is set.
            if self.skiplist_handler:
                if events and self.skiplist_handler.should_skip(
                        events[-1].start_pos.file_path):
                    # Issue #20: this bug is in a file which should be skipped
                    LOG.debug(bug.hash_value + ' is skipped (in ' +
                              events[-1].start_pos.file_path + ")")
                    continue

            # Create remaining data for bugs and send them to the server.
            bug_paths = []
            for path in bug.paths():
                bug_paths.append(
                    shared.ttypes.BugPathPos(path.start_pos.line,
                                             path.start_pos.col,
                                             path.end_pos.line,
                                             path.end_pos.col,
                                             file_ids[
                                                 path.start_pos.file_path]))

            bug_events = []
            for event in bug.events():
                bug_events.append(shared.ttypes.BugPathEvent(
                    event.start_pos.line,
                    event.start_pos.col,
                    event.end_pos.line,
                    event.end_pos.col,
                    event.msg,
                    file_ids[event.start_pos.file_path]))

            bug_hash = bug.hash_value

            severity_name = self.severity_map.get(bug.checker_name,
                                                  'UNSPECIFIED')
            severity = shared.ttypes.Severity._NAMES_TO_VALUES[severity_name]

            sp_handler = suppress_handler.SourceSuppressHandler(bug)

            # Check for suppress comment.
            supp = sp_handler.get_suppressed()
            if supp:
                connection.add_suppress_bug(self.__run_id, [supp])

            LOG.debug('Storing check results to the database.')

            report_id = connection.add_report(analisys_id,
                                              file_ids[bug.file_path],
                                              bug_hash,
                                              bug.msg,
                                              bug_paths,
                                              bug_events,
                                              bug.checker_name,
                                              bug.category,
                                              bug.type,
                                              severity,
                                              supp is not None)

            report_ids.append(report_id)

    def handle_plist(self, plist):
        with client.get_connection() as connection:
            # TODO: When the analyzer name can be read from PList, then it
            # should be passed too.
            # TODO: File name should be read from the PList and passed.
            analysis_id = connection. \
                add_build_action(self.__run_id,
                                 plist,
                                 'Build action from plist',
                                 '',
                                 '')

            try:
                files, bugs = plist_parser.parse_plist(plist)
            except Exception as ex:
                msg = 'Parsing the generated result file failed.'
                LOG.error(msg + ' ' + plist)
                LOG.error(str(ex))
                connection.finish_build_action(analysis_id, msg)
                return 1

            self.__store_bugs(files, bugs, connection, analysis_id)

            connection.finish_build_action(analysis_id, self.analyzer_stderr)

    def handle_results(self):
        """
        Send the plist content to the database.
        Server API calls should be used in one connection.
         - addBuildAction
         - addReport
         - needFileContent
         - addFileContent
         - finishBuildAction
        """

        with client.get_connection() as connection:

            LOG.debug('Storing original build and analyzer command '
                      'to the database.')

            _, source_file_name = ntpath.split(self.analyzed_source_file)

            analysis_id = \
                connection.add_build_action(self.__run_id,
                                            self.buildaction.original_command,
                                            ' '.join(
                                                self.analyzer_cmd),
                                            self.buildaction.analyzer_type,
                                            source_file_name)

            # Store buildaction and analyzer command to the database.

            assert self.analyzer_returncode == 0

            plist_file = self.get_analyzer_result_file()

            try:
                files, bugs = plist_parser.parse_plist(plist_file)
            except Exception as ex:
                LOG.debug(str(ex))
                msg = 'Parsing the generated result file failed.'
                LOG.error(msg + ' ' + plist_file)
                connection.finish_build_action(analysis_id, msg)
                return 1

            self.__store_bugs(files, bugs, connection, analysis_id)

            connection.finish_build_action(analysis_id, self.analyzer_stderr)


@@ -54,25 +54,30 @@ class PlistToHtmlTest(unittest.TestCase):
                         plist_file.truncate()
                         plist_file.write(new_content)

-    def __test_html_builder(self, proj: str):
+    def __test_html_builder(self, proj: str) -> str:
         """
         Test building html file from the given proj's plist file.
         """
-        proj_dir = os.path.join(self.test_workspace, 'test_files', proj)
-        plist_file = os.path.join(proj_dir, f"{proj}.plist")
-
-        reports = report_file.get_reports(plist_file)
+        html_builder = report_to_html.HtmlBuilder(self.layout_dir)

+        proj_dir = os.path.join(self.test_workspace, 'test_files', proj)
         output_dir = os.path.join(proj_dir, 'html')
         if not os.path.exists(output_dir):
             os.mkdir(output_dir)

-        output_path = os.path.join(output_dir, f"{proj}.plist.html")
+        processed_path_hashes = set()
+        for file_path in glob.glob(os.path.join(proj_dir, f"*.plist")):
+            file_name = os.path.basename(file_path)
+            output_path = os.path.join(output_dir, f"{file_name}.html")

-        html_builder = report_to_html.HtmlBuilder(self.layout_dir)
-        report_to_html.convert(plist_file, reports, output_dir, html_builder)
+            reports = report_file.get_reports(file_path)
+            reports = reports_helper.skip(
+                reports, processed_path_hashes)
+
+            report_to_html.convert(
+                file_path, reports, output_dir, html_builder)

-        self.assertTrue(os.path.exists(output_path))
+            self.assertTrue(os.path.exists(output_path))

         html_builder.create_index_html(output_dir)
         html_builder.create_statistics_html(output_dir)

# -------------------------------------------------------------------------
#
#  Part of the CodeChecker project, under the Apache License v2.0 with
#  LLVM Exceptions. See LICENSE for license information.
#  SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# -------------------------------------------------------------------------

import os
import shutil
import unittest

from typing import ClassVar

from libtest import env

from codechecker_report_converter.report.output.html import \
    html as report_to_html
from codechecker_report_converter.report import report_file

def get_project_path(test_project) -> str:
    """ Return project path for the given project. """
    return os.path.join(env.test_proj_root(), test_project)

class PlistToHtmlTest(unittest.TestCase):
    test_workspace: ClassVar[str]
    layout_dir: ClassVar[str]

    @classmethod
    def setUpClass(self):
        """ Initialize test files. """
        self.test_workspace = os.environ['TEST_WORKSPACE']
        self.layout_dir = os.environ['LAYOUT_DIR']

        test_file_dir_path = os.path.join(self.test_workspace, "test_files")

        test_projects = ['notes', 'macros', 'simple']
        for test_project in test_projects:
            test_project_path = os.path.join(test_file_dir_path, test_project)
            shutil.copytree(get_project_path(test_project), test_project_path)

            for test_file in os.listdir(test_project_path):
                if test_file.endswith(".plist"):
                    test_file_path = os.path.join(test_project_path, test_file)
                    with open(test_file_path, 'r+',
                              encoding='utf-8', errors='ignore') as plist_file:
                        content = plist_file.read()
                        new_content = content.replace("$FILE_PATH$",
                                                      test_project_path)
                        plist_file.seek(0)
                        plist_file.truncate()
                        plist_file.write(new_content)

    def __test_html_builder(self, proj: str):
        """
        Test building html file from the given proj's plist file.
        """
        proj_dir = os.path.join(self.test_workspace, 'test_files', proj)
        plist_file = os.path.join(proj_dir, f"{proj}.plist")

        reports = report_file.get_reports(plist_file)

        output_dir = os.path.join(proj_dir, 'html')
        if not os.path.exists(output_dir):
            os.mkdir(output_dir)

        output_path = os.path.join(output_dir, f"{proj}.plist.html")

        html_builder = report_to_html.HtmlBuilder(self.layout_dir)
        report_to_html.convert(plist_file, reports, output_dir, html_builder)

        self.assertTrue(os.path.exists(output_path))

        html_builder.create_index_html(output_dir)
        html_builder.create_statistics_html(output_dir)

        index_html = os.path.join(output_dir, 'index.html')
        self.assertTrue(os.path.exists(index_html))

    def test_get_report_data_notes(self):
        """ Get report data for plist which contains notes. """
        proj_notes = os.path.join(self.test_workspace, 'test_files', 'notes')
        plist_file = os.path.join(proj_notes, 'notes.plist')

        reports = report_file.get_reports(plist_file)

        html_builder = report_to_html.HtmlBuilder(self.layout_dir)
        html_builder._add_html_reports(reports)

        self.assertEqual(len(html_builder.files), 1)

        html_reports = html_builder.html_reports
        self.assertEqual(len(html_reports), 1)

        report = html_reports[0]
        self.assertEqual(len(report['notes']), 1)
        self.assertEqual(len(report['macros']), 0)
        self.assertGreaterEqual(len(report['events']), 1)
        self.assertEqual(report['checkerName'], 'alpha.clone.CloneChecker')

    def test_get_report_data_macros(self):
        """ Get report data for plist which contains macro expansion. """
        proj_macros = os.path.join(self.test_workspace, 'test_files', 'macros')
        plist_file = os.path.join(proj_macros, 'macros.plist')

        reports = report_file.get_reports(plist_file)

        html_builder = report_to_html.HtmlBuilder(self.layout_dir)
        html_builder._add_html_reports(reports)

        self.assertEqual(len(html_builder.files), 1)

        html_reports = html_builder.html_reports
        self.assertEqual(len(html_reports), 1)

        report = html_reports[0]
        self.assertEqual(len(reports), 1)

        report = html_reports[0]
        self.assertEqual(len(report['notes']), 0)
        self.assertEqual(len(report['macros']), 1)
        self.assertGreaterEqual(len(report['events']), 1)
        self.assertEqual(report['checkerName'], 'core.NullDereference')

    def test_get_report_data_simple(self):
        """ Get report data for plist which contains simple reports. """
        proj_simple = os.path.join(self.test_workspace, 'test_files', 'simple')
        plist_file = os.path.join(proj_simple, 'simple.plist')

        reports = report_file.get_reports(plist_file)

        html_builder = report_to_html.HtmlBuilder(self.layout_dir)
        html_builder._add_html_reports(reports)

        self.assertEqual(len(html_builder.files), 1)

        html_reports = html_builder.html_reports
        self.assertEqual(len(html_reports), 2)

        dead_stores = [r for r in html_reports if
                       r['checkerName'] == 'deadcode.DeadStores'][0]
        self.assertEqual(len(dead_stores['notes']), 0)
        self.assertEqual(len(dead_stores['macros']), 0)
        self.assertGreaterEqual(len(dead_stores['events']), 1)

        divide_zero = [r for r in html_reports if
                       r['checkerName'] == 'core.DivideZero'][0]
        self.assertEqual(len(divide_zero['notes']), 0)
        self.assertEqual(len(divide_zero['macros']), 0)
        self.assertGreaterEqual(len(divide_zero['events']), 1)

    def test_html_builder(self):
        """ Test building html files from plist files on multiple projects. """
        self.__test_html_builder('notes')
        self.__test_html_builder('macros')
        self.__test_html_builder('simple')


@@ -31,6 +31,7 @@ type Set interface {
 	Iter(func(item interface{}) error)
 	Copy() Set
 	Equals(Set) bool
+	ContainsAll(Set) bool
 }

 type empty struct{}

// Copyright (c) 2016-2017 Tigera, Inc. All rights reserved.
//
// 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 set

import (
	"errors"
	"reflect"

	log "github.com/Sirupsen/logrus"
)

type Set interface {
	Len() int
	Add(interface{})
	AddAll(itemArray interface{})
	Discard(interface{})
	Clear()
	Contains(interface{}) bool
	Iter(func(item interface{}) error)
	Copy() Set
	Equals(Set) bool
}

type empty struct{}

var emptyValue = empty{}

var (
	StopIteration = errors.New("Stop iteration")
	RemoveItem    = errors.New("Remove item")
)

func New() Set {
	return make(mapSet)
}

func From(members ...interface{}) Set {
	s := New()
	s.AddAll(members)
	return s
}

func FromArray(membersArray interface{}) Set {
	s := New()
	s.AddAll(membersArray)
	return s
}

func Empty() Set {
	return mapSet(nil)
}

type mapSet map[interface{}]empty

func (set mapSet) Len() int {
	return len(set)
}

func (set mapSet) Add(item interface{}) {
	set[item] = emptyValue
}

func (set mapSet) AddAll(itemArray interface{}) {

	arrVal := reflect.ValueOf(itemArray)
	for i := 0; i < arrVal.Len(); i++ {
		set.Add(arrVal.Index(i).Interface())
	}
}

func (set mapSet) Discard(item interface{}) {
	delete(set, item)
}

func (set mapSet) Clear() {
	for item := range set {
		delete(set, item)
	}
}

func (set mapSet) Contains(item interface{}) bool {
	_, present := set[item]
	return present
}

func (set mapSet) Iter(visitor func(item interface{}) error) {
loop:
	for item := range set {
		err := visitor(item)
		switch err {
		case StopIteration:
			break loop
		case RemoveItem:
			delete(set, item)
		case nil:
			break
		default:
			log.WithError(err).Panic("Unexpected iteration error")
		}
	}
}

func (set mapSet) Copy() Set {
	cpy := New()
	for item := range set {
		cpy.Add(item)
	}
	return cpy
}

func (set mapSet) Equals(other Set) bool {
	if set.Len() != other.Len() {
		return false
	}
	for item := range set {
		if !other.Contains(item) {
			return false
		}
	}
	return true
}


@@ -14,7 +14,7 @@ from thrift.protocol import TJSONProtocol
 from thrift.protocol.TProtocol import TProtocolException

 import shared
-from Authentication import codeCheckerAuthentication
+from Authentication_v6 import codeCheckerAuthentication

 from libcodechecker import session_manager

# -------------------------------------------------------------------------
#                     The CodeChecker Infrastructure
#   This file is distributed under the University of Illinois Open Source
#   License. See LICENSE.TXT for details.
# -------------------------------------------------------------------------

import os
import sys
# import datetime
import socket

from thrift.transport import THttpClient
from thrift.protocol import TJSONProtocol
from thrift.protocol.TProtocol import TProtocolException

import shared
from Authentication import codeCheckerAuthentication

from libcodechecker import session_manager

class ThriftAuthHelper():
    def __init__(self, host, port, uri, session_token=None):
        self.__host = host
        self.__port = port
        self.transport = THttpClient.THttpClient(self.__host, self.__port, uri)
        self.protocol = TJSONProtocol.TJSONProtocol(self.transport)
        self.client = codeCheckerAuthentication.Client(self.protocol)

        if session_token:
            headers = {'Cookie': session_manager.SESSION_COOKIE_NAME +
                       "=" + session_token}
            self.transport.setCustomHeaders(headers)

            # ------------------------------------------------------------

    def ThriftClientCall(function):
        # print type(function)
        funcName = function.__name__

        def wrapper(self, *args, **kwargs):
            # print('['+host+':'+str(port)+'] >>>>> ['+funcName+']')
            # before = datetime.datetime.now()
            self.transport.open()
            func = getattr(self.client, funcName)
            try:
                res = func(*args, **kwargs)

            except shared.ttypes.RequestFailed as reqfailure:
                if reqfailure.errorCode == shared.ttypes.ErrorCode.DATABASE:
                    print('Database error on server')
                    print(str(reqfailure.message))
                elif reqfailure.errorCode ==\
                        shared.ttypes.ErrorCode.AUTH_DENIED:
                    print('Authentication denied.')
                    raise reqfailure
                elif reqfailure.errorCode ==\
                        shared.ttypes.ErrorCode.UNAUTHORIZED:
                    print('Unauthorised.')
                    raise reqfailure
                else:
                    print('Other error')
                    print(str(reqfailure))

                sys.exit(1)
            except TProtocolException as ex:
                print("Connection failed to {0}:{1}"
                      .format(self.__host, self.__port))
                sys.exit(1)
            except socket.error as serr:
                errCause = os.strerror(serr.errno)
                print(errCause)
                print(str(serr))
                sys.exit(1)

            # after = datetime.datetime.now()
            # timediff = after - before
            # diff = timediff.microseconds/1000
            # print('['+str(diff)+'ms] <<<<< ['+host+':'+str(port)+']')
            # print res
            self.transport.close()
            return res

        return wrapper

    # ============= Authentication and session handling =============
    @ThriftClientCall
    def getAuthParameters(self):
        pass

    @ThriftClientCall
    def getAcceptedAuthMethods(self):
        pass

    @ThriftClientCall
    def performLogin(self, auth_method, auth_string):
        pass

    @ThriftClientCall
    def destroySession(self):
        pass

    # ============= Authorization, permission management =============
    @ThriftClientCall
    def getPermissions(self, scope):
        pass

    @ThriftClientCall
    def getPermissionsForUser(self, scope, extra_params, filter):
        pass

    @ThriftClientCall
    def getAuthorisedNames(self, permission, extra_params):
        pass

    @ThriftClientCall
    def addPermission(self, permission, auth_name, is_group, extra_params):
        pass

    @ThriftClientCall
    def removePermission(self, permission, auth_name, is_group, extra_params):
        pass

    @ThriftClientCall
    def hasPermission(self, permission, extra_params):
        pass


/* **********************************************************
 * Copyright (c) 2010-2019 Google, Inc.  All rights reserved.
 * Copyright (c) 2003-2010 VMware, Inc.  All rights reserved.
 * **********************************************************/

/*
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * * Neither the name of VMware, Inc. nor the names of its contributors may be
 *   used to endorse or promote products derived from this software without
 *   specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 */

/* Copyright (c) 2003-2007 Determina Corp. */

/*
 * ntdll_shared.c
 * Routines for calling Windows system calls via the ntdll.dll wrappers,
 * meant for sharing beyond the core DR library.
 * Xref i#1409 on splitting files up and eliminating the NOT_DYNAMORIO_CORE
 * ifdefs that today select portions of files.
 */
#include "configure.h"
#ifdef NOT_DYNAMORIO_CORE
#    include "globals_shared.h"
#    define ASSERT(x)
#    define ASSERT_CURIOSITY(x)
#    define ASSERT_NOT_REACHED()
#    define ASSERT_NOT_IMPLEMENTED(x)
#    define DODEBUG(x)
#    define DOCHECK(n, x)
#    define DEBUG_DECLARE(x)
#    pragma warning(disable : 4210) // nonstd extension: function given file scope
#    pragma warning(disable : 4204) // nonstd extension: non-constant aggregate
                                    // initializer
#    define INVALID_FILE INVALID_HANDLE_VALUE
#    define STATUS_NOT_IMPLEMENTED ((NTSTATUS)0xC0000002L)
#else
/* we include globals.h mainly for ASSERT, even though we're
 * used by preinject.
 * preinject just defines its own d_r_internal_error!
 */
#    include "../globals.h"
#    include "../module_shared.h"
#endif

/* We have to hack away things we use here that won't work for non-core */
#if defined(NOT_DYNAMORIO_CORE_PROPER) || defined(NOT_DYNAMORIO_CORE)
#    undef ASSERT_OWN_NO_LOCKS
#    define ASSERT_OWN_NO_LOCKS() /* who cares if not the core */
#endif

#include "ntdll_shared.h"

#ifndef X64
NTSTATUS
nt_wow64_read_virtual_memory64(HANDLE process, uint64 base, void *buffer,
                               size_t buffer_length, size_t *bytes_read)
{
    /* This syscall was added in 2003 so we can't statically link. */
    typedef NTSTATUS(NTAPI * NtWow64ReadVirtualMemory64_t)(
        HANDLE ProcessHandle, IN PVOID64 BaseAddress, OUT PVOID Buffer,
        IN ULONGLONG BufferSize, OUT PULONGLONG NumberOfBytesRead);
    static NtWow64ReadVirtualMemory64_t ntcall;
    NTSTATUS res;
    if (ntcall == NULL) {
#    if !defined(NOT_DYNAMORIO_CORE) && !defined(NOT_DYNAMORIO_CORE_PROPER)
        /* The first call may not be during init so we have to unprot */
        if (dynamo_initialized)
            SELF_UNPROTECT_DATASEC(DATASEC_RARELY_PROT);
#    endif
        ntcall = (NtWow64ReadVirtualMemory64_t)
#    ifdef NOT_DYNAMORIO_CORE
            GetProcAddress(GetModuleHandle("ntdll.dll"), "NtWow64ReadVirtualMemory64");
#    else
            d_r_get_proc_address(get_ntdll_base(), "NtWow64ReadVirtualMemory64");
#    endif
#    if !defined(NOT_DYNAMORIO_CORE) && !defined(NOT_DYNAMORIO_CORE_PROPER)
        if (dynamo_initialized)
            SELF_PROTECT_DATASEC(DATASEC_RARELY_PROT);
#    endif
    }
    if (ntcall == NULL) {
        /* We do not need to fall back to NtReadVirtualMemory, b/c
         * NtWow64ReadVirtualMemory64 was added in xp64==2003 and so should
         * always exist if we are in a WOW64 process: and we should only be
         * called from a WOW64 process.
         */
        ASSERT_NOT_REACHED();
        res = STATUS_NOT_IMPLEMENTED;
    } else {
        uint64 len;
        res = ntcall(process, (PVOID64)base, buffer, (ULONGLONG)buffer_length, &len);
        if (bytes_read != NULL)
            *bytes_read = (size_t)len;
    }
    return res;
}
#endif


@@ -126,7 +126,7 @@ class AnalyzerConfigHandler(object):
             else:
                 # Turn default checkers on.
                 for checker in checker_config['default']:
-                    self.set_checker_enabled(checker, True)
+                    self.set_checker_enabled(checker)

         # If enable_all is given, almost all checkers should be enabled.
         if enable_all:

# -------------------------------------------------------------------------
#                     The CodeChecker Infrastructure
#   This file is distributed under the University of Illinois Open Source
#   License. See LICENSE.TXT for details.
# -------------------------------------------------------------------------
"""
Static analyzer configuration handler.
"""

from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

from abc import ABCMeta
import collections
import os
import platform
import sys

from codechecker_common.logger import get_logger

LOG = get_logger('system')

class AnalyzerConfigHandler(object):
    """
    Handle the checker configurations and enabled disabled checkers lists.
    """
    __metaclass__ = ABCMeta

    def __init__(self):

        self.analyzer_binary = None
        self.analyzer_plugins_dir = None
        self.compiler_resource_dir = ''
        self.analyzer_extra_arguments = []
        self.checker_config = ''
        self.report_hash = None

        # The key is the checker name, the value is a tuple.
        # False if disabled (should be by default).
        # True if checker is enabled.
        # (False/True, 'checker_description')
        self.__available_checkers = collections.OrderedDict()

    @property
    def analyzer_plugins(self):
        """
        Full path of the analyzer plugins.
        """
        plugin_dir = self.analyzer_plugins_dir
        if not plugin_dir or not os.path.exists(plugin_dir):
            return []

        analyzer_plugins = [os.path.join(plugin_dir, f)
                            for f in os.listdir(plugin_dir)
                            if os.path.isfile(os.path.join(plugin_dir, f))
                            and f.endswith(".so")]
        return analyzer_plugins

    def add_checker(self, checker_name, enabled, description):
        """
        Add additional checker.
        Tuple of (checker_name, True or False).
        """
        self.__available_checkers[checker_name] = (enabled, description)

    def set_checker_enabled(self, checker_name, enabled=True):
        """
        Enable checker, keep description if already set.
        """
        for ch_name, values in self.__available_checkers.items():
            if ch_name.startswith(checker_name) or \
               ch_name.endswith(checker_name):
                _, description = values
                self.__available_checkers[ch_name] = (enabled, description)

    def checks(self):
        """
        Return the checkers.
        """
        return self.__available_checkers

    def __gen_name_variations(self):
        """
        Generate all applicable name variations from the given checker list.
        """
        checker_names = (name for name in self.__available_checkers)
        reserved_names = []

        for name in checker_names:
            delim = '.' if '.' in name else '-'
            parts = name.split(delim)
            # Creates a list of variations from a checker name, e.g.
            # ['security', 'security.insecureAPI', 'security.insecureAPI.gets']
            # from 'security.insecureAPI.gets' or
            # ['misc', 'misc-dangling', 'misc-dangling-handle']
            # from 'misc-dangling-handle'.
            v = [delim.join(parts[:(i + 1)]) for i in range(len(parts))]
            reserved_names += v

        return reserved_names

    def initialize_checkers(self,
                            available_profiles,
                            package_root,
                            checkers,
                            checker_config=None,
                            cmdline_checkers=None,
                            enable_all=False):
        """
        Initializes the checker list for the specified config handler based on
        given checker profiles, commandline arguments and the
        analyzer-retrieved checker list.
        """

        # By default disable all checkers.
        for checker_name, description in checkers:
            self.add_checker(checker_name, False, description)

        # Set default enabled or disabled checkers, based on the config file.
        if checker_config:
            # Check whether a default profile exists.
            if 'default' not in checker_config:
                LOG.warning("No default profile found!")
            else:
                # Turn default checkers on.
                for checker in checker_config['default']:
                    self.set_checker_enabled(checker, True)

        # If enable_all is given, almost all checkers should be enabled.
        if enable_all:
            for checker_name, enabled in checkers:
                if not checker_name.startswith("alpha.") and \
                        not checker_name.startswith("debug.") and \
                        not checker_name.startswith("osx."):
                    # There are a few exceptions, though, which still need to
                    # be manually enabled by the user: alpha and debug.
                    self.set_checker_enabled(checker_name)

                if checker_name.startswith("osx.") and \
                        platform.system() == 'Darwin':
                    # OSX checkers are only enable-all'd if we are on OSX.
                    self.set_checker_enabled(checker_name)

        # Set user defined enabled or disabled checkers from the command line.
        if cmdline_checkers:

            # Construct a list of reserved checker names.
            # (It is used to check if a profile name is valid.)
            reserved_names = self.__gen_name_variations()

            for identifier, enabled in cmdline_checkers:

                # The identifier is a profile name.
                if identifier in available_profiles:
                    profile_name = identifier

                    if profile_name == "list":
                        LOG.error("'list' is a reserved profile keyword. ")
                        LOG.error("Please choose another profile name in "
                                  "'%s'/config/config.json and rebuild.",
                                  package_root)
                        sys.exit(1)

                    if profile_name in reserved_names:
                        LOG.warning("Profile name '%s' conflicts with a "
                                    "checker(-group) name.", profile_name)

                    # Enable or disable all checkers belonging to the profile.
                    for checker in checker_config[profile_name]:
                        self.set_checker_enabled(checker, enabled)

                # The identifier is a checker(-group) name.
                else:
                    checker_name = identifier
                    self.set_checker_enabled(checker_name, enabled)


@@ -24,7 +24,7 @@ class ClangSAConfigHandler(config_handler.AnalyzerConfigHandler):
     Configuration handler for the clang static analyzer.
     """

-    def __init__(self, environ):
+    def __init__(self, environ, analyzer_binary):
         super(ClangSAConfigHandler, self).__init__()
         self.ctu_dir = ''
         self.ctu_on_demand = False

# -------------------------------------------------------------------------
#
#  Part of the CodeChecker project, under the Apache License v2.0 with
#  LLVM Exceptions. See LICENSE for license information.
#  SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# -------------------------------------------------------------------------
"""
Clang Static analyzer configuration handler.
"""
import os

from codechecker_analyzer import env
from codechecker_common.logger import get_logger
from .ctu_autodetection import CTUAutodetection

from .. import config_handler

LOG = get_logger('analyzer.clangsa')

class ClangSAConfigHandler(config_handler.AnalyzerConfigHandler):
    """
    Configuration handler for the clang static analyzer.
    """

    def __init__(self, environ):
        super(ClangSAConfigHandler, self).__init__()
        self.ctu_dir = ''
        self.ctu_on_demand = False
        self.log_file = ''
        self.path_env_extra = ''
        self.ld_lib_path_extra = ''
        self.enable_z3 = False
        self.enable_z3_refutation = False
        self.environ = environ
        self.version_info = None

    @property
    def analyzer_plugins(self):
        """ Full path of the analyzer plugins. """
        plugin_dir = self.analyzer_plugins_dir

        clangsa_plugin_dir = env.get_clangsa_plugin_dir()
        is_analyzer_from_path = env.is_analyzer_from_path()
        if is_analyzer_from_path:
            if not clangsa_plugin_dir:
                return []

            # If the CC_ANALYZERS_FROM_PATH and CC_CLANGSA_PLUGIN_DIR
            # environment variables are set we will use this value as the
            # plugin directory.
            plugin_dir = clangsa_plugin_dir

        if not plugin_dir or not os.path.exists(plugin_dir):
            return []

        return [os.path.join(plugin_dir, f)
                for f in os.listdir(plugin_dir)
                if os.path.isfile(os.path.join(plugin_dir, f))
                and f.endswith(".so")]

    @property
    def ctu_capability(self):
        return CTUAutodetection(self.analyzer_binary, self.environ)


@@ -69,7 +69,10 @@ char *gpu_name_get()
 	}

 	char *gpu_name = get_line(pipe);
-	fclose(pipe);
+
+	string_chomp(gpu_name);
+
+	pclose(pipe);

 	return gpu_name;
 }

/*
Copyright (C) 2013- The University of Notre Dame
This software is distributed under the GNU General Public License.
See the file COPYING for details.
*/

#include "gpu_info.h"
#include "stringtools.h"
#include "get_line.h"

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

#define GPU_AUTODETECT "cctools_gpu_autodetect"

int gpu_info_get()
{
	int pipefd[2];
	pipe(pipefd);

	pid_t pid = fork();

	if(pid<0) {
		return 0;
	} else if(pid==0) {
		close(pipefd[0]);
		dup2(pipefd[1], fileno(stdout));
		char *args[] = {GPU_AUTODETECT, NULL};
		if(!access(GPU_AUTODETECT, R_OK|X_OK)){
			execv(GPU_AUTODETECT, args);
		} else {
			execvp(GPU_AUTODETECT, args);
		}
		_exit(0);
	} else {
		close(pipefd[1]);
		int status = 0;
		int gpu_count = 0;
		char buffer[10]; /* Enough characters to hold a decimal representation of a 32 bit int. */
		if(read(pipefd[0], buffer, 10)){
			waitpid(pid, &status, 0);
			gpu_count = atoi(buffer);
		}

		close(pipefd[0]);
		return gpu_count;
	}
}

char *gpu_name_get()
{
	char *nvidia_cmd = "/bin/nvidia-smi";

	if(access(nvidia_cmd, X_OK) != 0) {
		return NULL;
	}

	FILE *pipe = popen("/bin/nvidia-smi --query-gpu=gpu_name --format=csv,noheader", "r");
	if(!pipe) {
		return NULL;
	}

	char *gpu_name = get_line(pipe);
	fclose(pipe);

	return gpu_name;
}

/* vim: set noexpandtab tabstop=4: */


@@ -1,5 +1,4 @@
 using System;
-using System.Reflection;
 using System.Threading;
 using System.Threading.Tasks;
 using Datadog.Trace.ClrProfiler.Emit;

using System;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Datadog.Trace.ClrProfiler.Emit;
using Datadog.Trace.ClrProfiler.Helpers;
using Datadog.Trace.Logging;

namespace Datadog.Trace.ClrProfiler.Integrations
{
    /// <summary>
    /// Traces an Elasticsearch pipeline
    /// </summary>
    public static class ElasticsearchNet5Integration
    {
        private const string IntegrationName = "ElasticsearchNet5";
        private const string Version5 = "5";
        private const string ElasticsearchAssembly = "Elasticsearch.Net";
        private const string RequestPipelineInterface = "Elasticsearch.Net.IRequestPipeline";

        private static readonly ILog Log = LogProvider.GetLogger(typeof(ElasticsearchNet5Integration));
        private static readonly Type ElasticsearchResponseType = Type.GetType("Elasticsearch.Net.ElasticsearchResponse`1, Elasticsearch.Net", throwOnError: false);

        /// <summary>
        /// Traces a synchronous call to Elasticsearch.
        /// </summary>
        /// <typeparam name="TResponse">The type of the response</typeparam>
        /// <param name="pipeline">The pipeline for the original method</param>
        /// <param name="requestData">The request data</param>
        /// <param name="opCode">The OpCode used in the original method call.</param>
        /// <param name="mdToken">The mdToken of the original method call.</param>
        /// <param name="moduleVersionPtr">A pointer to the module version GUID.</param>
        /// <returns>The original result</returns>
        [InterceptMethod(
            CallerAssembly = ElasticsearchAssembly,
            TargetAssembly = ElasticsearchAssembly,
            TargetType = RequestPipelineInterface,
            TargetSignatureTypes = new[] { "Elasticsearch.Net.ElasticsearchResponse`1<T>", "Elasticsearch.Net.RequestData" },
            TargetMinimumVersion = Version5,
            TargetMaximumVersion = Version5)]
        public static object CallElasticsearch<TResponse>(
            object pipeline,
            object requestData,
            int opCode,
            int mdToken,
            long moduleVersionPtr)
        {
            const string methodName = nameof(CallElasticsearch);
            Func<object, object, object> callElasticSearch;
            var pipelineType = pipeline.GetType();
            var genericArgument = typeof(TResponse);

            try
            {
                callElasticSearch =
                    MethodBuilder<Func<object, object, object>>
                       .Start(moduleVersionPtr, mdToken, opCode, methodName)
                       .WithConcreteType(pipelineType)
                       .WithMethodGenerics(genericArgument)
                       .WithParameters(requestData)
                       .Build();
            }
            catch (Exception ex)
            {
                // profiled app will not continue working as expected without this method
                Log.ErrorException($"Error retrieving {pipelineType.Name}.{methodName}(RequestData requestData)", ex);
                throw;
            }

            using (var scope = ElasticsearchNetCommon.CreateScope(Tracer.Instance, IntegrationName, pipeline, requestData))
            {
                try
                {
                    return callElasticSearch(pipeline, requestData);
                }
                catch (Exception ex) when (scope?.Span.SetExceptionForFilter(ex) ?? false)
                {
                    // unreachable code
                    throw;
                }
            }
        }

        /// <summary>
        /// Traces an asynchronous call to Elasticsearch.
        /// </summary>
        /// <typeparam name="TResponse">Type type of the response</typeparam>
        /// <param name="pipeline">The pipeline for the original method</param>
        /// <param name="requestData">The request data</param>
        /// <param name="cancellationTokenSource">A cancellation token</param>
        /// <param name="opCode">The OpCode used in the original method call.</param>
        /// <param name="mdToken">The mdToken of the original method call.</param>
        /// <param name="moduleVersionPtr">A pointer to the module version GUID.</param>
        /// <returns>The original result</returns>
        [InterceptMethod(
            CallerAssembly = ElasticsearchAssembly,
            TargetAssembly = ElasticsearchAssembly,
            TargetType = RequestPipelineInterface,
            TargetSignatureTypes = new[] { "System.Threading.Tasks.Task`1<Elasticsearch.Net.ElasticsearchResponse`1<T>>", "Elasticsearch.Net.RequestData", ClrNames.CancellationToken },
            TargetMinimumVersion = Version5,
            TargetMaximumVersion = Version5)]
        public static object CallElasticsearchAsync<TResponse>(
            object pipeline,
            object requestData,
            object cancellationTokenSource,
            int opCode,
            int mdToken,
            long moduleVersionPtr)
        {
            var tokenSource = cancellationTokenSource as CancellationTokenSource;
            var cancellationToken = tokenSource?.Token ?? CancellationToken.None;

            var genericArgument = typeof(TResponse);
            var genericResponseType = ElasticsearchResponseType.MakeGenericType(genericArgument);

            Func<object, object, CancellationToken, object> instrumentedMethod;

            try
            {
                instrumentedMethod =
                    MethodBuilder<Func<object, object, CancellationToken, object>>
                       .Start(moduleVersionPtr, mdToken, opCode, nameof(CallElasticsearchAsync))
                       .WithConcreteType(pipeline.GetType())
                       .WithMethodGenerics(genericArgument)
                       .WithParameters(requestData, cancellationToken)
                       .ForceMethodDefinitionResolution()
                       .Build();
            }
            catch (Exception ex)
            {
                Log.ErrorException($"Error resolving Elasticsearch.Net.IRequestPipeline.{nameof(CallElasticsearchAsync)}<T>(...)", ex);
                throw;
            }

            return AsyncHelper.InvokeGenericTaskDelegate(
                owningType: ElasticsearchNetCommon.RequestPipelineType,
                taskResultType: genericResponseType,
                nameOfIntegrationMethod: nameof(CallElasticsearchAsyncInternal),
                integrationType: typeof(ElasticsearchNet5Integration),
                pipeline,
                requestData,
                cancellationToken,
                instrumentedMethod);
        }

        /// <summary>
        /// Traces an asynchronous call to Elasticsearch.
        /// </summary>
        /// <typeparam name="T">Type type of the Task</typeparam>
        /// <param name="pipeline">The pipeline for the original method</param>
        /// <param name="requestData">The request data</param>
        /// <param name="cancellationToken">A cancellation token</param>
        /// <param name="originalMethod">A delegate for the method we are instrumenting</param>
        /// <returns>The original result</returns>
        private static async Task<T> CallElasticsearchAsyncInternal<T>(
            object pipeline,
            object requestData,
            CancellationToken cancellationToken,
            Func<object, object, CancellationToken, object> originalMethod)
        {
            using (var scope = ElasticsearchNetCommon.CreateScope(Tracer.Instance, IntegrationName, pipeline, requestData))
            {
                try
                {
                    var task = (Task<T>)originalMethod(pipeline, requestData, cancellationToken);
                    return await task.ConfigureAwait(false);
                }
                catch (Exception ex) when (scope?.Span.SetExceptionForFilter(ex) ?? false)
                {
                    // unreachable code
                    throw;
                }
            }
        }
    }
}


@@ -31,13 +31,15 @@ namespace Nethermind.Blockchain.Find
         private readonly IReceiptsRecovery _receiptsRecovery;
         private readonly int _maxBlockDepth;
         private readonly IBlockFinder _blockFinder;
+        private readonly ILogger _logger;

-        public LogFinder(IBlockFinder blockFinder, IReceiptStorage receiptStorage, IBloomStorage bloomStorage, IReceiptsRecovery receiptsRecovery, int maxBlockDepth = 1000)
+        public LogFinder(IBlockFinder blockFinder, IReceiptStorage receiptStorage, IBloomStorage bloomStorage, IReceiptsRecovery receiptsRecovery, ILogManager logManager, int maxBlockDepth = 1000)
         {
             _blockFinder = blockFinder ?? throw new ArgumentNullException(nameof(blockFinder));
             _receiptStorage = receiptStorage ?? throw new ArgumentNullException(nameof(receiptStorage));
             _bloomStorage = bloomStorage ?? throw new ArgumentNullException(nameof(bloomStorage));
             _receiptsRecovery = receiptsRecovery ?? throw new ArgumentNullException(nameof(receiptsRecovery));
+            _logger = logManager?.GetClassLogger<LogFinder>() ?? throw new ArgumentNullException(nameof(logManager));
             _maxBlockDepth = maxBlockDepth;
         }

//  Copyright (c) 2018 Demerzel Solutions Limited
//  This file is part of the Nethermind library.
//
//  The Nethermind library is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  The Nethermind library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//  GNU Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public License
//  along with the Nethermind. If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.Linq;
using Nethermind.Blockchain.Filters;
using Nethermind.Blockchain.Receipts;
using Nethermind.Core;
using Nethermind.Store.Bloom;

namespace Nethermind.Blockchain.Find
{
    public class LogFinder : ILogFinder
    {
        private readonly IReceiptStorage _receiptStorage;
        private readonly IBloomStorage _bloomStorage;
        private readonly IReceiptsRecovery _receiptsRecovery;
        private readonly int _maxBlockDepth;
        private readonly IBlockFinder _blockFinder;

        public LogFinder(IBlockFinder blockFinder, IReceiptStorage receiptStorage, IBloomStorage bloomStorage, IReceiptsRecovery receiptsRecovery, int maxBlockDepth = 1000)
        {
            _blockFinder = blockFinder ?? throw new ArgumentNullException(nameof(blockFinder));
            _receiptStorage = receiptStorage ?? throw new ArgumentNullException(nameof(receiptStorage));
            _bloomStorage = bloomStorage ?? throw new ArgumentNullException(nameof(bloomStorage));
            _receiptsRecovery = receiptsRecovery ?? throw new ArgumentNullException(nameof(receiptsRecovery));
            _maxBlockDepth = maxBlockDepth;
        }

        public IEnumerable<FilterLog> FindLogs(LogFilter filter)
        {
            BlockHeader FindHeader(BlockParameter blockParameter, string name) => _blockFinder.FindHeader(blockParameter) ?? throw new ArgumentException(ILogFinder.NotFoundError, name);

            var toBlock = FindHeader(filter.ToBlock, nameof(filter.ToBlock));
            var fromBlock = FindHeader(filter.FromBlock, nameof(filter.FromBlock));

            if (fromBlock.Number > toBlock.Number && toBlock.Number != 0)
            {
                throw new ArgumentException("'From' block is later than 'to' block.");
            }

            return ShouldUseBloomDatabase(fromBlock, toBlock) && CanUseBloomDatabase(toBlock, fromBlock)
                ? FilterLogsWithBloomsIndex(filter, fromBlock, toBlock)
                : FilterLogsIteratively(filter, fromBlock, toBlock);
        }

        private bool ShouldUseBloomDatabase(BlockHeader fromBlock, BlockHeader toBlock)
        {
            var blocksToSearch = toBlock.Number - fromBlock.Number + 1;
            return blocksToSearch > 1; // if we are searching only in 1 block skip bloom index altogether, this can be tweaked
        }

        private IEnumerable<FilterLog> FilterLogsWithBloomsIndex(LogFilter filter, BlockHeader fromBlock, BlockHeader toBlock)
        {
            var enumeration = _bloomStorage.GetBlooms(fromBlock.Number, toBlock.Number);
            foreach (var bloom in enumeration)
            {
                if (filter.Matches(bloom) && enumeration.TryGetBlockNumber(out var blockNumber))
                {
                    foreach (var filterLog in FindLogsInBlock(filter, _blockFinder.FindBlock(blockNumber)))
                    {
                        yield return filterLog;
                    }
                }
            }
        }

        private bool CanUseBloomDatabase(BlockHeader toBlock, BlockHeader fromBlock) => _bloomStorage.ContainsRange(fromBlock.Number, toBlock.Number) && _blockFinder.IsMainChain(toBlock) && _blockFinder.IsMainChain(fromBlock);

        private IEnumerable<FilterLog> FilterLogsIteratively(LogFilter filter, BlockHeader fromBlock, BlockHeader toBlock)
        {
            int count = 0;

            while (count < _maxBlockDepth && toBlock.Number >= (fromBlock?.Number ?? long.MaxValue))
            {
                foreach (var filterLog in FindLogsInBlock(filter, toBlock))
                {
                    yield return filterLog;
                }

                if (!TryGetParentBlock(toBlock, out toBlock))
                {
                    break;
                }

                count++;
            }
        }

        private IEnumerable<FilterLog> FindLogsInBlock(LogFilter filter, BlockHeader block) =>
            filter.Matches(block.Bloom)
                ? FindLogsInBlock(filter, _blockFinder.FindBlock(block.Hash))
                : Enumerable.Empty<FilterLog>();

        private IEnumerable<FilterLog> FindLogsInBlock(LogFilter filter, Block block)
        {
            var receipts = _receiptStorage.FindForBlock(block, _receiptsRecovery);
            long logIndexInBlock = 0;
            foreach (var receipt in receipts)
            {
                if (receipt == null)
                {
                    continue;
                }

                if (filter.Matches(receipt.Bloom))
                {
                    for (var index = 0; index < receipt.Logs.Length; index++)
                    {
                        var log = receipt.Logs[index];
                        if (filter.Accepts(log))
                        {
                            yield return new FilterLog(logIndexInBlock, index, receipt, log);
                        }

                        logIndexInBlock++;
                    }
                }
                else
                {
                    logIndexInBlock += receipt.Logs.Length;
                }
            }
        }

        private bool TryGetParentBlock(BlockHeader currentBlock, out BlockHeader parentHeader)
        {
            if (currentBlock.IsGenesis)
            {
                parentHeader = null;
                return false;
            }

            parentHeader = _blockFinder.FindParentHeader(currentBlock, BlockTreeLookupOptions.TotalDifficultyNotNeeded);
            return true;
        }
    }
}


@@ -81,9 +81,13 @@ namespace Datadog.Trace.DuckTyping
         public static T DuckAs<T>(this object instance)
             where T : class
         {
-            if (DuckType.CanCreate<T>(instance))
+            if (instance is not null)
             {
-                return DuckType.Create<T>(instance);
+                DuckType.CreateTypeResult proxyResult = DuckType.CreateCache<T>.GetProxy(instance.GetType());
+                if (proxyResult.Success)
+                {
+                    return proxyResult.CreateInstance<T>(instance);
+                }
             }

             return null;

using System;
using System.Runtime.CompilerServices;
using Datadog.Trace.Logging;

namespace Datadog.Trace.DuckTyping
{
    /// <summary>
    /// Duck type extensions
    /// </summary>
    public static class DuckTypeExtensions
    {
        private static readonly IDatadogLogger Log = DatadogLogging.GetLoggerFor(typeof(DuckType));

        /// <summary>
        /// Gets the duck type instance for the object implementing a base class or interface T
        /// </summary>
        /// <param name="instance">Object instance</param>
        /// <typeparam name="T">Target type</typeparam>
        /// <returns>DuckType instance</returns>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static T DuckCast<T>(this object instance)
            => DuckType.Create<T>(instance);

        /// <summary>
        /// Gets the duck type instance for the object implementing a base class or interface T
        /// </summary>
        /// <param name="instance">Object instance</param>
        /// <param name="targetType">Target type</param>
        /// <returns>DuckType instance</returns>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static object DuckCast(this object instance, Type targetType)
            => DuckType.Create(targetType, instance);

        /// <summary>
        /// Tries to ducktype the object implementing a base class or interface T
        /// </summary>
        /// <typeparam name="T">Target type</typeparam>
        /// <param name="instance">Object instance</param>
        /// <param name="value">Ducktype instance</param>
        /// <returns>true if the object instance was ducktyped; otherwise, false.</returns>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static bool TryDuckCast<T>(this object instance, out T value)
        {
            if (DuckType.CanCreate<T>(instance))
            {
                value = DuckType.Create<T>(instance);
                return true;
            }

            value = default;
            return false;
        }

        /// <summary>
        /// Tries to ducktype the object implementing a base class or interface T
        /// </summary>
        /// <param name="instance">Object instance</param>
        /// <param name="targetType">Target type</param>
        /// <param name="value">Ducktype instance</param>
        /// <returns>true if the object instance was ducktyped; otherwise, false.</returns>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static bool TryDuckCast(this object instance, Type targetType, out object value)
        {
            if (DuckType.CanCreate(targetType, instance))
            {
                value = DuckType.Create(targetType, instance);
                return true;
            }

            value = default;
            return false;
        }

        /// <summary>
        /// Gets the duck type instance for the object implementing a base class or interface T
        /// </summary>
        /// <param name="instance">Object instance</param>
        /// <typeparam name="T">Target type</typeparam>
        /// <returns>DuckType instance</returns>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static T DuckAs<T>(this object instance)
            where T : class
        {
            if (DuckType.CanCreate<T>(instance))
            {
                return DuckType.Create<T>(instance);
            }

            return null;
        }

        /// <summary>
        /// Gets the duck type instance for the object implementing a base class or interface T
        /// </summary>
        /// <param name="instance">Object instance</param>
        /// <param name="targetType">Target type</param>
        /// <returns>DuckType instance</returns>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static object DuckAs(this object instance, Type targetType)
        {
            if (DuckType.CanCreate(targetType, instance))
            {
                return DuckType.Create(targetType, instance);
            }

            return null;
        }

        /// <summary>
        /// Gets if a proxy can be created
        /// </summary>
        /// <param name="instance">Instance object</param>
        /// <typeparam name="T">Duck type</typeparam>
        /// <returns>true if the proxy can be created; otherwise, false</returns>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static bool DuckIs<T>(this object instance)
            => DuckType.CanCreate<T>(instance);

        /// <summary>
        /// Gets if a proxy can be created
        /// </summary>
        /// <param name="instance">Instance object</param>
        /// <param name="targetType">Duck type</param>
        /// <returns>true if the proxy can be created; otherwise, false</returns>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static bool DuckIs(this object instance, Type targetType)
            => DuckType.CanCreate(targetType, instance);
    }
}


@@ -60,6 +60,20 @@ namespace Datadog.Trace.PlatformHelpers

         public string ResourceId { get; }

+        public AzureContext AzureContext { get; private set; } = AzureContext.AzureAppService;
+
+        public string FunctionsExtensionVersion { get; }
+
+        public string FunctionsWorkerRuntime { get; }
+
+        public string InstanceName { get; }
+
+        public string InstanceId { get; }
+
+        public string OperatingSystem { get; }
+
+        public string Runtime { get; }
+
         private string CompileResourceId()
         {
             string resourceId = null;

using System;
using System.Collections;
using Datadog.Trace.ExtensionMethods;
using Datadog.Trace.Logging;
using Datadog.Trace.Util;

namespace Datadog.Trace.PlatformHelpers
{
    internal class AzureAppServices
    {
        /// <summary>
        /// Configuration key which is used as a flag to tell us whether we are running in the context of Azure App Services.
        /// </summary>
        internal static readonly string AzureAppServicesContextKey = "DD_AZURE_APP_SERVICES";

        /// <summary>
        /// Example: 8c56d827-5f07-45ce-8f2b-6c5001db5c6f+apm-dotnet-EastUSwebspace
        /// Format: {subscriptionId}+{planResourceGroup}-{hostedInRegion}
        /// </summary>
        internal static readonly string WebsiteOwnerNameKey = "WEBSITE_OWNER_NAME";

        /// <summary>
        /// This is the name of the resource group the site instance is assigned to.
        /// </summary>
        internal static readonly string ResourceGroupKey = "WEBSITE_RESOURCE_GROUP";

        /// <summary>
        /// This is the unique name of the website instance within azure app services.
        /// </summary>
        internal static readonly string SiteNameKey = "WEBSITE_DEPLOYMENT_ID";

        private static readonly Vendors.Serilog.ILogger Log = DatadogLogging.GetLogger(typeof(AzureAppServices));

        static AzureAppServices()
        {
            Metadata = new AzureAppServices(EnvironmentHelpers.GetEnvironmentVariables());
        }

        public AzureAppServices(IDictionary environmentVariables)
        {
            IsRelevant = GetVariableIfExists(AzureAppServicesContextKey, environmentVariables)?.ToBoolean() ?? false;
            if (IsRelevant)
            {
                SubscriptionId = GetSubscriptionId(environmentVariables);
                ResourceGroup = GetVariableIfExists(ResourceGroupKey, environmentVariables);
                SiteName = GetVariableIfExists(SiteNameKey, environmentVariables);
                ResourceId = CompileResourceId();
            }
        }

        public static AzureAppServices Metadata { get; set; }

        public bool IsRelevant { get; }

        public string SubscriptionId { get; }

        public string ResourceGroup { get; }

        public string SiteName { get; }

        public string ResourceId { get; }

        private string CompileResourceId()
        {
            string resourceId = null;

            try
            {
                var success = true;
                if (SubscriptionId == null)
                {
                    success = false;
                    Log.Warning("Could not successfully retrieve the subscription ID from variable: {0}", WebsiteOwnerNameKey);
                }

                if (SiteName == null)
                {
                    success = false;
                    Log.Warning("Could not successfully retrieve the deployment ID from variable: {0}", SiteNameKey);
                }

                if (ResourceGroup == null)
                {
                    success = false;
                    Log.Warning("Could not successfully retrieve the resource group name from variable: {0}", ResourceGroupKey);
                }

                if (success)
                {
                    resourceId = $"/subscriptions/{SubscriptionId}/resourcegroups/{ResourceGroup}/providers/microsoft.web/sites/{SiteName}".ToLowerInvariant();
                }
            }
            catch (Exception ex)
            {
                Log.SafeLogError(ex, "Could not successfully setup the resource id for azure app services.");
            }

            return resourceId;
        }

        private string GetSubscriptionId(IDictionary environmentVariables)
        {
            try
            {
                var websiteOwner = GetVariableIfExists(WebsiteOwnerNameKey, environmentVariables);
                if (!string.IsNullOrWhiteSpace(websiteOwner))
                {
                    var plusSplit = websiteOwner.Split('+');
                    if (plusSplit.Length > 0 && !string.IsNullOrWhiteSpace(plusSplit[0]))
                    {
                        return plusSplit[0];
                    }
                }
            }
            catch (Exception ex)
            {
                Log.SafeLogError(ex, "Could not successfully retrieve the subscription id for azure app services.");
            }

            return null;
        }

        private string GetVariableIfExists(string key, IDictionary environmentVariables)
        {
            if (environmentVariables.Contains(key))
            {
                return environmentVariables[key]?.ToString();
            }

            return null;
        }
    }
}


@@ -65,16 +65,19 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
             return tcs.Task;
         }

-        private void OnConnection(UvStreamHandle listenSocket, int status)
-        {
-            var acceptSocket = new UvTcpHandle();
-            acceptSocket.Init(Thread.Loop, Thread.QueueCloseHandle);
-            listenSocket.Accept(acceptSocket);
+        /// <summary>
+        /// Creates the socket used to listen for incoming connections
+        /// </summary>
+        protected abstract T CreateListenSocket(string host, int port);

-            DispatchConnection(acceptSocket);
-        }
+        /// <summary>
+        /// Handles an incoming connection
+        /// </summary>
+        /// <param name="listenSocket">Socket being used to listen on</param>
+        /// <param name="status">Connection status</param>
+        protected abstract void OnConnection(T listenSocket, int status);

-        protected virtual void DispatchConnection(UvTcpHandle socket)
+        protected virtual void DispatchConnection(T socket)
         {
             var connection = new Connection(this, socket);
             connection.Start();

// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using Microsoft.AspNet.Server.Kestrel.Infrastructure;
using Microsoft.AspNet.Server.Kestrel.Networking;
using System;
using System.Diagnostics;
using System.Net;
using System.Threading.Tasks;

namespace Microsoft.AspNet.Server.Kestrel.Http
{
    /// <summary>
    /// Summary description for Accept
    /// </summary>
    public class Listener : ListenerContext, IDisposable
    {
        private static readonly Action<UvStreamHandle, int, Exception, object> _connectionCallback = ConnectionCallback;

        UvTcpHandle ListenSocket { get; set; }

        private static void ConnectionCallback(UvStreamHandle stream, int status, Exception error, object state)
        {
            if (error != null)
            {
                Trace.WriteLine("Listener.ConnectionCallback " + error.ToString());
            }
            else
            {
                ((Listener)state).OnConnection(stream, status);
            }
        }

        public Listener(IMemoryPool memory)
        {
            Memory = memory;
        }

        public Task StartAsync(
            string scheme,
            string host,
            int port,
            KestrelThread thread,
            Func<Frame, Task> application)
        {
            Thread = thread;
            Application = application;

            var tcs = new TaskCompletionSource<int>();
            Thread.Post(_ =>
            {
                try
                {
                    ListenSocket = new UvTcpHandle();
                    ListenSocket.Init(Thread.Loop, Thread.QueueCloseHandle);
                    ListenSocket.Bind(new IPEndPoint(IPAddress.Any, port));
                    ListenSocket.Listen(Constants.ListenBacklog, _connectionCallback, this);
                    tcs.SetResult(0);
                }
                catch (Exception ex)
                {
                    tcs.SetException(ex);
                }
            }, null);
            return tcs.Task;
        }

        private void OnConnection(UvStreamHandle listenSocket, int status)
        {
            var acceptSocket = new UvTcpHandle();
            acceptSocket.Init(Thread.Loop, Thread.QueueCloseHandle);
            listenSocket.Accept(acceptSocket);

            DispatchConnection(acceptSocket);
        }

        protected virtual void DispatchConnection(UvTcpHandle socket)
        {
            var connection = new Connection(this, socket);
            connection.Start();
        }

        public void Dispose()
        {
            // Ensure the event loop is still running.
            // If the event loop isn't running and we try to wait on this Post
            // to complete, then KestrelEngine will never be disposed and
            // the exception that stopped the event loop will never be surfaced.
            if (Thread.FatalError == null)
            {
                var tcs = new TaskCompletionSource<int>();
                Thread.Post(
                    _ =>
                    {
                        try
                        {
                            ListenSocket.Dispose();
                            tcs.SetResult(0);
                        }
                        catch (Exception ex)
                        {
                            tcs.SetException(ex);
                        }
                    },
                    null);

                // REVIEW: Should we add a timeout here to be safe?
                tcs.Task.Wait();
            }

            ListenSocket = null;
        }
    }
}


@@ -78,11 +78,6 @@ namespace OpenTelemetry.Context
         /// <param name="value">The value of the context entry.</param>
         public DistributedContext(string key, string value)
         {
-            if (key is null || value is null)
-            {
-                throw new ArgumentNullException(key is null ? nameof(key) : nameof(value));
-            }
-
             this.entries = carrier is NoopDistributedContextCarrier ? emptyList : new List<DistributedContextEntry>(1) { new DistributedContextEntry(key, value) };
         }

// <copyright file="DistributedContext.cs" company="OpenTelemetry Authors">
// Copyright 2018, OpenTelemetry Authors
//
// 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.
// </copyright>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization.Formatters;

namespace OpenTelemetry.Context
{
    /// <summary>
    /// Distributed context.
    /// </summary>
    public readonly struct DistributedContext : IEquatable<DistributedContext>
    {
        private static DistributedContextCarrier carrier = NoopDistributedContextCarrier.Instance;
        private static List<DistributedContextEntry> emptyList = new List<DistributedContextEntry>();
        private readonly IEnumerable<DistributedContextEntry> entries;

        /// <summary>
        /// Initializes a new instance of the <see cref="DistributedContext"/> struct.
        /// </summary>
        /// <param name="entries">Entries for distributed context.</param>
        public DistributedContext(IEnumerable<DistributedContextEntry> entries)
        {
            if (carrier is NoopDistributedContextCarrier || entries is null || entries.Count() == 0)
            {
                this.entries = emptyList;
            }
            else
            {
                // Filter the default and duplicate entries.
                List<DistributedContextEntry> list = new List<DistributedContextEntry>(entries.Count());
                for (int i = 0; i < entries.Count(); i++)
                {
                    DistributedContextEntry entry = entries.ElementAt(i);
                    if (entry == default)
                    {
                        continue;
                    }

                    int j;
                    for (j = entries.Count() - 1; j > i; j--)
                    {
                        if (entry.Key == entries.ElementAt(j).Key)
                        {
                            break;
                        }
                    }

                    if (j <= i)
                    {
                        list.Add(entry);
                    }
                }

                this.entries = list;
            }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DistributedContext"/> struct.
        /// </summary>
        /// <param name="key">The key of the context entry.</param>
        /// <param name="value">The value of the context entry.</param>
        public DistributedContext(string key, string value)
        {
            if (key is null || value is null)
            {
                throw new ArgumentNullException(key is null ? nameof(key) : nameof(value));
            }

            this.entries = carrier is NoopDistributedContextCarrier ? emptyList : new List<DistributedContextEntry>(1) { new DistributedContextEntry(key, value) };
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DistributedContext"/> struct.
        /// </summary>
        /// <param name="entry">The distributed context entry.</param>
        public DistributedContext(DistributedContextEntry entry)
        {
            this.entries = carrier is NoopDistributedContextCarrier || entry == default ? emptyList : new List<DistributedContextEntry>(1) { entry };
        }

        /// <summary>
        /// Gets empty object of <see cref="DistributedContext"/> struct.
        /// </summary>
        public static DistributedContext Empty { get; } = new DistributedContext(emptyList);

        /// <summary>
        /// Gets the current <see cref="DistributedContext"/>.
        /// </summary>
        public static DistributedContext Current => carrier.Current;

        /// <summary>
        /// Gets or sets the default carrier instance of the <see cref="DistributedContextCarrier"/> class.
        /// SDK will need to override the value to AsyncLocalDistributedContextCarrier.Instance.
        /// </summary>
        public static DistributedContextCarrier Carrier
        {
            get => carrier;
            set
            {
                if (value is null)
                {
                    throw new ArgumentNullException(nameof(value));
                }

                carrier = value;
            }
        }

        /// <summary>
        /// Gets all the <see cref="DistributedContextEntry"/> in this <see cref="DistributedContext"/>.
        /// </summary>
        public IEnumerable<DistributedContextEntry> Entries => this.entries;

        /// <summary>
        /// Sets the current <see cref="DistributedContext"/>.
        /// </summary>
        /// <param name="context">Context to set as current.</param>
        /// <returns>Scope object. On disposal - original context will be restored.</returns>
        public static IDisposable SetCurrent(in DistributedContext context) => carrier.SetCurrent(context);

        /// <summary>
        /// Gets the <see cref="DistributedContextEntry"/> with the specified name.
        /// </summary>
        /// <param name="key">Name of the <see cref="DistributedContextEntry"/> to get.</param>
        /// <returns>The <see cref="DistributedContextEntry"/> with the specified name. If not found - null.</returns>
        public string GetEntryValue(string key) => this.entries.LastOrDefault(x => x.Key == key).Value;

        /// <inheritdoc/>
        public bool Equals(DistributedContext other)
        {
            if (this.entries.Count() != other.entries.Count())
            {
                return false;
            }

            foreach (DistributedContextEntry entry in this.entries)
            {
                if (other.GetEntryValue(entry.Key) != entry.Value)
                {
                    return false;
                }
            }

            return true;
        }
    }
}