1#!/usr/bin/env python 2# 3# Copyright 2018 The Chromium Authors. All rights reserved. 4# Use of this source code is governed by a BSD-style license that can be 5# found in the LICENSE file. 6# 7# Verify HEAD against origin/master to see if anything bad has been added to 8# HEAD that we would not want to roll. For example, if HEAD introduces any 9# UNCHECKED_BITSTREAM_READERs, then we definitely want to fix that before 10# including HEAD in Chromium. 11# 12# Usage: check_merge.py [new_branch] 13# where |new_branch| is the branch that we'd like to compare to origin/master. 14 15import os 16import re 17import sys 18import subprocess 19 20# The current good ffmpeg + config that we're diffing against. 21EXISTING_COMMIT = "origin/master" 22 23# If any of these regexes match, it indicates failure. Generally, we want to 24# catch any change in how these are defined. These are checked against things 25# that are added with respect to |EXISTING_COMMIT| by the commit we're checking. 26# 27# Remember that we're going to check ffmpeg files and Chromium files (e.g., 28# the build configs for each platform, ffmpeg_generated.gni, etc.). 29# TODO(liberato): consider making these a dictionary, with the value as some 30# descriptive text (e.g., the bug number) about why it's not allowed. 31INSERTION_TRIPWIRES = [ 32 # In Chromium, all codecs should use the safe bitstream reader. Roller must 33 # undo any new usage of the unchecked reader. 34 "^.define.*UNCHECKED_BITSTREAM_READER.*1", 35 36 # In Chromium, explicitly skipping some matroskadec code blocks for 37 # the following CONFIG variables (which should remain defined as 0) is 38 # necessary to remove code that may be a security risk. Discuss with cevans@ 39 # before removing these explicit skips or enabling these variables. 40 "^.define.*CONFIG_LZO.*1", 41 "^.define.*CONFIG_SIPR_DECODER.*1", 42 "^.define.*CONFIG_RA_288_DECODER.*1", 43 "^.define.*CONFIG_COOK_DECODER.*1", 44 "^.define.*CONFIG_ATRAC3_DECODER.*1", 45 46 # Miscellaneous tripwires. 47 "^.define.*CONFIG_SPDIF_DEMUXER.*1", 48 "^.define.*CONFIG_W64_DEMUXER.*1", 49 "^.define.*[Vv]4[Ll]2.*1", 50 "^.define.*CONFIG_PRORES_.*1", 51] 52 53# Filenames that will be excluded from the regex matching. 54EXCLUDED_FILENAMES = [ 55 r"^configure$", 56 r"^chromium/scripts/", 57 r"^chromium/patches/", 58] 59 60def search_regexps(text, regexps): 61 return [r for r in regexps if re.search(r, text)] 62 63def main(argv): 64 # What we're considering merging, and would like to check. Normally, this is 65 # HEAD, but you might want to verify some previous merge. 66 if len(argv) > 1: 67 new_commit = argv[1] 68 else: 69 new_commit = "HEAD" 70 71 print "Comparing %s to baseline %s..." % (new_commit, EXISTING_COMMIT) 72 73 diff = subprocess.Popen(["git", "diff", "-U0", EXISTING_COMMIT, new_commit], 74 stdout=subprocess.PIPE).communicate()[0] 75 filename=None 76 skip = False 77 files_encountered = 0 78 files_skipped = 0 79 failures = set() 80 for line in diff.splitlines(): 81 if line.startswith("+++"): 82 # +++ b/filename => filename 83 filename = line.split("/",1)[1] 84 skip = False 85 files_encountered += 1 86 if search_regexps(filename, EXCLUDED_FILENAMES): 87 skip = True 88 files_skipped += 1 89 elif line.startswith("+") and not skip: 90 # |line| is an insertion into |new_commit|. 91 # Drop the leading "+" from the string being searched. 92 tripwire = search_regexps(line[1:], INSERTION_TRIPWIRES) 93 if tripwire: 94 failures.add("Tripwire '%s' found in %s" % (tripwire, filename)) 95 96 # If we have failures, then print them and fail. 97 if failures: 98 for failure in failures: 99 print "Failure: %s" % failure 100 sys.exit(2) 101 102 print ("No problems found! Checked %d files, skipped %d." % 103 (files_encountered - files_skipped, files_skipped)) 104 105if __name__ == '__main__': 106 main(sys.argv) 107