def Javac(text: str, class_name: str, cflags: typing.List[str], timeout_seconds: int = 60) -> str: """Run code through javac. Args: text: The code to compile. class_name: The name of the class defined in the file. cflags: Additional options passed to javac. timeout_seconds: The number of seconds to wait before killing javac. Returns: The unmodified input code. """ with tempfile.TemporaryDirectory('w', prefix='clgen_javac_') as d: path = pathlib.Path(d) / (class_name + '.java') with open(path, 'w') as f: f.write(text) cmd = ['timeout', '-s9', str(timeout_seconds), 'javac', f.name] + cflags logging.debug('$ %s', ' '.join(cmd)) process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) stdout, stderr = process.communicate() if process.returncode == 9: raise errors.BadCodeException(f'Javac timed out after {timeout_seconds}s') elif process.returncode != 0: raise errors.BadCodeException(stderr) return text
def Compile(text: str) -> str: """A preprocessor which attempts to compile a class file for the given code. Args: text: Code to compile. Returns: The input code, unmodified. """ match = CLASS_NAME_RE.search(text) if not match: raise errors.BadCodeException('Failed to determine class name') class_name = match.group(1) return Javac(text, class_name, [])
def Javac( text: str, class_name: str, cflags: typing.List[str], timeout_seconds: int = 60, ) -> str: """Run code through javac. Args: text: The code to compile. class_name: The name of the class defined in the file. cflags: Additional options passed to javac. timeout_seconds: The number of seconds to wait before killing javac. Returns: The unmodified input code. """ with tempfile.TemporaryDirectory("w", prefix="clgen_javac_") as d: path = pathlib.Path(d) / (class_name + ".java") with open(path, "w") as f: f.write(text) cmd = ["timeout", "-s9", str(timeout_seconds), "javac", f.name] + cflags app.Log(2, "$ %s", " ".join(cmd)) process = subprocess.Popen( cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, ) stdout, stderr = process.communicate() if process.returncode == 9: raise errors.BadCodeException( f"Javac timed out after {timeout_seconds}s") elif process.returncode != 0: raise errors.BadCodeException(stderr) return text
def RejectSecrets(text: str) -> str: """Test for secrets such as private keys in a text. Args: text: The text to check. Returns: The unmodified text. Raises: BadCodeException: In case the text contains secrets. """ try: secrets.ScanForSecrets(text) return text except secrets.TextContainsSecret as e: raise errors.BadCodeException(str(e))
def UnwrapMethodInClass(text: str) -> str: """A preprocessor which unwraps a method from a class definition. This is the inverse of WrapMethodInClass(). Args: text: Class to strip a single method from. If the class contains more than one method, this function will error. Returns: A method definition. """ methods = extractors.ExtractJavaMethods(text, static_only=False) if len(methods) != 1: raise errors.BadCodeException( f"Expected 1 method, found {len(methods)}") return methods[0]
def MockPreprocessorBadCode(text: str) -> str: """A mock preprocessor which raises a BadCodeException.""" del text raise errors.BadCodeException('bad code')