diff --git a/.gitattributes b/.gitattributes index cbb13b2a5..79481810d 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4,9 +4,13 @@ ofrak_patch_maker/technical_docs/vbcc.pdf filter=lfs diff=lfs merge=lfs -text ofrak_core/test_ofrak/components/assets/* filter=lfs diff=lfs merge=lfs -text ofrak_core/test_ofrak/components/assets/README.md !filter !diff !merge text ofrak_core/test_ofrak/components/assets/kernel_address_space_build.sh !filter !diff !merge text +ofrak_core/test_ofrak/components/assets/string_test.c !filter !diff !merge text ofrak_tutorial/assets/* filter=lfs diff=lfs merge=lfs -text docs/user-guide/gui/assets/* filter=lfs diff=lfs merge=lfs -text ofrak_core/test_ofrak/components/assets/elf/* filter=lfs diff=lfs merge=lfs -text ofrak_core/test_ofrak/components/assets/elf/edge-cases/* filter=lfs diff=lfs merge=lfs -text frontend/public/themes/**/* filter=lfs diff=lfs merge=lfs -text disassemblers/ofrak_angr/ofrak_angr_test/assets/* filter=lfs diff=lfs merge=lfs -text +ofrak_core/pytest_ofrak/elf/assets/* filter=lfs diff=lfs merge=lfs -text +ofrak_core/pytest_ofrak/elf/assets/*.c !filter !diff !merge text +ofrak_core/pytest_ofrak/elf/assets/Makefile !filter !diff !merge text diff --git a/.github/workflows/test-all.yml b/.github/workflows/test-all.yml index 854eae2ab..cae4522d7 100644 --- a/.github/workflows/test-all.yml +++ b/.github/workflows/test-all.yml @@ -22,7 +22,7 @@ defaults: jobs: lint: name: Lint - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v3 with: @@ -52,7 +52,7 @@ jobs: ofrak-ghidra: name: Test main OFRAK components - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v3 with: @@ -93,7 +93,7 @@ jobs: ofrak-angr: name: Test OFRAK angr and capstone components - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v3 with: @@ -125,7 +125,7 @@ jobs: ofrak-tutorial: name: Test OFRAK examples and tutorial notebooks - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v3 with: diff --git a/disassemblers/ofrak_binary_ninja/ofrak_binary_ninja/components/binary_ninja_analyzer.py b/disassemblers/ofrak_binary_ninja/ofrak_binary_ninja/components/binary_ninja_analyzer.py index 0ca5a0234..b9d959dd7 100644 --- a/disassemblers/ofrak_binary_ninja/ofrak_binary_ninja/components/binary_ninja_analyzer.py +++ b/disassemblers/ofrak_binary_ninja/ofrak_binary_ninja/components/binary_ninja_analyzer.py @@ -1,5 +1,4 @@ import logging -import tempfile from dataclasses import dataclass from typing import Optional, List @@ -29,11 +28,9 @@ async def analyze( self, resource: Resource, config: Optional[BinaryNinjaAnalyzerConfig] = None ) -> BinaryNinjaAnalysis: if not config: - resource_data = await resource.get_data() - temp_file = tempfile.NamedTemporaryFile() - temp_file.write(resource_data) - temp_file.flush() - bv = open_view(temp_file.name) + async with resource.temp_to_disk(delete=False) as temp_path: + bv = open_view(temp_path) + return BinaryNinjaAnalysis(bv) else: bv = BinaryViewType.get_view_of_file(config.bndb_file) diff --git a/ofrak_core/CHANGELOG.md b/ofrak_core/CHANGELOG.md index cc9eb5ff7..4f68e2897 100644 --- a/ofrak_core/CHANGELOG.md +++ b/ofrak_core/CHANGELOG.md @@ -34,6 +34,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - Fix bug where calling `Resource.remove_tag` on both a tag class and a class that inherits from that class causes a `KeyError` on resource save. ([#510](https://github.com/redballoonsecurity/ofrak/pull/510)) - Use PyPI version of `bincopy`, upgrade to version 20.0.0 ([#528](https://github.com/redballoonsecurity/ofrak/pull/528)) - Fix bugs on Windows arising from using `os.path` methods when only forward-slashes are acceptable ([#521](https://github.com/redballoonsecurity/ofrak/pull/521)) +- Made some changes to OFRAK test suite to improve test coverage on Windows ([#487](https://github.com/redballoonsecurity/ofrak/pull/487)) +- Fix usage of `NamedTemporaryFile` with external tools on Windows ([#486](https://github.com/redballoonsecurity/ofrak/pull/486)) ### Changed - By default, the ofrak log is now `ofrak-YYYYMMDDhhmmss.log` rather than just `ofrak.log` and the name can be specified on the command line ([#480](https://github.com/redballoonsecurity/ofrak/pull/480)) diff --git a/ofrak_core/ofrak/component/abstract.py b/ofrak_core/ofrak/component/abstract.py index 19a1c0c8b..44aa25d4b 100644 --- a/ofrak_core/ofrak/component/abstract.py +++ b/ofrak_core/ofrak/component/abstract.py @@ -96,8 +96,14 @@ async def run( # Check if the problem was that one of the dependencies is missing missing_file = e.filename for dep in self.external_dependencies: - if dep.tool == missing_file: + if missing_file: + if dep.tool == missing_file: + raise ComponentMissingDependencyError(self, dep) + # on Windows a filename is not provided from subprocess FileNotFoundError, so just + # assume the any missing tool we find is the problem + elif not await dep.is_tool_installed(): raise ComponentMissingDependencyError(self, dep) + raise except CalledProcessError as e: raise ComponentSubprocessError(e) diff --git a/ofrak_core/ofrak/core/apk.py b/ofrak_core/ofrak/core/apk.py index 9cf6cd065..9b01321e5 100644 --- a/ofrak_core/ofrak/core/apk.py +++ b/ofrak_core/ofrak/core/apk.py @@ -2,7 +2,7 @@ import os import pathlib import sys -import tempfile +import tempfile312 as tempfile from subprocess import CalledProcessError from dataclasses import dataclass @@ -101,10 +101,7 @@ async def unpack(self, resource: Resource, config=None): :param config: """ apk = await resource.view_as(Apk) - data = await resource.get_data() - with tempfile.NamedTemporaryFile() as temp_file: - temp_file.write(data) - temp_file.flush() + async with resource.temp_to_disk() as temp_path: with tempfile.TemporaryDirectory() as temp_flush_dir: cmd = [ "apktool", @@ -112,7 +109,7 @@ async def unpack(self, resource: Resource, config=None): "--output", temp_flush_dir, "--force", - temp_file.name, + temp_path, ] proc = await asyncio.create_subprocess_exec( *cmd, @@ -156,7 +153,8 @@ async def pack( apk = await resource.view_as(Apk) temp_flush_dir = await apk.flush_to_disk() apk_suffix = ".apk" - with tempfile.NamedTemporaryFile(suffix=apk_suffix) as temp_apk: + with tempfile.NamedTemporaryFile(suffix=apk_suffix, delete_on_close=False) as temp_apk: + temp_apk.close() apk_cmd = [ "apktool", "build", @@ -218,13 +216,11 @@ async def identify(self, resource: Resource, config=None) -> None: if magic.mime == "application/vnd.android.package-archive": resource.add_tag(Apk) elif magic is not None and magic.mime in ["application/java-archive", "application/zip"]: - with tempfile.NamedTemporaryFile(suffix=".zip") as temp_file: - temp_file.write(await resource.get_data()) - temp_file.flush() + async with resource.temp_to_disk(suffix=".zip") as temp_path: unzip_cmd = [ "unzip", "-l", - temp_file.name, + temp_path, ] unzip_proc = await asyncio.create_subprocess_exec( *unzip_cmd, diff --git a/ofrak_core/ofrak/core/binwalk.py b/ofrak_core/ofrak/core/binwalk.py index 6a87d3723..e433d4e8e 100644 --- a/ofrak_core/ofrak/core/binwalk.py +++ b/ofrak_core/ofrak/core/binwalk.py @@ -1,5 +1,4 @@ import asyncio -import tempfile from concurrent.futures.process import ProcessPoolExecutor from dataclasses import dataclass from typing import Dict @@ -62,15 +61,11 @@ def __init__( async def analyze(self, resource: Resource, config=None) -> BinwalkAttributes: if not BINWALK_INSTALLED: raise ComponentMissingDependencyError(self, BINWALK_TOOL) - with tempfile.NamedTemporaryFile() as temp_file: - data = await resource.get_data() - temp_file.write(data) - temp_file.flush() - + async with resource.temp_to_disk() as temp_path: # Should errors be handled the way they are in the `DataSummaryAnalyzer`? Likely to be # overkill here. offsets = await asyncio.get_running_loop().run_in_executor( - self.pool, _run_binwalk_on_file, temp_file.name + self.pool, _run_binwalk_on_file, temp_path ) return BinwalkAttributes(offsets) diff --git a/ofrak_core/ofrak/core/cpio.py b/ofrak_core/ofrak/core/cpio.py index 4557efd29..685701990 100644 --- a/ofrak_core/ofrak/core/cpio.py +++ b/ofrak_core/ofrak/core/cpio.py @@ -1,6 +1,6 @@ import asyncio import logging -import tempfile +import tempfile312 as tempfile from dataclasses import dataclass from enum import Enum from subprocess import CalledProcessError @@ -100,8 +100,8 @@ async def unpack(self, resource: Resource, config=None): cwd=temp_flush_dir, ) await proc.communicate(input=resource_data) - if proc.returncode: - raise CalledProcessError(returncode=proc.returncode, cmd=cmd) + # if proc.returncode: + # raise CalledProcessError(returncode=proc.returncode, cmd=cmd) await cpio_v.initialize_from_disk(temp_flush_dir) diff --git a/ofrak_core/ofrak/core/elf/lief_modifier.py b/ofrak_core/ofrak/core/elf/lief_modifier.py index 6cd575167..56a11b65e 100644 --- a/ofrak_core/ofrak/core/elf/lief_modifier.py +++ b/ofrak_core/ofrak/core/elf/lief_modifier.py @@ -1,9 +1,9 @@ -import tempfile from dataclasses import dataclass from typing import List, Optional import lief +import tempfile312 as tempfile from ofrak.component.modifier import Modifier from ofrak.model.component_model import ComponentConfig from ofrak.resource import Resource @@ -68,9 +68,9 @@ async def modify(self, resource: Resource, config: LiefAddSegmentConfig) -> None else: _ = binary.add(segment) - with tempfile.NamedTemporaryFile() as temp_file: + with tempfile.NamedTemporaryFile(delete_on_close=False) as temp_file: + temp_file.close() binary.write(temp_file.name) - temp_file.flush() with open(temp_file.name, "rb") as f_handle: new_data = f_handle.read() # replace all old content (old range) with new content from Lief @@ -97,9 +97,9 @@ async def modify(self, resource: Resource, config: LiefAddSectionModifierConfig) section.flags = config.flags binary.add(section) - with tempfile.NamedTemporaryFile() as temp_file: + with tempfile.NamedTemporaryFile(delete_on_close=False) as temp_file: + temp_file.close() binary.write(temp_file.name) - temp_file.flush() with open(temp_file.name, "rb") as f_handle: new_data = f_handle.read() # replace all old content (old range) with new content from Lief @@ -123,9 +123,9 @@ async def modify(self, resource: Resource, config: LiefRemoveSectionModifierConf raise AttributeError(f"No section with name {config.name}") binary.remove(section) - with tempfile.NamedTemporaryFile() as temp_file: + with tempfile.NamedTemporaryFile(delete_on_close=False) as temp_file: + temp_file.close() binary.write(temp_file.name) - temp_file.flush() with open(temp_file.name, "rb") as f_handle: new_data = f_handle.read() # replace all old content (old range) with new content from Lief diff --git a/ofrak_core/ofrak/core/extfs.py b/ofrak_core/ofrak/core/extfs.py index b09cd4001..3c50705b9 100644 --- a/ofrak_core/ofrak/core/extfs.py +++ b/ofrak_core/ofrak/core/extfs.py @@ -1,5 +1,5 @@ import asyncio -import tempfile +import tempfile312 as tempfile from dataclasses import dataclass from subprocess import CalledProcessError @@ -55,16 +55,13 @@ class ExtUnpacker(Unpacker[None]): external_dependencies = (_DEBUGFS,) async def unpack(self, resource: Resource, config: ComponentConfig = None) -> None: - with tempfile.NamedTemporaryFile(suffix=".extfs") as temp_fs_file: - temp_fs_file.write(await resource.get_data()) - temp_fs_file.flush() - + async with resource.temp_to_disk(suffix=".extfs") as temp_fs_path: with tempfile.TemporaryDirectory() as temp_dir: command = [ "debugfs", "-R", f"rdump / {temp_dir}", - temp_fs_file.name, + temp_fs_path, ] proc = await asyncio.create_subprocess_exec( *command, diff --git a/ofrak_core/ofrak/core/filesystem.py b/ofrak_core/ofrak/core/filesystem.py index a6849b609..d62c8836f 100644 --- a/ofrak_core/ofrak/core/filesystem.py +++ b/ofrak_core/ofrak/core/filesystem.py @@ -2,7 +2,7 @@ import stat import sys import warnings -import tempfile +import tempfile312 as tempfile import posixpath from pathlib import PurePath from dataclasses import dataclass diff --git a/ofrak_core/ofrak/core/gzip.py b/ofrak_core/ofrak/core/gzip.py index 342810a6c..66df3d5ee 100644 --- a/ofrak_core/ofrak/core/gzip.py +++ b/ofrak_core/ofrak/core/gzip.py @@ -3,7 +3,7 @@ from typing import Optional import zlib from subprocess import CalledProcessError -import tempfile +import tempfile312 as tempfile from ofrak.component.packer import Packer from ofrak.component.unpacker import Unpacker @@ -110,9 +110,9 @@ async def pack_with_zlib_module(data: bytes) -> bytes: @staticmethod async def pack_with_pigz(data: bytes) -> bytes: - with tempfile.NamedTemporaryFile() as uncompressed_file: + with tempfile.NamedTemporaryFile(delete_on_close=False) as uncompressed_file: uncompressed_file.write(data) - uncompressed_file.flush() + uncompressed_file.close() cmd = [ "pigz", diff --git a/ofrak_core/ofrak/core/ihex.py b/ofrak_core/ofrak/core/ihex.py index 7d209bde3..429d6b447 100644 --- a/ofrak_core/ofrak/core/ihex.py +++ b/ofrak_core/ofrak/core/ihex.py @@ -2,7 +2,7 @@ import re import sys from dataclasses import dataclass -from typing import List, Union, Tuple, Any +from typing import Any, List, Tuple, Union from bincopy import BinFile diff --git a/ofrak_core/ofrak/core/iso9660.py b/ofrak_core/ofrak/core/iso9660.py index dcbb05113..4549846b3 100644 --- a/ofrak_core/ofrak/core/iso9660.py +++ b/ofrak_core/ofrak/core/iso9660.py @@ -1,7 +1,7 @@ import asyncio import logging +import tempfile312 as tempfile import posixpath -import tempfile from dataclasses import dataclass from io import BytesIO from subprocess import CalledProcessError @@ -301,7 +301,8 @@ async def pack(self, resource: Resource, config=None) -> None: iso_attrs = resource.get_attributes(ISO9660ImageAttributes) temp_flush_dir = await iso_view.flush_to_disk() - with tempfile.NamedTemporaryFile(suffix=".iso", mode="rb") as temp: + with tempfile.NamedTemporaryFile(suffix=".iso", mode="rb", delete_on_close=False) as temp: + temp.close() cmd = [ "mkisofs", *(["-J"] if iso_attrs.has_joliet else []), @@ -329,7 +330,8 @@ async def pack(self, resource: Resource, config=None) -> None: returncode = await proc.wait() if proc.returncode: raise CalledProcessError(returncode=returncode, cmd=cmd) - new_data = temp.read() + with open(temp.name, "rb") as new_fh: + new_data = new_fh.read() # Passing in the original range effectively replaces the original data with the new data resource.queue_patch(Range(0, await resource.get_data_length()), new_data) diff --git a/ofrak_core/ofrak/core/jffs2.py b/ofrak_core/ofrak/core/jffs2.py index 48883a095..1b0b94c1a 100644 --- a/ofrak_core/ofrak/core/jffs2.py +++ b/ofrak_core/ofrak/core/jffs2.py @@ -1,6 +1,6 @@ import asyncio import logging -import tempfile +import tempfile312 as tempfile from dataclasses import dataclass from subprocess import CalledProcessError @@ -38,18 +38,14 @@ class Jffs2Unpacker(Unpacker[None]): external_dependencies = (JEFFERSON,) async def unpack(self, resource: Resource, config=None): - with tempfile.NamedTemporaryFile() as temp_file: - resource_data = await resource.get_data() - temp_file.write(resource_data) - temp_file.flush() - + async with resource.temp_to_disk() as temp_path: with tempfile.TemporaryDirectory() as temp_flush_dir: cmd = [ "jefferson", "--force", "--dest", temp_flush_dir, - temp_file.name, + temp_path, ] proc = await asyncio.create_subprocess_exec( *cmd, @@ -73,7 +69,8 @@ class Jffs2Packer(Packer[None]): async def pack(self, resource: Resource, config=None): jffs2_view: Jffs2Filesystem = await resource.view_as(Jffs2Filesystem) temp_flush_dir = await jffs2_view.flush_to_disk() - with tempfile.NamedTemporaryFile(suffix=".sqsh", mode="rb") as temp: + with tempfile.NamedTemporaryFile(suffix=".sqsh", mode="rb", delete_on_close=False) as temp: + temp.close() cmd = [ "mkfs.jffs2", "-r", @@ -87,7 +84,8 @@ async def pack(self, resource: Resource, config=None): returncode = await proc.wait() if proc.returncode: raise CalledProcessError(returncode=returncode, cmd=cmd) - new_data = temp.read() + with open(temp.name, "rb") as new_fh: + new_data = new_fh.read() # Passing in the original range effectively replaces the original data with the new data resource.queue_patch(Range(0, await resource.get_data_length()), new_data) diff --git a/ofrak_core/ofrak/core/lzo.py b/ofrak_core/ofrak/core/lzo.py index f69634c52..ac22da72c 100644 --- a/ofrak_core/ofrak/core/lzo.py +++ b/ofrak_core/ofrak/core/lzo.py @@ -1,5 +1,4 @@ import asyncio -import tempfile from subprocess import CalledProcessError from ofrak.component.packer import Packer @@ -37,27 +36,18 @@ class LzoUnpacker(Unpacker[None]): external_dependencies = (LZOP,) async def unpack(self, resource: Resource, config: ComponentConfig = None) -> None: - with tempfile.NamedTemporaryFile(suffix=".lzo") as compressed_file: - compressed_file.write(await resource.get_data()) - compressed_file.flush() - - cmd = [ - "lzop", - "-d", - "-f", - "-c", - compressed_file.name, - ] - proc = await asyncio.create_subprocess_exec( - *cmd, - stdout=asyncio.subprocess.PIPE, - stderr=asyncio.subprocess.PIPE, - ) - stdout, stderr = await proc.communicate() - if proc.returncode: - raise CalledProcessError(returncode=proc.returncode, cmd=cmd) - - await resource.create_child(tags=(GenericBinary,), data=stdout) + cmd = ["lzop", "-d", "-f"] + proc = await asyncio.create_subprocess_exec( + *cmd, + stdin=asyncio.subprocess.PIPE, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + ) + stdout, stderr = await proc.communicate(await resource.get_data()) + if proc.returncode: + raise CalledProcessError(returncode=proc.returncode, cmd=cmd) + + await resource.create_child(tags=(GenericBinary,), data=stdout) class LzoPacker(Packer[None]): @@ -73,28 +63,20 @@ async def pack(self, resource: Resource, config: ComponentConfig = None): child_file = await lzo_view.get_child() uncompressed_data = await child_file.resource.get_data() - with tempfile.NamedTemporaryFile(suffix=".lzo") as uncompressed_file: - uncompressed_file.write(uncompressed_data) - uncompressed_file.flush() - - cmd = [ - "lzop", - "-f", - "-c", - uncompressed_file.name, - ] - proc = await asyncio.create_subprocess_exec( - *cmd, - stdout=asyncio.subprocess.PIPE, - stderr=asyncio.subprocess.PIPE, - ) - stdout, stderr = await proc.communicate() - if proc.returncode: - raise CalledProcessError(returncode=proc.returncode, cmd=cmd) - - compressed_data = stdout - original_size = await lzo_view.resource.get_data_length() - resource.queue_patch(Range(0, original_size), compressed_data) + cmd = ["lzop", "-f"] + proc = await asyncio.create_subprocess_exec( + *cmd, + stdin=asyncio.subprocess.PIPE, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + ) + stdout, stderr = await proc.communicate(uncompressed_data) + if proc.returncode: + raise CalledProcessError(returncode=proc.returncode, cmd=cmd) + + compressed_data = stdout + original_size = await lzo_view.resource.get_data_length() + resource.queue_patch(Range(0, original_size), compressed_data) MagicMimeIdentifier.register(LzoData, "application/x-lzop") diff --git a/ofrak_core/ofrak/core/patch_maker/modifiers.py b/ofrak_core/ofrak/core/patch_maker/modifiers.py index 76f1c9171..a5c0c098f 100644 --- a/ofrak_core/ofrak/core/patch_maker/modifiers.py +++ b/ofrak_core/ofrak/core/patch_maker/modifiers.py @@ -1,7 +1,7 @@ import asyncio import logging import os -import tempfile +import tempfile312 as tempfile from dataclasses import dataclass from typing import Dict, List, Optional, Tuple, Type, Union, cast diff --git a/ofrak_core/ofrak/core/rar.py b/ofrak_core/ofrak/core/rar.py index 6def88610..09eede84a 100644 --- a/ofrak_core/ofrak/core/rar.py +++ b/ofrak_core/ofrak/core/rar.py @@ -1,5 +1,5 @@ import asyncio -import tempfile +import tempfile312 as tempfile from dataclasses import dataclass from subprocess import CalledProcessError @@ -30,7 +30,7 @@ class RarArchive(GenericBinary, FilesystemRoot): class RarUnpacker(Unpacker[None]): """ - Unpack RAR archives using the free `unrar` tool. + Unpack RAR archives using the free `unar` tool. """ targets = (RarArchive,) @@ -38,28 +38,24 @@ class RarUnpacker(Unpacker[None]): external_dependencies = (UNAR,) async def unpack(self, resource: Resource, config: ComponentConfig = None): - with tempfile.NamedTemporaryFile( - suffix=".rar" - ) as temp_archive, tempfile.TemporaryDirectory() as temp_dir: - temp_archive.write(await resource.get_data()) - temp_archive.flush() - - cmd = [ - "unar", - "-no-directory", - "-no-recursion", - temp_archive.name, - ] - proc = await asyncio.create_subprocess_exec( - *cmd, - cwd=temp_dir, - ) - returncode = await proc.wait() - if proc.returncode: - raise CalledProcessError(returncode=returncode, cmd=cmd) - - rar_view = await resource.view_as(RarArchive) - await rar_view.initialize_from_disk(temp_dir) + async with resource.temp_to_disk(suffix=".rar") as temp_archive: + with tempfile.TemporaryDirectory() as temp_dir: + cmd = [ + "unar", + "-no-directory", + "-no-recursion", + temp_archive, + ] + proc = await asyncio.create_subprocess_exec( + *cmd, + cwd=temp_dir, + ) + returncode = await proc.wait() + if proc.returncode: + raise CalledProcessError(returncode=returncode, cmd=cmd) + + rar_view = await resource.view_as(RarArchive) + await rar_view.initialize_from_disk(temp_dir) MagicMimeIdentifier.register(RarArchive, "application/x-rar-compressed") diff --git a/ofrak_core/ofrak/core/seven_zip.py b/ofrak_core/ofrak/core/seven_zip.py index 64d5b7688..edd2d071a 100644 --- a/ofrak_core/ofrak/core/seven_zip.py +++ b/ofrak_core/ofrak/core/seven_zip.py @@ -1,7 +1,7 @@ import asyncio import logging import os -import tempfile +import tempfile312 as tempfile from dataclasses import dataclass from subprocess import CalledProcessError @@ -39,15 +39,13 @@ class SevenZUnpacker(Unpacker[None]): async def unpack(self, resource: Resource, config=None): seven_zip_v = await resource.view_as(SevenZFilesystem) resource_data = await seven_zip_v.resource.get_data() - with tempfile.NamedTemporaryFile() as temp_file: - temp_file.write(resource_data) - temp_file.flush() + async with resource.temp_to_disk(suffix=".7z") as temp_path: with tempfile.TemporaryDirectory() as temp_flush_dir: cmd = [ "7zz", "x", f"-o{temp_flush_dir}", - temp_file.name, + temp_path, ] proc = await asyncio.create_subprocess_exec( *cmd, diff --git a/ofrak_core/ofrak/core/squashfs.py b/ofrak_core/ofrak/core/squashfs.py index 10bdf645a..3f73c2c41 100644 --- a/ofrak_core/ofrak/core/squashfs.py +++ b/ofrak_core/ofrak/core/squashfs.py @@ -1,6 +1,6 @@ import asyncio import logging -import tempfile +import tempfile312 as tempfile from dataclasses import dataclass from subprocess import CalledProcessError @@ -66,11 +66,7 @@ class SquashfsUnpacker(Unpacker[None]): external_dependencies = (UNSQUASHFS,) async def unpack(self, resource: Resource, config=None): - with tempfile.NamedTemporaryFile() as temp_file: - resource_data = await resource.get_data() - temp_file.write(resource_data) - temp_file.flush() - + async with resource.temp_to_disk() as temp_path: with tempfile.TemporaryDirectory() as temp_flush_dir: cmd = [ "unsquashfs", @@ -78,7 +74,7 @@ async def unpack(self, resource: Resource, config=None): "-force", "-dest", temp_flush_dir, - temp_file.name, + temp_path, ] proc = await asyncio.create_subprocess_exec( *cmd, @@ -102,7 +98,8 @@ class SquashfsPacker(Packer[None]): async def pack(self, resource: Resource, config=None): squashfs_view: SquashfsFilesystem = await resource.view_as(SquashfsFilesystem) temp_flush_dir = await squashfs_view.flush_to_disk() - with tempfile.NamedTemporaryFile(suffix=".sqsh", mode="rb") as temp: + with tempfile.NamedTemporaryFile(suffix=".sqsh", mode="rb", delete_on_close=False) as temp: + temp.close() cmd = [ "mksquashfs", temp_flush_dir, @@ -115,7 +112,8 @@ async def pack(self, resource: Resource, config=None): returncode = await proc.wait() if proc.returncode: raise CalledProcessError(returncode=returncode, cmd=cmd) - new_data = temp.read() + with open(temp.name, "rb") as new_fh: + new_data = new_fh.read() # Passing in the original range effectively replaces the original data with the new data resource.queue_patch(Range(0, await resource.get_data_length()), new_data) diff --git a/ofrak_core/ofrak/core/strings_analyzer.py b/ofrak_core/ofrak/core/strings_analyzer.py index cd0b40243..4bc7fe9e6 100644 --- a/ofrak_core/ofrak/core/strings_analyzer.py +++ b/ofrak_core/ofrak/core/strings_analyzer.py @@ -1,5 +1,4 @@ import asyncio -import tempfile from dataclasses import dataclass from typing import Dict, Optional @@ -61,16 +60,13 @@ async def analyze( config = StringsAnalyzerConfig() strings = dict() - with tempfile.NamedTemporaryFile() as temp_file: - temp_file.write(await resource.get_data()) - temp_file.flush() - + async with resource.temp_to_disk() as temp_path: proc = await asyncio.subprocess.create_subprocess_exec( "strings", "-t", "d", f"-{config.min_length}", - temp_file.name, + temp_path, stdout=asyncio.subprocess.PIPE, ) diff --git a/ofrak_core/ofrak/core/tar.py b/ofrak_core/ofrak/core/tar.py index fabe7f876..6c023323a 100644 --- a/ofrak_core/ofrak/core/tar.py +++ b/ofrak_core/ofrak/core/tar.py @@ -1,6 +1,6 @@ import asyncio import os.path -import tempfile +import tempfile312 as tempfile from dataclasses import dataclass from subprocess import CalledProcessError @@ -37,16 +37,13 @@ class TarUnpacker(Unpacker[None]): async def unpack(self, resource: Resource, config: ComponentConfig = None) -> None: # Write the archive data to a file - with tempfile.NamedTemporaryFile(suffix=".tar") as temp_archive: - temp_archive.write(await resource.get_data()) - temp_archive.flush() - + async with resource.temp_to_disk(suffix=".tar") as temp_archive_path: # Check the archive member files to ensure none unpack to a parent directory cmd = [ "tar", "-P", "-tf", - temp_archive.name, + temp_archive_path, ] proc = await asyncio.create_subprocess_exec( *cmd, @@ -67,7 +64,7 @@ async def unpack(self, resource: Resource, config: ComponentConfig = None) -> No # Unpack into a temporary directory using the temporary file with tempfile.TemporaryDirectory() as temp_dir: - command = ["tar", "--xattrs", "-C", temp_dir, "-xf", temp_archive.name] + command = ["tar", "--xattrs", "-C", temp_dir, "-xf", temp_archive_path] proc = await asyncio.create_subprocess_exec( *command, ) @@ -94,7 +91,8 @@ async def pack(self, resource: Resource, config: ComponentConfig = None) -> None flush_dir = await tar_view.flush_to_disk() # Pack it back into a temporary archive - with tempfile.NamedTemporaryFile(suffix=".tar") as temp_archive: + with tempfile.NamedTemporaryFile(suffix=".tar", delete_on_close=False) as temp_archive: + temp_archive.close() cmd = [ "tar", "--xattrs", @@ -112,7 +110,8 @@ async def pack(self, resource: Resource, config: ComponentConfig = None) -> None raise CalledProcessError(returncode=returncode, cmd=cmd) # Replace the original archive data - resource.queue_patch(Range(0, await resource.get_data_length()), temp_archive.read()) + with open(temp_archive.name, "rb") as new_fh: + resource.queue_patch(Range(0, await resource.get_data_length()), new_fh.read()) MagicMimeIdentifier.register(TarArchive, "application/x-tar") diff --git a/ofrak_core/ofrak/core/ubi.py b/ofrak_core/ofrak/core/ubi.py index f82a64cda..f59dc72b7 100644 --- a/ofrak_core/ofrak/core/ubi.py +++ b/ofrak_core/ofrak/core/ubi.py @@ -1,5 +1,5 @@ import asyncio -import tempfile +import tempfile312 as tempfile from dataclasses import dataclass import logging from typing import List, Tuple @@ -131,15 +131,11 @@ class UbiAnalyzer(Analyzer[None, Ubi]): async def analyze(self, resource: Resource, config=None) -> Ubi: # Flush to disk - with tempfile.NamedTemporaryFile() as temp_file: - resource_data = await resource.get_data() - temp_file.write(resource_data) - temp_file.flush() - + async with resource.temp_to_disk() as temp_path: ubi_obj = ubireader_ubi( ubi_io.ubi_file( - temp_file.name, - block_size=guess_peb_size(temp_file.name), + temp_path, + block_size=guess_peb_size(temp_path), start_offset=0, end_offset=None, ) @@ -241,7 +237,6 @@ class UbiPacker(Packer[None]): async def pack(self, resource: Resource, config=None) -> None: ubi_view = await resource.view_as(Ubi) - # with tempfile.NamedTemporaryFile(mode="rb") as temp: with tempfile.TemporaryDirectory() as temp_flush_dir: ubi_volumes = await resource.get_children() ubinize_ini_entries = [] diff --git a/ofrak_core/ofrak/core/ubifs.py b/ofrak_core/ofrak/core/ubifs.py index 9af8157ff..250055125 100644 --- a/ofrak_core/ofrak/core/ubifs.py +++ b/ofrak_core/ofrak/core/ubifs.py @@ -1,5 +1,5 @@ import asyncio -import tempfile +import tempfile312 as tempfile from dataclasses import dataclass import logging from subprocess import CalledProcessError @@ -97,15 +97,11 @@ class UbifsAnalyzer(Analyzer[None, Ubifs]): external_dependencies = (PY_LZO_TOOL,) async def analyze(self, resource: Resource, config=None) -> Ubifs: - with tempfile.NamedTemporaryFile() as temp_file: - resource_data = await resource.get_data() - temp_file.write(resource_data) - temp_file.flush() - + async with resource.temp_to_disk() as temp_path: ubifs_obj = ubireader_ubifs( ubi_io.ubi_file( - temp_file.name, - block_size=guess_leb_size(temp_file.name), + temp_path, + block_size=guess_leb_size(temp_path), start_offset=0, end_offset=None, ) @@ -172,7 +168,8 @@ async def pack(self, resource: Resource, config=None) -> None: ubifs_view = await resource.view_as(Ubifs) flush_dir = await ubifs_view.flush_to_disk() - with tempfile.NamedTemporaryFile(mode="rb") as temp: + with tempfile.NamedTemporaryFile(mode="rb", delete_on_close=False) as temp: + temp.close() cmd = [ "mkfs.ubifs", "-m", @@ -202,7 +199,8 @@ async def pack(self, resource: Resource, config=None) -> None: returncode = await proc.wait() if proc.returncode: raise CalledProcessError(returncode=returncode, cmd=cmd) - new_data = temp.read() + with open(temp.name, "rb") as new_fh: + new_data = new_fh.read() resource.queue_patch(Range(0, await resource.get_data_length()), new_data) diff --git a/ofrak_core/ofrak/core/uefi.py b/ofrak_core/ofrak/core/uefi.py index 887b8dd18..7186127be 100644 --- a/ofrak_core/ofrak/core/uefi.py +++ b/ofrak_core/ofrak/core/uefi.py @@ -1,7 +1,7 @@ import os import asyncio import logging -import tempfile +import tempfile312 as tempfile from dataclasses import dataclass from subprocess import CalledProcessError diff --git a/ofrak_core/ofrak/core/xattr_stub.py b/ofrak_core/ofrak/core/xattr_stub.py index 2015bddd0..b6a27ccac 100644 --- a/ofrak_core/ofrak/core/xattr_stub.py +++ b/ofrak_core/ofrak/core/xattr_stub.py @@ -141,7 +141,7 @@ def removexattr(f, attr, symlink=False): def _warn_user_no_xattr(function_name: str) -> None: LOGGER.warning( - f"Function {function_name} not found. Library xattr is not available on Windows platforms. \ - Extended attributes will not be properly handled while using OFRAK on this platform. \ - If you require extended attributes, please use a platform that supports xattr." + f"Function {function_name} not found. Library xattr is not available on Windows platforms. " + "Extended attributes will not be properly handled while using OFRAK on this platform. " + "If you require extended attributes, please use a platform that supports xattr." ) diff --git a/ofrak_core/ofrak/core/zip.py b/ofrak_core/ofrak/core/zip.py index 2a19d06a8..39419a185 100644 --- a/ofrak_core/ofrak/core/zip.py +++ b/ofrak_core/ofrak/core/zip.py @@ -1,7 +1,7 @@ import asyncio import logging import os -import tempfile +import tempfile312 as tempfile from dataclasses import dataclass from subprocess import CalledProcessError @@ -51,13 +51,11 @@ class ZipUnpacker(Unpacker[None]): async def unpack(self, resource: Resource, config=None): zip_view = await resource.view_as(ZipArchive) - with tempfile.NamedTemporaryFile(suffix=".zip") as temp_archive: - temp_archive.write(await resource.get_data()) - temp_archive.flush() + async with resource.temp_to_disk(suffix=".zip") as temp_path: with tempfile.TemporaryDirectory() as temp_dir: cmd = [ "unzip", - temp_archive.name, + temp_path, "-d", temp_dir, ] diff --git a/ofrak_core/ofrak/core/zstd.py b/ofrak_core/ofrak/core/zstd.py index f0cddee81..91df1c1b9 100644 --- a/ofrak_core/ofrak/core/zstd.py +++ b/ofrak_core/ofrak/core/zstd.py @@ -1,5 +1,4 @@ import asyncio -import tempfile from dataclasses import dataclass from typing import Optional from subprocess import CalledProcessError @@ -42,29 +41,15 @@ class ZstdUnpacker(Unpacker[None]): external_dependencies = (ZSTD,) async def unpack(self, resource: Resource, config: ComponentConfig = None) -> None: - with tempfile.NamedTemporaryFile(suffix=".zstd") as compressed_file: - compressed_file.write(await resource.get_data()) - compressed_file.flush() - output_filename = tempfile.mktemp() - - cmd = [ - "zstd", - "-d", - "-k", - compressed_file.name, - "-o", - output_filename, - ] - proc = await asyncio.create_subprocess_exec( - *cmd, - ) - returncode = await proc.wait() - if proc.returncode: - raise CalledProcessError(returncode=returncode, cmd=cmd) - with open(output_filename, "rb") as f: - result = f.read() - - await resource.create_child(tags=(GenericBinary,), data=result) + cmd = ["zstd", "-d", "-k"] + proc = await asyncio.create_subprocess_exec( + *cmd, stdin=asyncio.subprocess.PIPE, stdout=asyncio.subprocess.PIPE + ) + result, _ = await proc.communicate(await resource.get_data()) + if proc.returncode: + raise CalledProcessError(returncode=proc.returncode, cmd=cmd) + + await resource.create_child(tags=(GenericBinary,), data=result) class ZstdPacker(Packer[ZstdPackerConfig]): @@ -82,27 +67,19 @@ async def pack(self, resource: Resource, config: Optional[ZstdPackerConfig] = No child_file = await zstd_view.get_child() uncompressed_data = await child_file.resource.get_data() - with tempfile.NamedTemporaryFile() as uncompressed_file: - uncompressed_file.write(uncompressed_data) - uncompressed_file.flush() - output_filename = tempfile.mktemp() - - command = ["zstd", "-T0", f"-{config.compression_level}"] - if config.compression_level > 19: - command.append("--ultra") - command.extend([uncompressed_file.name, "-o", output_filename]) - proc = await asyncio.create_subprocess_exec( - *command, - ) - returncode = await proc.wait() - if proc.returncode: - raise CalledProcessError(returncode=returncode, cmd=command) - with open(output_filename, "rb") as f: - result = f.read() - - compressed_data = result - original_size = await zstd_view.resource.get_data_length() - resource.queue_patch(Range(0, original_size), compressed_data) + command = ["zstd", "-T0", f"-{config.compression_level}"] + if config.compression_level > 19: + command.append("--ultra") + proc = await asyncio.create_subprocess_exec( + *command, stdin=asyncio.subprocess.PIPE, stdout=asyncio.subprocess.PIPE + ) + result, _ = await proc.communicate(uncompressed_data) + if proc.returncode: + raise CalledProcessError(returncode=proc.returncode, cmd=command) + + compressed_data = result + original_size = await zstd_view.resource.get_data_length() + resource.queue_patch(Range(0, original_size), compressed_data) MagicMimeIdentifier.register(ZstdData, "application/x-zstd") diff --git a/ofrak_core/ofrak/ofrak_context.py b/ofrak_core/ofrak/ofrak_context.py index 0b74878e4..8c0ee44d1 100644 --- a/ofrak_core/ofrak/ofrak_context.py +++ b/ofrak_core/ofrak/ofrak_context.py @@ -1,7 +1,7 @@ import asyncio import logging import os -import tempfile +import tempfile312 as tempfile import time from types import ModuleType from typing import Type, Any, Awaitable, Callable, List, Iterable, Optional diff --git a/ofrak_core/ofrak/resource.py b/ofrak_core/ofrak/resource.py index 1d7d3616c..69c651959 100644 --- a/ofrak_core/ofrak/resource.py +++ b/ofrak_core/ofrak/resource.py @@ -4,6 +4,7 @@ import logging from inspect import isawaitable from typing import ( + AsyncIterator, BinaryIO, Iterable, List, @@ -20,6 +21,8 @@ Pattern, overload, ) +from contextlib import asynccontextmanager +import tempfile312 as tempfile from ofrak.component.interface import ComponentInterface from ofrak.model.component_model import ComponentContext, CC, ComponentRunResult @@ -1527,6 +1530,21 @@ async def summarize_tree( tree_string += f"{indent}{branch_symbol}{SPACER_LINE}{child_tree_string}" return tree_string + @asynccontextmanager + async def temp_to_disk( + self, + prefix: Optional[str] = None, + suffix: Optional[str] = None, + dir: Optional[str] = None, + delete: bool = True, + ) -> AsyncIterator[str]: + with tempfile.NamedTemporaryFile( + mode="wb", prefix=prefix, suffix=suffix, dir=dir, delete_on_close=False, delete=delete + ) as temp: + temp.write(await self.get_data()) + temp.close() + yield temp.name + async def save_resources( resources: Iterable["Resource"], diff --git a/ofrak_core/pytest_ofrak/elf/assets/Makefile b/ofrak_core/pytest_ofrak/elf/assets/Makefile new file mode 100644 index 000000000..d1123333b --- /dev/null +++ b/ofrak_core/pytest_ofrak/elf/assets/Makefile @@ -0,0 +1,22 @@ + +CC=gcc + +default: program + +program.o: program.c $(HEADERS) + $(CC) -c program.c -fno-asynchronous-unwind-tables -o program.o + +program: program.o + $(CC) program.o -o program + +program_no_reloc: program.o + $(CC) program.o -no-pie -o program_no_reloc + +program_relocated: program_relocated.o + $(CC) program_relocated.o -o program_relocated + +large_elf.o: large_elf.c $(HEADERS) + $(CC) -c large_elf.c -o large_elf.o + +large_elf: large_elf.o + $(CC) large_elf.o -no-pie -o large_elf diff --git a/ofrak_core/pytest_ofrak/elf/assets/large_elf b/ofrak_core/pytest_ofrak/elf/assets/large_elf new file mode 100755 index 000000000..d49e8fcd1 --- /dev/null +++ b/ofrak_core/pytest_ofrak/elf/assets/large_elf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9788923282cb7150388b515be63281ea747c69ab2f304d079c08a83fe601e294 +size 651864 diff --git a/ofrak_core/pytest_ofrak/elf/assets/large_elf.c b/ofrak_core/pytest_ofrak/elf/assets/large_elf.c new file mode 100644 index 000000000..ad3a50e96 --- /dev/null +++ b/ofrak_core/pytest_ofrak/elf/assets/large_elf.c @@ -0,0 +1,17 @@ + +int foo(); +int bar(); + +int main() { + return bar(); +} + +int noop0(){}int noop1(){}int noop2(){}int noop3(){}int noop4(){}int noop5(){}int noop6(){}int noop7(){}int noop8(){}int noop9(){}int noop10(){}int noop11(){}int noop12(){}int noop13(){}int noop14(){}int noop15(){}int noop16(){}int noop17(){}int noop18(){}int noop19(){}int noop20(){}int noop21(){}int noop22(){}int noop23(){}int noop24(){}int noop25(){}int noop26(){}int noop27(){}int noop28(){}int noop29(){}int noop30(){}int noop31(){}int noop32(){}int noop33(){}int noop34(){}int noop35(){}int noop36(){}int noop37(){}int noop38(){}int noop39(){}int noop40(){}int noop41(){}int noop42(){}int noop43(){}int noop44(){}int noop45(){}int noop46(){}int noop47(){}int noop48(){}int noop49(){}int noop50(){}int noop51(){}int noop52(){}int noop53(){}int noop54(){}int noop55(){}int noop56(){}int noop57(){}int noop58(){}int noop59(){}int noop60(){}int noop61(){}int noop62(){}int noop63(){}int noop64(){}int noop65(){}int noop66(){}int noop67(){}int noop68(){}int noop69(){}int noop70(){}int noop71(){}int noop72(){}int noop73(){}int noop74(){}int noop75(){}int noop76(){}int noop77(){}int noop78(){}int noop79(){}int noop80(){}int noop81(){}int noop82(){}int noop83(){}int noop84(){}int noop85(){}int noop86(){}int noop87(){}int noop88(){}int noop89(){}int noop90(){}int noop91(){}int noop92(){}int noop93(){}int noop94(){}int noop95(){}int noop96(){}int noop97(){}int noop98(){}int noop99(){}int noop100(){}int noop101(){}int noop102(){}int noop103(){}int noop104(){}int noop105(){}int noop106(){}int noop107(){}int noop108(){}int noop109(){}int noop110(){}int noop111(){}int noop112(){}int noop113(){}int noop114(){}int noop115(){}int noop116(){}int noop117(){}int noop118(){}int noop119(){}int noop120(){}int noop121(){}int noop122(){}int noop123(){}int noop124(){}int noop125(){}int noop126(){}int noop127(){}int noop128(){}int noop129(){}int noop130(){}int noop131(){}int noop132(){}int noop133(){}int noop134(){}int noop135(){}int noop136(){}int noop137(){}int noop138(){}int noop139(){}int noop140(){}int noop141(){}int noop142(){}int noop143(){}int noop144(){}int noop145(){}int noop146(){}int noop147(){}int noop148(){}int noop149(){}int noop150(){}int noop151(){}int noop152(){}int noop153(){}int noop154(){}int noop155(){}int noop156(){}int noop157(){}int noop158(){}int noop159(){}int noop160(){}int noop161(){}int noop162(){}int noop163(){}int noop164(){}int noop165(){}int noop166(){}int noop167(){}int noop168(){}int noop169(){}int noop170(){}int noop171(){}int noop172(){}int noop173(){}int noop174(){}int noop175(){}int noop176(){}int noop177(){}int noop178(){}int noop179(){}int noop180(){}int noop181(){}int noop182(){}int noop183(){}int noop184(){}int noop185(){}int noop186(){}int noop187(){}int noop188(){}int noop189(){}int noop190(){}int noop191(){}int noop192(){}int noop193(){}int noop194(){}int noop195(){}int noop196(){}int noop197(){}int noop198(){}int noop199(){}int noop200(){}int noop201(){}int noop202(){}int noop203(){}int noop204(){}int noop205(){}int noop206(){}int noop207(){}int noop208(){}int noop209(){}int noop210(){}int noop211(){}int noop212(){}int noop213(){}int noop214(){}int noop215(){}int noop216(){}int noop217(){}int noop218(){}int noop219(){}int noop220(){}int noop221(){}int noop222(){}int noop223(){}int noop224(){}int noop225(){}int noop226(){}int noop227(){}int noop228(){}int noop229(){}int noop230(){}int noop231(){}int noop232(){}int noop233(){}int noop234(){}int noop235(){}int noop236(){}int noop237(){}int noop238(){}int noop239(){}int noop240(){}int noop241(){}int noop242(){}int noop243(){}int noop244(){}int noop245(){}int noop246(){}int noop247(){}int noop248(){}int noop249(){}int noop250(){}int noop251(){}int noop252(){}int noop253(){}int noop254(){}int noop255(){}int noop256(){}int noop257(){}int noop258(){}int noop259(){}int noop260(){}int noop261(){}int noop262(){}int noop263(){}int noop264(){}int noop265(){}int noop266(){}int noop267(){}int noop268(){}int noop269(){}int noop270(){}int noop271(){}int noop272(){}int noop273(){}int noop274(){}int noop275(){}int noop276(){}int noop277(){}int noop278(){}int noop279(){}int noop280(){}int noop281(){}int noop282(){}int noop283(){}int noop284(){}int noop285(){}int noop286(){}int noop287(){}int noop288(){}int noop289(){}int noop290(){}int noop291(){}int noop292(){}int noop293(){}int noop294(){}int noop295(){}int noop296(){}int noop297(){}int noop298(){}int noop299(){}int noop300(){}int noop301(){}int noop302(){}int noop303(){}int noop304(){}int noop305(){}int noop306(){}int noop307(){}int noop308(){}int noop309(){}int noop310(){}int noop311(){}int noop312(){}int noop313(){}int noop314(){}int noop315(){}int noop316(){}int noop317(){}int noop318(){}int noop319(){}int noop320(){}int noop321(){}int noop322(){}int noop323(){}int noop324(){}int noop325(){}int noop326(){}int noop327(){}int noop328(){}int noop329(){}int noop330(){}int noop331(){}int noop332(){}int noop333(){}int noop334(){}int noop335(){}int noop336(){}int noop337(){}int noop338(){}int noop339(){}int noop340(){}int noop341(){}int noop342(){}int noop343(){}int noop344(){}int noop345(){}int noop346(){}int noop347(){}int noop348(){}int noop349(){}int noop350(){}int noop351(){}int noop352(){}int noop353(){}int noop354(){}int noop355(){}int noop356(){}int noop357(){}int noop358(){}int noop359(){}int noop360(){}int noop361(){}int noop362(){}int noop363(){}int noop364(){}int noop365(){}int noop366(){}int noop367(){}int noop368(){}int noop369(){}int noop370(){}int noop371(){}int noop372(){}int noop373(){}int noop374(){}int noop375(){}int noop376(){}int noop377(){}int noop378(){}int noop379(){}int noop380(){}int noop381(){}int noop382(){}int noop383(){}int noop384(){}int noop385(){}int noop386(){}int noop387(){}int noop388(){}int noop389(){}int noop390(){}int noop391(){}int noop392(){}int noop393(){}int noop394(){}int noop395(){}int noop396(){}int noop397(){}int noop398(){}int noop399(){}int noop400(){}int noop401(){}int noop402(){}int noop403(){}int noop404(){}int noop405(){}int noop406(){}int noop407(){}int noop408(){}int noop409(){}int noop410(){}int noop411(){}int noop412(){}int noop413(){}int noop414(){}int noop415(){}int noop416(){}int noop417(){}int noop418(){}int noop419(){}int noop420(){}int noop421(){}int noop422(){}int noop423(){}int noop424(){}int noop425(){}int noop426(){}int noop427(){}int noop428(){}int noop429(){}int noop430(){}int noop431(){}int noop432(){}int noop433(){}int noop434(){}int noop435(){}int noop436(){}int noop437(){}int noop438(){}int noop439(){}int noop440(){}int noop441(){}int noop442(){}int noop443(){}int noop444(){}int noop445(){}int noop446(){}int noop447(){}int noop448(){}int noop449(){}int noop450(){}int noop451(){}int noop452(){}int noop453(){}int noop454(){}int noop455(){}int noop456(){}int noop457(){}int noop458(){}int noop459(){}int noop460(){}int noop461(){}int noop462(){}int noop463(){}int noop464(){}int noop465(){}int noop466(){}int noop467(){}int noop468(){}int noop469(){}int noop470(){}int noop471(){}int noop472(){}int noop473(){}int noop474(){}int noop475(){}int noop476(){}int noop477(){}int noop478(){}int noop479(){}int noop480(){}int noop481(){}int noop482(){}int noop483(){}int noop484(){}int noop485(){}int noop486(){}int noop487(){}int noop488(){}int noop489(){}int noop490(){}int noop491(){}int noop492(){}int noop493(){}int noop494(){}int noop495(){}int noop496(){}int noop497(){}int noop498(){}int noop499(){}int noop500(){}int noop501(){}int noop502(){}int noop503(){}int noop504(){}int noop505(){}int noop506(){}int noop507(){}int noop508(){}int noop509(){}int noop510(){}int noop511(){}int noop512(){}int noop513(){}int noop514(){}int noop515(){}int noop516(){}int noop517(){}int noop518(){}int noop519(){}int noop520(){}int noop521(){}int noop522(){}int noop523(){}int noop524(){}int noop525(){}int noop526(){}int noop527(){}int noop528(){}int noop529(){}int noop530(){}int noop531(){}int noop532(){}int noop533(){}int noop534(){}int noop535(){}int noop536(){}int noop537(){}int noop538(){}int noop539(){}int noop540(){}int noop541(){}int noop542(){}int noop543(){}int noop544(){}int noop545(){}int noop546(){}int noop547(){}int noop548(){}int noop549(){}int noop550(){}int noop551(){}int noop552(){}int noop553(){}int noop554(){}int noop555(){}int noop556(){}int noop557(){}int noop558(){}int noop559(){}int noop560(){}int noop561(){}int noop562(){}int noop563(){}int noop564(){}int noop565(){}int noop566(){}int noop567(){}int noop568(){}int noop569(){}int noop570(){}int noop571(){}int noop572(){}int noop573(){}int noop574(){}int noop575(){}int noop576(){}int noop577(){}int noop578(){}int noop579(){}int noop580(){}int noop581(){}int noop582(){}int noop583(){}int noop584(){}int noop585(){}int noop586(){}int noop587(){}int noop588(){}int noop589(){}int noop590(){}int noop591(){}int noop592(){}int noop593(){}int noop594(){}int noop595(){}int noop596(){}int noop597(){}int noop598(){}int noop599(){}int noop600(){}int noop601(){}int noop602(){}int noop603(){}int noop604(){}int noop605(){}int noop606(){}int noop607(){}int noop608(){}int noop609(){}int noop610(){}int noop611(){}int noop612(){}int noop613(){}int noop614(){}int noop615(){}int noop616(){}int noop617(){}int noop618(){}int noop619(){}int noop620(){}int noop621(){}int noop622(){}int noop623(){}int noop624(){}int noop625(){}int noop626(){}int noop627(){}int noop628(){}int noop629(){}int noop630(){}int noop631(){}int noop632(){}int noop633(){}int noop634(){}int noop635(){}int noop636(){}int noop637(){}int noop638(){}int noop639(){}int noop640(){}int noop641(){}int noop642(){}int noop643(){}int noop644(){}int noop645(){}int noop646(){}int noop647(){}int noop648(){}int noop649(){}int noop650(){}int noop651(){}int noop652(){}int noop653(){}int noop654(){}int noop655(){}int noop656(){}int noop657(){}int noop658(){}int noop659(){}int noop660(){}int noop661(){}int noop662(){}int noop663(){}int noop664(){}int noop665(){}int noop666(){}int noop667(){}int noop668(){}int noop669(){}int noop670(){}int noop671(){}int noop672(){}int noop673(){}int noop674(){}int noop675(){}int noop676(){}int noop677(){}int noop678(){}int noop679(){}int noop680(){}int noop681(){}int noop682(){}int noop683(){}int noop684(){}int noop685(){}int noop686(){}int noop687(){}int noop688(){}int noop689(){}int noop690(){}int noop691(){}int noop692(){}int noop693(){}int noop694(){}int noop695(){}int noop696(){}int noop697(){}int noop698(){}int noop699(){}int noop700(){}int noop701(){}int noop702(){}int noop703(){}int noop704(){}int noop705(){}int noop706(){}int noop707(){}int noop708(){}int noop709(){}int noop710(){}int noop711(){}int noop712(){}int noop713(){}int noop714(){}int noop715(){}int noop716(){}int noop717(){}int noop718(){}int noop719(){}int noop720(){}int noop721(){}int noop722(){}int noop723(){}int noop724(){}int noop725(){}int noop726(){}int noop727(){}int noop728(){}int noop729(){}int noop730(){}int noop731(){}int noop732(){}int noop733(){}int noop734(){}int noop735(){}int noop736(){}int noop737(){}int noop738(){}int noop739(){}int noop740(){}int noop741(){}int noop742(){}int noop743(){}int noop744(){}int noop745(){}int noop746(){}int noop747(){}int noop748(){}int noop749(){}int noop750(){}int noop751(){}int noop752(){}int noop753(){}int noop754(){}int noop755(){}int noop756(){}int noop757(){}int noop758(){}int noop759(){}int noop760(){}int noop761(){}int noop762(){}int noop763(){}int noop764(){}int noop765(){}int noop766(){}int noop767(){}int noop768(){}int noop769(){}int noop770(){}int noop771(){}int noop772(){}int noop773(){}int noop774(){}int noop775(){}int noop776(){}int noop777(){}int noop778(){}int noop779(){}int noop780(){}int noop781(){}int noop782(){}int noop783(){}int noop784(){}int noop785(){}int noop786(){}int noop787(){}int noop788(){}int noop789(){}int noop790(){}int noop791(){}int noop792(){}int noop793(){}int noop794(){}int noop795(){}int noop796(){}int noop797(){}int noop798(){}int noop799(){}int noop800(){}int noop801(){}int noop802(){}int noop803(){}int noop804(){}int noop805(){}int noop806(){}int noop807(){}int noop808(){}int noop809(){}int noop810(){}int noop811(){}int noop812(){}int noop813(){}int noop814(){}int noop815(){}int noop816(){}int noop817(){}int noop818(){}int noop819(){}int noop820(){}int noop821(){}int noop822(){}int noop823(){}int noop824(){}int noop825(){}int noop826(){}int noop827(){}int noop828(){}int noop829(){}int noop830(){}int noop831(){}int noop832(){}int noop833(){}int noop834(){}int noop835(){}int noop836(){}int noop837(){}int noop838(){}int noop839(){}int noop840(){}int noop841(){}int noop842(){}int noop843(){}int noop844(){}int noop845(){}int noop846(){}int noop847(){}int noop848(){}int noop849(){}int noop850(){}int noop851(){}int noop852(){}int noop853(){}int noop854(){}int noop855(){}int noop856(){}int noop857(){}int noop858(){}int noop859(){}int noop860(){}int noop861(){}int noop862(){}int noop863(){}int noop864(){}int noop865(){}int noop866(){}int noop867(){}int noop868(){}int noop869(){}int noop870(){}int noop871(){}int noop872(){}int noop873(){}int noop874(){}int noop875(){}int noop876(){}int noop877(){}int noop878(){}int noop879(){}int noop880(){}int noop881(){}int noop882(){}int noop883(){}int noop884(){}int noop885(){}int noop886(){}int noop887(){}int noop888(){}int noop889(){}int noop890(){}int noop891(){}int noop892(){}int noop893(){}int noop894(){}int noop895(){}int noop896(){}int noop897(){}int noop898(){}int noop899(){}int noop900(){}int noop901(){}int noop902(){}int noop903(){}int noop904(){}int noop905(){}int noop906(){}int noop907(){}int noop908(){}int noop909(){}int noop910(){}int noop911(){}int noop912(){}int noop913(){}int noop914(){}int noop915(){}int noop916(){}int noop917(){}int noop918(){}int noop919(){}int noop920(){}int noop921(){}int noop922(){}int noop923(){}int noop924(){}int noop925(){}int noop926(){}int noop927(){}int noop928(){}int noop929(){}int noop930(){}int noop931(){}int noop932(){}int noop933(){}int noop934(){}int noop935(){}int noop936(){}int noop937(){}int noop938(){}int noop939(){}int noop940(){}int noop941(){}int noop942(){}int noop943(){}int noop944(){}int noop945(){}int noop946(){}int noop947(){}int noop948(){}int noop949(){}int noop950(){}int noop951(){}int noop952(){}int noop953(){}int noop954(){}int noop955(){}int noop956(){}int noop957(){}int noop958(){}int noop959(){}int noop960(){}int noop961(){}int noop962(){}int noop963(){}int noop964(){}int noop965(){}int noop966(){}int noop967(){}int noop968(){}int noop969(){}int noop970(){}int noop971(){}int noop972(){}int noop973(){}int noop974(){}int noop975(){}int noop976(){}int noop977(){}int noop978(){}int noop979(){}int noop980(){}int noop981(){}int noop982(){}int noop983(){}int noop984(){}int noop985(){}int noop986(){}int noop987(){}int noop988(){}int noop989(){}int noop990(){}int noop991(){}int noop992(){}int noop993(){}int noop994(){}int noop995(){}int noop996(){}int noop997(){}int noop998(){}int noop999(){}int noop1000(){}int noop1001(){}int noop1002(){}int noop1003(){}int noop1004(){}int noop1005(){}int noop1006(){}int noop1007(){}int noop1008(){}int noop1009(){}int noop1010(){}int noop1011(){}int noop1012(){}int noop1013(){}int noop1014(){}int noop1015(){}int noop1016(){}int noop1017(){}int noop1018(){}int noop1019(){}int noop1020(){}int noop1021(){}int noop1022(){}int noop1023(){}int noop1024(){}int noop1025(){}int noop1026(){}int noop1027(){}int noop1028(){}int noop1029(){}int noop1030(){}int noop1031(){}int noop1032(){}int noop1033(){}int noop1034(){}int noop1035(){}int noop1036(){}int noop1037(){}int noop1038(){}int noop1039(){}int noop1040(){}int noop1041(){}int noop1042(){}int noop1043(){}int noop1044(){}int noop1045(){}int noop1046(){}int noop1047(){}int noop1048(){}int noop1049(){}int noop1050(){}int noop1051(){}int noop1052(){}int noop1053(){}int noop1054(){}int noop1055(){}int noop1056(){}int noop1057(){}int noop1058(){}int noop1059(){}int noop1060(){}int noop1061(){}int noop1062(){}int noop1063(){}int noop1064(){}int noop1065(){}int noop1066(){}int noop1067(){}int noop1068(){}int noop1069(){}int noop1070(){}int noop1071(){}int noop1072(){}int noop1073(){}int noop1074(){}int noop1075(){}int noop1076(){}int noop1077(){}int noop1078(){}int noop1079(){}int noop1080(){}int noop1081(){}int noop1082(){}int noop1083(){}int noop1084(){}int noop1085(){}int noop1086(){}int noop1087(){}int noop1088(){}int noop1089(){}int noop1090(){}int noop1091(){}int noop1092(){}int noop1093(){}int noop1094(){}int noop1095(){}int noop1096(){}int noop1097(){}int noop1098(){}int noop1099(){}int noop1100(){}int noop1101(){}int noop1102(){}int noop1103(){}int noop1104(){}int noop1105(){}int noop1106(){}int noop1107(){}int noop1108(){}int noop1109(){}int noop1110(){}int noop1111(){}int noop1112(){}int noop1113(){}int noop1114(){}int noop1115(){}int noop1116(){}int noop1117(){}int noop1118(){}int noop1119(){}int noop1120(){}int noop1121(){}int noop1122(){}int noop1123(){}int noop1124(){}int noop1125(){}int noop1126(){}int noop1127(){}int noop1128(){}int noop1129(){}int noop1130(){}int noop1131(){}int noop1132(){}int noop1133(){}int noop1134(){}int noop1135(){}int noop1136(){}int noop1137(){}int noop1138(){}int noop1139(){}int noop1140(){}int noop1141(){}int noop1142(){}int noop1143(){}int noop1144(){}int noop1145(){}int noop1146(){}int noop1147(){}int noop1148(){}int noop1149(){}int noop1150(){}int noop1151(){}int noop1152(){}int noop1153(){}int noop1154(){}int noop1155(){}int noop1156(){}int noop1157(){}int noop1158(){}int noop1159(){}int noop1160(){}int noop1161(){}int noop1162(){}int noop1163(){}int noop1164(){}int noop1165(){}int noop1166(){}int noop1167(){}int noop1168(){}int noop1169(){}int noop1170(){}int noop1171(){}int noop1172(){}int noop1173(){}int noop1174(){}int noop1175(){}int noop1176(){}int noop1177(){}int noop1178(){}int noop1179(){}int noop1180(){}int noop1181(){}int noop1182(){}int noop1183(){}int noop1184(){}int noop1185(){}int noop1186(){}int noop1187(){}int noop1188(){}int noop1189(){}int noop1190(){}int noop1191(){}int noop1192(){}int noop1193(){}int noop1194(){}int noop1195(){}int noop1196(){}int noop1197(){}int noop1198(){}int noop1199(){}int noop1200(){}int noop1201(){}int noop1202(){}int noop1203(){}int noop1204(){}int noop1205(){}int noop1206(){}int noop1207(){}int noop1208(){}int noop1209(){}int noop1210(){}int noop1211(){}int noop1212(){}int noop1213(){}int noop1214(){}int noop1215(){}int noop1216(){}int noop1217(){}int noop1218(){}int noop1219(){}int noop1220(){}int noop1221(){}int noop1222(){}int noop1223(){}int noop1224(){}int noop1225(){}int noop1226(){}int noop1227(){}int noop1228(){}int noop1229(){}int noop1230(){}int noop1231(){}int noop1232(){}int noop1233(){}int noop1234(){}int noop1235(){}int noop1236(){}int noop1237(){}int noop1238(){}int noop1239(){}int noop1240(){}int noop1241(){}int noop1242(){}int noop1243(){}int noop1244(){}int noop1245(){}int noop1246(){}int noop1247(){}int noop1248(){}int noop1249(){}int noop1250(){}int noop1251(){}int noop1252(){}int noop1253(){}int noop1254(){}int noop1255(){}int noop1256(){}int noop1257(){}int noop1258(){}int noop1259(){}int noop1260(){}int noop1261(){}int noop1262(){}int noop1263(){}int noop1264(){}int noop1265(){}int noop1266(){}int noop1267(){}int noop1268(){}int noop1269(){}int noop1270(){}int noop1271(){}int noop1272(){}int noop1273(){}int noop1274(){}int noop1275(){}int noop1276(){}int noop1277(){}int noop1278(){}int noop1279(){}int noop1280(){}int noop1281(){}int noop1282(){}int noop1283(){}int noop1284(){}int noop1285(){}int noop1286(){}int noop1287(){}int noop1288(){}int noop1289(){}int noop1290(){}int noop1291(){}int noop1292(){}int noop1293(){}int noop1294(){}int noop1295(){}int noop1296(){}int noop1297(){}int noop1298(){}int noop1299(){}int noop1300(){}int noop1301(){}int noop1302(){}int noop1303(){}int noop1304(){}int noop1305(){}int noop1306(){}int noop1307(){}int noop1308(){}int noop1309(){}int noop1310(){}int noop1311(){}int noop1312(){}int noop1313(){}int noop1314(){}int noop1315(){}int noop1316(){}int noop1317(){}int noop1318(){}int noop1319(){}int noop1320(){}int noop1321(){}int noop1322(){}int noop1323(){}int noop1324(){}int noop1325(){}int noop1326(){}int noop1327(){}int noop1328(){}int noop1329(){}int noop1330(){}int noop1331(){}int noop1332(){}int noop1333(){}int noop1334(){}int noop1335(){}int noop1336(){}int noop1337(){}int noop1338(){}int noop1339(){}int noop1340(){}int noop1341(){}int noop1342(){}int noop1343(){}int noop1344(){}int noop1345(){}int noop1346(){}int noop1347(){}int noop1348(){}int noop1349(){}int noop1350(){}int noop1351(){}int noop1352(){}int noop1353(){}int noop1354(){}int noop1355(){}int noop1356(){}int noop1357(){}int noop1358(){}int noop1359(){}int noop1360(){}int noop1361(){}int noop1362(){}int noop1363(){}int noop1364(){}int noop1365(){}int noop1366(){}int noop1367(){}int noop1368(){}int noop1369(){}int noop1370(){}int noop1371(){}int noop1372(){}int noop1373(){}int noop1374(){}int noop1375(){}int noop1376(){}int noop1377(){}int noop1378(){}int noop1379(){}int noop1380(){}int noop1381(){}int noop1382(){}int noop1383(){}int noop1384(){}int noop1385(){}int noop1386(){}int noop1387(){}int noop1388(){}int noop1389(){}int noop1390(){}int noop1391(){}int noop1392(){}int noop1393(){}int noop1394(){}int noop1395(){}int noop1396(){}int noop1397(){}int noop1398(){}int noop1399(){}int noop1400(){}int noop1401(){}int noop1402(){}int noop1403(){}int noop1404(){}int noop1405(){}int noop1406(){}int noop1407(){}int noop1408(){}int noop1409(){}int noop1410(){}int noop1411(){}int noop1412(){}int noop1413(){}int noop1414(){}int noop1415(){}int noop1416(){}int noop1417(){}int noop1418(){}int noop1419(){}int noop1420(){}int noop1421(){}int noop1422(){}int noop1423(){}int noop1424(){}int noop1425(){}int noop1426(){}int noop1427(){}int noop1428(){}int noop1429(){}int noop1430(){}int noop1431(){}int noop1432(){}int noop1433(){}int noop1434(){}int noop1435(){}int noop1436(){}int noop1437(){}int noop1438(){}int noop1439(){}int noop1440(){}int noop1441(){}int noop1442(){}int noop1443(){}int noop1444(){}int noop1445(){}int noop1446(){}int noop1447(){}int noop1448(){}int noop1449(){}int noop1450(){}int noop1451(){}int noop1452(){}int noop1453(){}int noop1454(){}int noop1455(){}int noop1456(){}int noop1457(){}int noop1458(){}int noop1459(){}int noop1460(){}int noop1461(){}int noop1462(){}int noop1463(){}int noop1464(){}int noop1465(){}int noop1466(){}int noop1467(){}int noop1468(){}int noop1469(){}int noop1470(){}int noop1471(){}int noop1472(){}int noop1473(){}int noop1474(){}int noop1475(){}int noop1476(){}int noop1477(){}int noop1478(){}int noop1479(){}int noop1480(){}int noop1481(){}int noop1482(){}int noop1483(){}int noop1484(){}int noop1485(){}int noop1486(){}int noop1487(){}int noop1488(){}int noop1489(){}int noop1490(){}int noop1491(){}int noop1492(){}int noop1493(){}int noop1494(){}int noop1495(){}int noop1496(){}int noop1497(){}int noop1498(){}int noop1499(){}int noop1500(){}int noop1501(){}int noop1502(){}int noop1503(){}int noop1504(){}int noop1505(){}int noop1506(){}int noop1507(){}int noop1508(){}int noop1509(){}int noop1510(){}int noop1511(){}int noop1512(){}int noop1513(){}int noop1514(){}int noop1515(){}int noop1516(){}int noop1517(){}int noop1518(){}int noop1519(){}int noop1520(){}int noop1521(){}int noop1522(){}int noop1523(){}int noop1524(){}int noop1525(){}int noop1526(){}int noop1527(){}int noop1528(){}int noop1529(){}int noop1530(){}int noop1531(){}int noop1532(){}int noop1533(){}int noop1534(){}int noop1535(){}int noop1536(){}int noop1537(){}int noop1538(){}int noop1539(){}int noop1540(){}int noop1541(){}int noop1542(){}int noop1543(){}int noop1544(){}int noop1545(){}int noop1546(){}int noop1547(){}int noop1548(){}int noop1549(){}int noop1550(){}int noop1551(){}int noop1552(){}int noop1553(){}int noop1554(){}int noop1555(){}int noop1556(){}int noop1557(){}int noop1558(){}int noop1559(){}int noop1560(){}int noop1561(){}int noop1562(){}int noop1563(){}int noop1564(){}int noop1565(){}int noop1566(){}int noop1567(){}int noop1568(){}int noop1569(){}int noop1570(){}int noop1571(){}int noop1572(){}int noop1573(){}int noop1574(){}int noop1575(){}int noop1576(){}int noop1577(){}int noop1578(){}int noop1579(){}int noop1580(){}int noop1581(){}int noop1582(){}int noop1583(){}int noop1584(){}int noop1585(){}int noop1586(){}int noop1587(){}int noop1588(){}int noop1589(){}int noop1590(){}int noop1591(){}int noop1592(){}int noop1593(){}int noop1594(){}int noop1595(){}int noop1596(){}int noop1597(){}int noop1598(){}int noop1599(){}int noop1600(){}int noop1601(){}int noop1602(){}int noop1603(){}int noop1604(){}int noop1605(){}int noop1606(){}int noop1607(){}int noop1608(){}int noop1609(){}int noop1610(){}int noop1611(){}int noop1612(){}int noop1613(){}int noop1614(){}int noop1615(){}int noop1616(){}int noop1617(){}int noop1618(){}int noop1619(){}int noop1620(){}int noop1621(){}int noop1622(){}int noop1623(){}int noop1624(){}int noop1625(){}int noop1626(){}int noop1627(){}int noop1628(){}int noop1629(){}int noop1630(){}int noop1631(){}int noop1632(){}int noop1633(){}int noop1634(){}int noop1635(){}int noop1636(){}int noop1637(){}int noop1638(){}int noop1639(){}int noop1640(){}int noop1641(){}int noop1642(){}int noop1643(){}int noop1644(){}int noop1645(){}int noop1646(){}int noop1647(){}int noop1648(){}int noop1649(){}int noop1650(){}int noop1651(){}int noop1652(){}int noop1653(){}int noop1654(){}int noop1655(){}int noop1656(){}int noop1657(){}int noop1658(){}int noop1659(){}int noop1660(){}int noop1661(){}int noop1662(){}int noop1663(){}int noop1664(){}int noop1665(){}int noop1666(){}int noop1667(){}int noop1668(){}int noop1669(){}int noop1670(){}int noop1671(){}int noop1672(){}int noop1673(){}int noop1674(){}int noop1675(){}int noop1676(){}int noop1677(){}int noop1678(){}int noop1679(){}int noop1680(){}int noop1681(){}int noop1682(){}int noop1683(){}int noop1684(){}int noop1685(){}int noop1686(){}int noop1687(){}int noop1688(){}int noop1689(){}int noop1690(){}int noop1691(){}int noop1692(){}int noop1693(){}int noop1694(){}int noop1695(){}int noop1696(){}int noop1697(){}int noop1698(){}int noop1699(){}int noop1700(){}int noop1701(){}int noop1702(){}int noop1703(){}int noop1704(){}int noop1705(){}int noop1706(){}int noop1707(){}int noop1708(){}int noop1709(){}int noop1710(){}int noop1711(){}int noop1712(){}int noop1713(){}int noop1714(){}int noop1715(){}int noop1716(){}int noop1717(){}int noop1718(){}int noop1719(){}int noop1720(){}int noop1721(){}int noop1722(){}int noop1723(){}int noop1724(){}int noop1725(){}int noop1726(){}int noop1727(){}int noop1728(){}int noop1729(){}int noop1730(){}int noop1731(){}int noop1732(){}int noop1733(){}int noop1734(){}int noop1735(){}int noop1736(){}int noop1737(){}int noop1738(){}int noop1739(){}int noop1740(){}int noop1741(){}int noop1742(){}int noop1743(){}int noop1744(){}int noop1745(){}int noop1746(){}int noop1747(){}int noop1748(){}int noop1749(){}int noop1750(){}int noop1751(){}int noop1752(){}int noop1753(){}int noop1754(){}int noop1755(){}int noop1756(){}int noop1757(){}int noop1758(){}int noop1759(){}int noop1760(){}int noop1761(){}int noop1762(){}int noop1763(){}int noop1764(){}int noop1765(){}int noop1766(){}int noop1767(){}int noop1768(){}int noop1769(){}int noop1770(){}int noop1771(){}int noop1772(){}int noop1773(){}int noop1774(){}int noop1775(){}int noop1776(){}int noop1777(){}int noop1778(){}int noop1779(){}int noop1780(){}int noop1781(){}int noop1782(){}int noop1783(){}int noop1784(){}int noop1785(){}int noop1786(){}int noop1787(){}int noop1788(){}int noop1789(){}int noop1790(){}int noop1791(){}int noop1792(){}int noop1793(){}int noop1794(){}int noop1795(){}int noop1796(){}int noop1797(){}int noop1798(){}int noop1799(){}int noop1800(){}int noop1801(){}int noop1802(){}int noop1803(){}int noop1804(){}int noop1805(){}int noop1806(){}int noop1807(){}int noop1808(){}int noop1809(){}int noop1810(){}int noop1811(){}int noop1812(){}int noop1813(){}int noop1814(){}int noop1815(){}int noop1816(){}int noop1817(){}int noop1818(){}int noop1819(){}int noop1820(){}int noop1821(){}int noop1822(){}int noop1823(){}int noop1824(){}int noop1825(){}int noop1826(){}int noop1827(){}int noop1828(){}int noop1829(){}int noop1830(){}int noop1831(){}int noop1832(){}int noop1833(){}int noop1834(){}int noop1835(){}int noop1836(){}int noop1837(){}int noop1838(){}int noop1839(){}int noop1840(){}int noop1841(){}int noop1842(){}int noop1843(){}int noop1844(){}int noop1845(){}int noop1846(){}int noop1847(){}int noop1848(){}int noop1849(){}int noop1850(){}int noop1851(){}int noop1852(){}int noop1853(){}int noop1854(){}int noop1855(){}int noop1856(){}int noop1857(){}int noop1858(){}int noop1859(){}int noop1860(){}int noop1861(){}int noop1862(){}int noop1863(){}int noop1864(){}int noop1865(){}int noop1866(){}int noop1867(){}int noop1868(){}int noop1869(){}int noop1870(){}int noop1871(){}int noop1872(){}int noop1873(){}int noop1874(){}int noop1875(){}int noop1876(){}int noop1877(){}int noop1878(){}int noop1879(){}int noop1880(){}int noop1881(){}int noop1882(){}int noop1883(){}int noop1884(){}int noop1885(){}int noop1886(){}int noop1887(){}int noop1888(){}int noop1889(){}int noop1890(){}int noop1891(){}int noop1892(){}int noop1893(){}int noop1894(){}int noop1895(){}int noop1896(){}int noop1897(){}int noop1898(){}int noop1899(){}int noop1900(){}int noop1901(){}int noop1902(){}int noop1903(){}int noop1904(){}int noop1905(){}int noop1906(){}int noop1907(){}int noop1908(){}int noop1909(){}int noop1910(){}int noop1911(){}int noop1912(){}int noop1913(){}int noop1914(){}int noop1915(){}int noop1916(){}int noop1917(){}int noop1918(){}int noop1919(){}int noop1920(){}int noop1921(){}int noop1922(){}int noop1923(){}int noop1924(){}int noop1925(){}int noop1926(){}int noop1927(){}int noop1928(){}int noop1929(){}int noop1930(){}int noop1931(){}int noop1932(){}int noop1933(){}int noop1934(){}int noop1935(){}int noop1936(){}int noop1937(){}int noop1938(){}int noop1939(){}int noop1940(){}int noop1941(){}int noop1942(){}int noop1943(){}int noop1944(){}int noop1945(){}int noop1946(){}int noop1947(){}int noop1948(){}int noop1949(){}int noop1950(){}int noop1951(){}int noop1952(){}int noop1953(){}int noop1954(){}int noop1955(){}int noop1956(){}int noop1957(){}int noop1958(){}int noop1959(){}int noop1960(){}int noop1961(){}int noop1962(){}int noop1963(){}int noop1964(){}int noop1965(){}int noop1966(){}int noop1967(){}int noop1968(){}int noop1969(){}int noop1970(){}int noop1971(){}int noop1972(){}int noop1973(){}int noop1974(){}int noop1975(){}int noop1976(){}int noop1977(){}int noop1978(){}int noop1979(){}int noop1980(){}int noop1981(){}int noop1982(){}int noop1983(){}int noop1984(){}int noop1985(){}int noop1986(){}int noop1987(){}int noop1988(){}int noop1989(){}int noop1990(){}int noop1991(){}int noop1992(){}int noop1993(){}int noop1994(){}int noop1995(){}int noop1996(){}int noop1997(){}int noop1998(){}int noop1999(){}int noop2000(){}int noop2001(){}int noop2002(){}int noop2003(){}int noop2004(){}int noop2005(){}int noop2006(){}int noop2007(){}int noop2008(){}int noop2009(){}int noop2010(){}int noop2011(){}int noop2012(){}int noop2013(){}int noop2014(){}int noop2015(){}int noop2016(){}int noop2017(){}int noop2018(){}int noop2019(){}int noop2020(){}int noop2021(){}int noop2022(){}int noop2023(){}int noop2024(){}int noop2025(){}int noop2026(){}int noop2027(){}int noop2028(){}int noop2029(){}int noop2030(){}int noop2031(){}int noop2032(){}int noop2033(){}int noop2034(){}int noop2035(){}int noop2036(){}int noop2037(){}int noop2038(){}int noop2039(){}int noop2040(){}int noop2041(){}int noop2042(){}int noop2043(){}int noop2044(){}int noop2045(){}int noop2046(){}int noop2047(){}int noop2048(){}int noop2049(){}int noop2050(){}int noop2051(){}int noop2052(){}int noop2053(){}int noop2054(){}int noop2055(){}int noop2056(){}int noop2057(){}int noop2058(){}int noop2059(){}int noop2060(){}int noop2061(){}int noop2062(){}int noop2063(){}int noop2064(){}int noop2065(){}int noop2066(){}int noop2067(){}int noop2068(){}int noop2069(){}int noop2070(){}int noop2071(){}int noop2072(){}int noop2073(){}int noop2074(){}int noop2075(){}int noop2076(){}int noop2077(){}int noop2078(){}int noop2079(){}int noop2080(){}int noop2081(){}int noop2082(){}int noop2083(){}int noop2084(){}int noop2085(){}int noop2086(){}int noop2087(){}int noop2088(){}int noop2089(){}int noop2090(){}int noop2091(){}int noop2092(){}int noop2093(){}int noop2094(){}int noop2095(){}int noop2096(){}int noop2097(){}int noop2098(){}int noop2099(){}int noop2100(){}int noop2101(){}int noop2102(){}int noop2103(){}int noop2104(){}int noop2105(){}int noop2106(){}int noop2107(){}int noop2108(){}int noop2109(){}int noop2110(){}int noop2111(){}int noop2112(){}int noop2113(){}int noop2114(){}int noop2115(){}int noop2116(){}int noop2117(){}int noop2118(){}int noop2119(){}int noop2120(){}int noop2121(){}int noop2122(){}int noop2123(){}int noop2124(){}int noop2125(){}int noop2126(){}int noop2127(){}int noop2128(){}int noop2129(){}int noop2130(){}int noop2131(){}int noop2132(){}int noop2133(){}int noop2134(){}int noop2135(){}int noop2136(){}int noop2137(){}int noop2138(){}int noop2139(){}int noop2140(){}int noop2141(){}int noop2142(){}int noop2143(){}int noop2144(){}int noop2145(){}int noop2146(){}int noop2147(){}int noop2148(){}int noop2149(){}int noop2150(){}int noop2151(){}int noop2152(){}int noop2153(){}int noop2154(){}int noop2155(){}int noop2156(){}int noop2157(){}int noop2158(){}int noop2159(){}int noop2160(){}int noop2161(){}int noop2162(){}int noop2163(){}int noop2164(){}int noop2165(){}int noop2166(){}int noop2167(){}int noop2168(){}int noop2169(){}int noop2170(){}int noop2171(){}int noop2172(){}int noop2173(){}int noop2174(){}int noop2175(){}int noop2176(){}int noop2177(){}int noop2178(){}int noop2179(){}int noop2180(){}int noop2181(){}int noop2182(){}int noop2183(){}int noop2184(){}int noop2185(){}int noop2186(){}int noop2187(){}int noop2188(){}int noop2189(){}int noop2190(){}int noop2191(){}int noop2192(){}int noop2193(){}int noop2194(){}int noop2195(){}int noop2196(){}int noop2197(){}int noop2198(){}int noop2199(){}int noop2200(){}int noop2201(){}int noop2202(){}int noop2203(){}int noop2204(){}int noop2205(){}int noop2206(){}int noop2207(){}int noop2208(){}int noop2209(){}int noop2210(){}int noop2211(){}int noop2212(){}int noop2213(){}int noop2214(){}int noop2215(){}int noop2216(){}int noop2217(){}int noop2218(){}int noop2219(){}int noop2220(){}int noop2221(){}int noop2222(){}int noop2223(){}int noop2224(){}int noop2225(){}int noop2226(){}int noop2227(){}int noop2228(){}int noop2229(){}int noop2230(){}int noop2231(){}int noop2232(){}int noop2233(){}int noop2234(){}int noop2235(){}int noop2236(){}int noop2237(){}int noop2238(){}int noop2239(){}int noop2240(){}int noop2241(){}int noop2242(){}int noop2243(){}int noop2244(){}int noop2245(){}int noop2246(){}int noop2247(){}int noop2248(){}int noop2249(){}int noop2250(){}int noop2251(){}int noop2252(){}int noop2253(){}int noop2254(){}int noop2255(){}int noop2256(){}int noop2257(){}int noop2258(){}int noop2259(){}int noop2260(){}int noop2261(){}int noop2262(){}int noop2263(){}int noop2264(){}int noop2265(){}int noop2266(){}int noop2267(){}int noop2268(){}int noop2269(){}int noop2270(){}int noop2271(){}int noop2272(){}int noop2273(){}int noop2274(){}int noop2275(){}int noop2276(){}int noop2277(){}int noop2278(){}int noop2279(){}int noop2280(){}int noop2281(){}int noop2282(){}int noop2283(){}int noop2284(){}int noop2285(){}int noop2286(){}int noop2287(){}int noop2288(){}int noop2289(){}int noop2290(){}int noop2291(){}int noop2292(){}int noop2293(){}int noop2294(){}int noop2295(){}int noop2296(){}int noop2297(){}int noop2298(){}int noop2299(){}int noop2300(){}int noop2301(){}int noop2302(){}int noop2303(){}int noop2304(){}int noop2305(){}int noop2306(){}int noop2307(){}int noop2308(){}int noop2309(){}int noop2310(){}int noop2311(){}int noop2312(){}int noop2313(){}int noop2314(){}int noop2315(){}int noop2316(){}int noop2317(){}int noop2318(){}int noop2319(){}int noop2320(){}int noop2321(){}int noop2322(){}int noop2323(){}int noop2324(){}int noop2325(){}int noop2326(){}int noop2327(){}int noop2328(){}int noop2329(){}int noop2330(){}int noop2331(){}int noop2332(){}int noop2333(){}int noop2334(){}int noop2335(){}int noop2336(){}int noop2337(){}int noop2338(){}int noop2339(){}int noop2340(){}int noop2341(){}int noop2342(){}int noop2343(){}int noop2344(){}int noop2345(){}int noop2346(){}int noop2347(){}int noop2348(){}int noop2349(){}int noop2350(){}int noop2351(){}int noop2352(){}int noop2353(){}int noop2354(){}int noop2355(){}int noop2356(){}int noop2357(){}int noop2358(){}int noop2359(){}int noop2360(){}int noop2361(){}int noop2362(){}int noop2363(){}int noop2364(){}int noop2365(){}int noop2366(){}int noop2367(){}int noop2368(){}int noop2369(){}int noop2370(){}int noop2371(){}int noop2372(){}int noop2373(){}int noop2374(){}int noop2375(){}int noop2376(){}int noop2377(){}int noop2378(){}int noop2379(){}int noop2380(){}int noop2381(){}int noop2382(){}int noop2383(){}int noop2384(){}int noop2385(){}int noop2386(){}int noop2387(){}int noop2388(){}int noop2389(){}int noop2390(){}int noop2391(){}int noop2392(){}int noop2393(){}int noop2394(){}int noop2395(){}int noop2396(){}int noop2397(){}int noop2398(){}int noop2399(){}int noop2400(){}int noop2401(){}int noop2402(){}int noop2403(){}int noop2404(){}int noop2405(){}int noop2406(){}int noop2407(){}int noop2408(){}int noop2409(){}int noop2410(){}int noop2411(){}int noop2412(){}int noop2413(){}int noop2414(){}int noop2415(){}int noop2416(){}int noop2417(){}int noop2418(){}int noop2419(){}int noop2420(){}int noop2421(){}int noop2422(){}int noop2423(){}int noop2424(){}int noop2425(){}int noop2426(){}int noop2427(){}int noop2428(){}int noop2429(){}int noop2430(){}int noop2431(){}int noop2432(){}int noop2433(){}int noop2434(){}int noop2435(){}int noop2436(){}int noop2437(){}int noop2438(){}int noop2439(){}int noop2440(){}int noop2441(){}int noop2442(){}int noop2443(){}int noop2444(){}int noop2445(){}int noop2446(){}int noop2447(){}int noop2448(){}int noop2449(){}int noop2450(){}int noop2451(){}int noop2452(){}int noop2453(){}int noop2454(){}int noop2455(){}int noop2456(){}int noop2457(){}int noop2458(){}int noop2459(){}int noop2460(){}int noop2461(){}int noop2462(){}int noop2463(){}int noop2464(){}int noop2465(){}int noop2466(){}int noop2467(){}int noop2468(){}int noop2469(){}int noop2470(){}int noop2471(){}int noop2472(){}int noop2473(){}int noop2474(){}int noop2475(){}int noop2476(){}int noop2477(){}int noop2478(){}int noop2479(){}int noop2480(){}int noop2481(){}int noop2482(){}int noop2483(){}int noop2484(){}int noop2485(){}int noop2486(){}int noop2487(){}int noop2488(){}int noop2489(){}int noop2490(){}int noop2491(){}int noop2492(){}int noop2493(){}int noop2494(){}int noop2495(){}int noop2496(){}int noop2497(){}int noop2498(){}int noop2499(){}int noop2500(){}int noop2501(){}int noop2502(){}int noop2503(){}int noop2504(){}int noop2505(){}int noop2506(){}int noop2507(){}int noop2508(){}int noop2509(){}int noop2510(){}int noop2511(){}int noop2512(){}int noop2513(){}int noop2514(){}int noop2515(){}int noop2516(){}int noop2517(){}int noop2518(){}int noop2519(){}int noop2520(){}int noop2521(){}int noop2522(){}int noop2523(){}int noop2524(){}int noop2525(){}int noop2526(){}int noop2527(){}int noop2528(){}int noop2529(){}int noop2530(){}int noop2531(){}int noop2532(){}int noop2533(){}int noop2534(){}int noop2535(){}int noop2536(){}int noop2537(){}int noop2538(){}int noop2539(){}int noop2540(){}int noop2541(){}int noop2542(){}int noop2543(){}int noop2544(){}int noop2545(){}int noop2546(){}int noop2547(){}int noop2548(){}int noop2549(){}int noop2550(){}int noop2551(){}int noop2552(){}int noop2553(){}int noop2554(){}int noop2555(){}int noop2556(){}int noop2557(){}int noop2558(){}int noop2559(){}int noop2560(){}int noop2561(){}int noop2562(){}int noop2563(){}int noop2564(){}int noop2565(){}int noop2566(){}int noop2567(){}int noop2568(){}int noop2569(){}int noop2570(){}int noop2571(){}int noop2572(){}int noop2573(){}int noop2574(){}int noop2575(){}int noop2576(){}int noop2577(){}int noop2578(){}int noop2579(){}int noop2580(){}int noop2581(){}int noop2582(){}int noop2583(){}int noop2584(){}int noop2585(){}int noop2586(){}int noop2587(){}int noop2588(){}int noop2589(){}int noop2590(){}int noop2591(){}int noop2592(){}int noop2593(){}int noop2594(){}int noop2595(){}int noop2596(){}int noop2597(){}int noop2598(){}int noop2599(){}int noop2600(){}int noop2601(){}int noop2602(){}int noop2603(){}int noop2604(){}int noop2605(){}int noop2606(){}int noop2607(){}int noop2608(){}int noop2609(){}int noop2610(){}int noop2611(){}int noop2612(){}int noop2613(){}int noop2614(){}int noop2615(){}int noop2616(){}int noop2617(){}int noop2618(){}int noop2619(){}int noop2620(){}int noop2621(){}int noop2622(){}int noop2623(){}int noop2624(){}int noop2625(){}int noop2626(){}int noop2627(){}int noop2628(){}int noop2629(){}int noop2630(){}int noop2631(){}int noop2632(){}int noop2633(){}int noop2634(){}int noop2635(){}int noop2636(){}int noop2637(){}int noop2638(){}int noop2639(){}int noop2640(){}int noop2641(){}int noop2642(){}int noop2643(){}int noop2644(){}int noop2645(){}int noop2646(){}int noop2647(){}int noop2648(){}int noop2649(){}int noop2650(){}int noop2651(){}int noop2652(){}int noop2653(){}int noop2654(){}int noop2655(){}int noop2656(){}int noop2657(){}int noop2658(){}int noop2659(){}int noop2660(){}int noop2661(){}int noop2662(){}int noop2663(){}int noop2664(){}int noop2665(){}int noop2666(){}int noop2667(){}int noop2668(){}int noop2669(){}int noop2670(){}int noop2671(){}int noop2672(){}int noop2673(){}int noop2674(){}int noop2675(){}int noop2676(){}int noop2677(){}int noop2678(){}int noop2679(){}int noop2680(){}int noop2681(){}int noop2682(){}int noop2683(){}int noop2684(){}int noop2685(){}int noop2686(){}int noop2687(){}int noop2688(){}int noop2689(){}int noop2690(){}int noop2691(){}int noop2692(){}int noop2693(){}int noop2694(){}int noop2695(){}int noop2696(){}int noop2697(){}int noop2698(){}int noop2699(){}int noop2700(){}int noop2701(){}int noop2702(){}int noop2703(){}int noop2704(){}int noop2705(){}int noop2706(){}int noop2707(){}int noop2708(){}int noop2709(){}int noop2710(){}int noop2711(){}int noop2712(){}int noop2713(){}int noop2714(){}int noop2715(){}int noop2716(){}int noop2717(){}int noop2718(){}int noop2719(){}int noop2720(){}int noop2721(){}int noop2722(){}int noop2723(){}int noop2724(){}int noop2725(){}int noop2726(){}int noop2727(){}int noop2728(){}int noop2729(){}int noop2730(){}int noop2731(){}int noop2732(){}int noop2733(){}int noop2734(){}int noop2735(){}int noop2736(){}int noop2737(){}int noop2738(){}int noop2739(){}int noop2740(){}int noop2741(){}int noop2742(){}int noop2743(){}int noop2744(){}int noop2745(){}int noop2746(){}int noop2747(){}int noop2748(){}int noop2749(){}int noop2750(){}int noop2751(){}int noop2752(){}int noop2753(){}int noop2754(){}int noop2755(){}int noop2756(){}int noop2757(){}int noop2758(){}int noop2759(){}int noop2760(){}int noop2761(){}int noop2762(){}int noop2763(){}int noop2764(){}int noop2765(){}int noop2766(){}int noop2767(){}int noop2768(){}int noop2769(){}int noop2770(){}int noop2771(){}int noop2772(){}int noop2773(){}int noop2774(){}int noop2775(){}int noop2776(){}int noop2777(){}int noop2778(){}int noop2779(){}int noop2780(){}int noop2781(){}int noop2782(){}int noop2783(){}int noop2784(){}int noop2785(){}int noop2786(){}int noop2787(){}int noop2788(){}int noop2789(){}int noop2790(){}int noop2791(){}int noop2792(){}int noop2793(){}int noop2794(){}int noop2795(){}int noop2796(){}int noop2797(){}int noop2798(){}int noop2799(){}int noop2800(){}int noop2801(){}int noop2802(){}int noop2803(){}int noop2804(){}int noop2805(){}int noop2806(){}int noop2807(){}int noop2808(){}int noop2809(){}int noop2810(){}int noop2811(){}int noop2812(){}int noop2813(){}int noop2814(){}int noop2815(){}int noop2816(){}int noop2817(){}int noop2818(){}int noop2819(){}int noop2820(){}int noop2821(){}int noop2822(){}int noop2823(){}int noop2824(){}int noop2825(){}int noop2826(){}int noop2827(){}int noop2828(){}int noop2829(){}int noop2830(){}int noop2831(){}int noop2832(){}int noop2833(){}int noop2834(){}int noop2835(){}int noop2836(){}int noop2837(){}int noop2838(){}int noop2839(){}int noop2840(){}int noop2841(){}int noop2842(){}int noop2843(){}int noop2844(){}int noop2845(){}int noop2846(){}int noop2847(){}int noop2848(){}int noop2849(){}int noop2850(){}int noop2851(){}int noop2852(){}int noop2853(){}int noop2854(){}int noop2855(){}int noop2856(){}int noop2857(){}int noop2858(){}int noop2859(){}int noop2860(){}int noop2861(){}int noop2862(){}int noop2863(){}int noop2864(){}int noop2865(){}int noop2866(){}int noop2867(){}int noop2868(){}int noop2869(){}int noop2870(){}int noop2871(){}int noop2872(){}int noop2873(){}int noop2874(){}int noop2875(){}int noop2876(){}int noop2877(){}int noop2878(){}int noop2879(){}int noop2880(){}int noop2881(){}int noop2882(){}int noop2883(){}int noop2884(){}int noop2885(){}int noop2886(){}int noop2887(){}int noop2888(){}int noop2889(){}int noop2890(){}int noop2891(){}int noop2892(){}int noop2893(){}int noop2894(){}int noop2895(){}int noop2896(){}int noop2897(){}int noop2898(){}int noop2899(){}int noop2900(){}int noop2901(){}int noop2902(){}int noop2903(){}int noop2904(){}int noop2905(){}int noop2906(){}int noop2907(){}int noop2908(){}int noop2909(){}int noop2910(){}int noop2911(){}int noop2912(){}int noop2913(){}int noop2914(){}int noop2915(){}int noop2916(){}int noop2917(){}int noop2918(){}int noop2919(){}int noop2920(){}int noop2921(){}int noop2922(){}int noop2923(){}int noop2924(){}int noop2925(){}int noop2926(){}int noop2927(){}int noop2928(){}int noop2929(){}int noop2930(){}int noop2931(){}int noop2932(){}int noop2933(){}int noop2934(){}int noop2935(){}int noop2936(){}int noop2937(){}int noop2938(){}int noop2939(){}int noop2940(){}int noop2941(){}int noop2942(){}int noop2943(){}int noop2944(){}int noop2945(){}int noop2946(){}int noop2947(){}int noop2948(){}int noop2949(){}int noop2950(){}int noop2951(){}int noop2952(){}int noop2953(){}int noop2954(){}int noop2955(){}int noop2956(){}int noop2957(){}int noop2958(){}int noop2959(){}int noop2960(){}int noop2961(){}int noop2962(){}int noop2963(){}int noop2964(){}int noop2965(){}int noop2966(){}int noop2967(){}int noop2968(){}int noop2969(){}int noop2970(){}int noop2971(){}int noop2972(){}int noop2973(){}int noop2974(){}int noop2975(){}int noop2976(){}int noop2977(){}int noop2978(){}int noop2979(){}int noop2980(){}int noop2981(){}int noop2982(){}int noop2983(){}int noop2984(){}int noop2985(){}int noop2986(){}int noop2987(){}int noop2988(){}int noop2989(){}int noop2990(){}int noop2991(){}int noop2992(){}int noop2993(){}int noop2994(){}int noop2995(){}int noop2996(){}int noop2997(){}int noop2998(){}int noop2999(){}int noop3000(){}int noop3001(){}int noop3002(){}int noop3003(){}int noop3004(){}int noop3005(){}int noop3006(){}int noop3007(){}int noop3008(){}int noop3009(){}int noop3010(){}int noop3011(){}int noop3012(){}int noop3013(){}int noop3014(){}int noop3015(){}int noop3016(){}int noop3017(){}int noop3018(){}int noop3019(){}int noop3020(){}int noop3021(){}int noop3022(){}int noop3023(){}int noop3024(){}int noop3025(){}int noop3026(){}int noop3027(){}int noop3028(){}int noop3029(){}int noop3030(){}int noop3031(){}int noop3032(){}int noop3033(){}int noop3034(){}int noop3035(){}int noop3036(){}int noop3037(){}int noop3038(){}int noop3039(){}int noop3040(){}int noop3041(){}int noop3042(){}int noop3043(){}int noop3044(){}int noop3045(){}int noop3046(){}int noop3047(){}int noop3048(){}int noop3049(){}int noop3050(){}int noop3051(){}int noop3052(){}int noop3053(){}int noop3054(){}int noop3055(){}int noop3056(){}int noop3057(){}int noop3058(){}int noop3059(){}int noop3060(){}int noop3061(){}int noop3062(){}int noop3063(){}int noop3064(){}int noop3065(){}int noop3066(){}int noop3067(){}int noop3068(){}int noop3069(){}int noop3070(){}int noop3071(){}int noop3072(){}int noop3073(){}int noop3074(){}int noop3075(){}int noop3076(){}int noop3077(){}int noop3078(){}int noop3079(){}int noop3080(){}int noop3081(){}int noop3082(){}int noop3083(){}int noop3084(){}int noop3085(){}int noop3086(){}int noop3087(){}int noop3088(){}int noop3089(){}int noop3090(){}int noop3091(){}int noop3092(){}int noop3093(){}int noop3094(){}int noop3095(){}int noop3096(){}int noop3097(){}int noop3098(){}int noop3099(){}int noop3100(){}int noop3101(){}int noop3102(){}int noop3103(){}int noop3104(){}int noop3105(){}int noop3106(){}int noop3107(){}int noop3108(){}int noop3109(){}int noop3110(){}int noop3111(){}int noop3112(){}int noop3113(){}int noop3114(){}int noop3115(){}int noop3116(){}int noop3117(){}int noop3118(){}int noop3119(){}int noop3120(){}int noop3121(){}int noop3122(){}int noop3123(){}int noop3124(){}int noop3125(){}int noop3126(){}int noop3127(){}int noop3128(){}int noop3129(){}int noop3130(){}int noop3131(){}int noop3132(){}int noop3133(){}int noop3134(){}int noop3135(){}int noop3136(){}int noop3137(){}int noop3138(){}int noop3139(){}int noop3140(){}int noop3141(){}int noop3142(){}int noop3143(){}int noop3144(){}int noop3145(){}int noop3146(){}int noop3147(){}int noop3148(){}int noop3149(){}int noop3150(){}int noop3151(){}int noop3152(){}int noop3153(){}int noop3154(){}int noop3155(){}int noop3156(){}int noop3157(){}int noop3158(){}int noop3159(){}int noop3160(){}int noop3161(){}int noop3162(){}int noop3163(){}int noop3164(){}int noop3165(){}int noop3166(){}int noop3167(){}int noop3168(){}int noop3169(){}int noop3170(){}int noop3171(){}int noop3172(){}int noop3173(){}int noop3174(){}int noop3175(){}int noop3176(){}int noop3177(){}int noop3178(){}int noop3179(){}int noop3180(){}int noop3181(){}int noop3182(){}int noop3183(){}int noop3184(){}int noop3185(){}int noop3186(){}int noop3187(){}int noop3188(){}int noop3189(){}int noop3190(){}int noop3191(){}int noop3192(){}int noop3193(){}int noop3194(){}int noop3195(){}int noop3196(){}int noop3197(){}int noop3198(){}int noop3199(){}int noop3200(){}int noop3201(){}int noop3202(){}int noop3203(){}int noop3204(){}int noop3205(){}int noop3206(){}int noop3207(){}int noop3208(){}int noop3209(){}int noop3210(){}int noop3211(){}int noop3212(){}int noop3213(){}int noop3214(){}int noop3215(){}int noop3216(){}int noop3217(){}int noop3218(){}int noop3219(){}int noop3220(){}int noop3221(){}int noop3222(){}int noop3223(){}int noop3224(){}int noop3225(){}int noop3226(){}int noop3227(){}int noop3228(){}int noop3229(){}int noop3230(){}int noop3231(){}int noop3232(){}int noop3233(){}int noop3234(){}int noop3235(){}int noop3236(){}int noop3237(){}int noop3238(){}int noop3239(){}int noop3240(){}int noop3241(){}int noop3242(){}int noop3243(){}int noop3244(){}int noop3245(){}int noop3246(){}int noop3247(){}int noop3248(){}int noop3249(){}int noop3250(){}int noop3251(){}int noop3252(){}int noop3253(){}int noop3254(){}int noop3255(){}int noop3256(){}int noop3257(){}int noop3258(){}int noop3259(){}int noop3260(){}int noop3261(){}int noop3262(){}int noop3263(){}int noop3264(){}int noop3265(){}int noop3266(){}int noop3267(){}int noop3268(){}int noop3269(){}int noop3270(){}int noop3271(){}int noop3272(){}int noop3273(){}int noop3274(){}int noop3275(){}int noop3276(){}int noop3277(){}int noop3278(){}int noop3279(){}int noop3280(){}int noop3281(){}int noop3282(){}int noop3283(){}int noop3284(){}int noop3285(){}int noop3286(){}int noop3287(){}int noop3288(){}int noop3289(){}int noop3290(){}int noop3291(){}int noop3292(){}int noop3293(){}int noop3294(){}int noop3295(){}int noop3296(){}int noop3297(){}int noop3298(){}int noop3299(){}int noop3300(){}int noop3301(){}int noop3302(){}int noop3303(){}int noop3304(){}int noop3305(){}int noop3306(){}int noop3307(){}int noop3308(){}int noop3309(){}int noop3310(){}int noop3311(){}int noop3312(){}int noop3313(){}int noop3314(){}int noop3315(){}int noop3316(){}int noop3317(){}int noop3318(){}int noop3319(){}int noop3320(){}int noop3321(){}int noop3322(){}int noop3323(){}int noop3324(){}int noop3325(){}int noop3326(){}int noop3327(){}int noop3328(){}int noop3329(){}int noop3330(){}int noop3331(){}int noop3332(){}int noop3333(){}int noop3334(){}int noop3335(){}int noop3336(){}int noop3337(){}int noop3338(){}int noop3339(){}int noop3340(){}int noop3341(){}int noop3342(){}int noop3343(){}int noop3344(){}int noop3345(){}int noop3346(){}int noop3347(){}int noop3348(){}int noop3349(){}int noop3350(){}int noop3351(){}int noop3352(){}int noop3353(){}int noop3354(){}int noop3355(){}int noop3356(){}int noop3357(){}int noop3358(){}int noop3359(){}int noop3360(){}int noop3361(){}int noop3362(){}int noop3363(){}int noop3364(){}int noop3365(){}int noop3366(){}int noop3367(){}int noop3368(){}int noop3369(){}int noop3370(){}int noop3371(){}int noop3372(){}int noop3373(){}int noop3374(){}int noop3375(){}int noop3376(){}int noop3377(){}int noop3378(){}int noop3379(){}int noop3380(){}int noop3381(){}int noop3382(){}int noop3383(){}int noop3384(){}int noop3385(){}int noop3386(){}int noop3387(){}int noop3388(){}int noop3389(){}int noop3390(){}int noop3391(){}int noop3392(){}int noop3393(){}int noop3394(){}int noop3395(){}int noop3396(){}int noop3397(){}int noop3398(){}int noop3399(){}int noop3400(){}int noop3401(){}int noop3402(){}int noop3403(){}int noop3404(){}int noop3405(){}int noop3406(){}int noop3407(){}int noop3408(){}int noop3409(){}int noop3410(){}int noop3411(){}int noop3412(){}int noop3413(){}int noop3414(){}int noop3415(){}int noop3416(){}int noop3417(){}int noop3418(){}int noop3419(){}int noop3420(){}int noop3421(){}int noop3422(){}int noop3423(){}int noop3424(){}int noop3425(){}int noop3426(){}int noop3427(){}int noop3428(){}int noop3429(){}int noop3430(){}int noop3431(){}int noop3432(){}int noop3433(){}int noop3434(){}int noop3435(){}int noop3436(){}int noop3437(){}int noop3438(){}int noop3439(){}int noop3440(){}int noop3441(){}int noop3442(){}int noop3443(){}int noop3444(){}int noop3445(){}int noop3446(){}int noop3447(){}int noop3448(){}int noop3449(){}int noop3450(){}int noop3451(){}int noop3452(){}int noop3453(){}int noop3454(){}int noop3455(){}int noop3456(){}int noop3457(){}int noop3458(){}int noop3459(){}int noop3460(){}int noop3461(){}int noop3462(){}int noop3463(){}int noop3464(){}int noop3465(){}int noop3466(){}int noop3467(){}int noop3468(){}int noop3469(){}int noop3470(){}int noop3471(){}int noop3472(){}int noop3473(){}int noop3474(){}int noop3475(){}int noop3476(){}int noop3477(){}int noop3478(){}int noop3479(){}int noop3480(){}int noop3481(){}int noop3482(){}int noop3483(){}int noop3484(){}int noop3485(){}int noop3486(){}int noop3487(){}int noop3488(){}int noop3489(){}int noop3490(){}int noop3491(){}int noop3492(){}int noop3493(){}int noop3494(){}int noop3495(){}int noop3496(){}int noop3497(){}int noop3498(){}int noop3499(){}int noop3500(){}int noop3501(){}int noop3502(){}int noop3503(){}int noop3504(){}int noop3505(){}int noop3506(){}int noop3507(){}int noop3508(){}int noop3509(){}int noop3510(){}int noop3511(){}int noop3512(){}int noop3513(){}int noop3514(){}int noop3515(){}int noop3516(){}int noop3517(){}int noop3518(){}int noop3519(){}int noop3520(){}int noop3521(){}int noop3522(){}int noop3523(){}int noop3524(){}int noop3525(){}int noop3526(){}int noop3527(){}int noop3528(){}int noop3529(){}int noop3530(){}int noop3531(){}int noop3532(){}int noop3533(){}int noop3534(){}int noop3535(){}int noop3536(){}int noop3537(){}int noop3538(){}int noop3539(){}int noop3540(){}int noop3541(){}int noop3542(){}int noop3543(){}int noop3544(){}int noop3545(){}int noop3546(){}int noop3547(){}int noop3548(){}int noop3549(){}int noop3550(){}int noop3551(){}int noop3552(){}int noop3553(){}int noop3554(){}int noop3555(){}int noop3556(){}int noop3557(){}int noop3558(){}int noop3559(){}int noop3560(){}int noop3561(){}int noop3562(){}int noop3563(){}int noop3564(){}int noop3565(){}int noop3566(){}int noop3567(){}int noop3568(){}int noop3569(){}int noop3570(){}int noop3571(){}int noop3572(){}int noop3573(){}int noop3574(){}int noop3575(){}int noop3576(){}int noop3577(){}int noop3578(){}int noop3579(){}int noop3580(){}int noop3581(){}int noop3582(){}int noop3583(){}int noop3584(){}int noop3585(){}int noop3586(){}int noop3587(){}int noop3588(){}int noop3589(){}int noop3590(){}int noop3591(){}int noop3592(){}int noop3593(){}int noop3594(){}int noop3595(){}int noop3596(){}int noop3597(){}int noop3598(){}int noop3599(){}int noop3600(){}int noop3601(){}int noop3602(){}int noop3603(){}int noop3604(){}int noop3605(){}int noop3606(){}int noop3607(){}int noop3608(){}int noop3609(){}int noop3610(){}int noop3611(){}int noop3612(){}int noop3613(){}int noop3614(){}int noop3615(){}int noop3616(){}int noop3617(){}int noop3618(){}int noop3619(){}int noop3620(){}int noop3621(){}int noop3622(){}int noop3623(){}int noop3624(){}int noop3625(){}int noop3626(){}int noop3627(){}int noop3628(){}int noop3629(){}int noop3630(){}int noop3631(){}int noop3632(){}int noop3633(){}int noop3634(){}int noop3635(){}int noop3636(){}int noop3637(){}int noop3638(){}int noop3639(){}int noop3640(){}int noop3641(){}int noop3642(){}int noop3643(){}int noop3644(){}int noop3645(){}int noop3646(){}int noop3647(){}int noop3648(){}int noop3649(){}int noop3650(){}int noop3651(){}int noop3652(){}int noop3653(){}int noop3654(){}int noop3655(){}int noop3656(){}int noop3657(){}int noop3658(){}int noop3659(){}int noop3660(){}int noop3661(){}int noop3662(){}int noop3663(){}int noop3664(){}int noop3665(){}int noop3666(){}int noop3667(){}int noop3668(){}int noop3669(){}int noop3670(){}int noop3671(){}int noop3672(){}int noop3673(){}int noop3674(){}int noop3675(){}int noop3676(){}int noop3677(){}int noop3678(){}int noop3679(){}int noop3680(){}int noop3681(){}int noop3682(){}int noop3683(){}int noop3684(){}int noop3685(){}int noop3686(){}int noop3687(){}int noop3688(){}int noop3689(){}int noop3690(){}int noop3691(){}int noop3692(){}int noop3693(){}int noop3694(){}int noop3695(){}int noop3696(){}int noop3697(){}int noop3698(){}int noop3699(){}int noop3700(){}int noop3701(){}int noop3702(){}int noop3703(){}int noop3704(){}int noop3705(){}int noop3706(){}int noop3707(){}int noop3708(){}int noop3709(){}int noop3710(){}int noop3711(){}int noop3712(){}int noop3713(){}int noop3714(){}int noop3715(){}int noop3716(){}int noop3717(){}int noop3718(){}int noop3719(){}int noop3720(){}int noop3721(){}int noop3722(){}int noop3723(){}int noop3724(){}int noop3725(){}int noop3726(){}int noop3727(){}int noop3728(){}int noop3729(){}int noop3730(){}int noop3731(){}int noop3732(){}int noop3733(){}int noop3734(){}int noop3735(){}int noop3736(){}int noop3737(){}int noop3738(){}int noop3739(){}int noop3740(){}int noop3741(){}int noop3742(){}int noop3743(){}int noop3744(){}int noop3745(){}int noop3746(){}int noop3747(){}int noop3748(){}int noop3749(){}int noop3750(){}int noop3751(){}int noop3752(){}int noop3753(){}int noop3754(){}int noop3755(){}int noop3756(){}int noop3757(){}int noop3758(){}int noop3759(){}int noop3760(){}int noop3761(){}int noop3762(){}int noop3763(){}int noop3764(){}int noop3765(){}int noop3766(){}int noop3767(){}int noop3768(){}int noop3769(){}int noop3770(){}int noop3771(){}int noop3772(){}int noop3773(){}int noop3774(){}int noop3775(){}int noop3776(){}int noop3777(){}int noop3778(){}int noop3779(){}int noop3780(){}int noop3781(){}int noop3782(){}int noop3783(){}int noop3784(){}int noop3785(){}int noop3786(){}int noop3787(){}int noop3788(){}int noop3789(){}int noop3790(){}int noop3791(){}int noop3792(){}int noop3793(){}int noop3794(){}int noop3795(){}int noop3796(){}int noop3797(){}int noop3798(){}int noop3799(){}int noop3800(){}int noop3801(){}int noop3802(){}int noop3803(){}int noop3804(){}int noop3805(){}int noop3806(){}int noop3807(){}int noop3808(){}int noop3809(){}int noop3810(){}int noop3811(){}int noop3812(){}int noop3813(){}int noop3814(){}int noop3815(){}int noop3816(){}int noop3817(){}int noop3818(){}int noop3819(){}int noop3820(){}int noop3821(){}int noop3822(){}int noop3823(){}int noop3824(){}int noop3825(){}int noop3826(){}int noop3827(){}int noop3828(){}int noop3829(){}int noop3830(){}int noop3831(){}int noop3832(){}int noop3833(){}int noop3834(){}int noop3835(){}int noop3836(){}int noop3837(){}int noop3838(){}int noop3839(){}int noop3840(){}int noop3841(){}int noop3842(){}int noop3843(){}int noop3844(){}int noop3845(){}int noop3846(){}int noop3847(){}int noop3848(){}int noop3849(){}int noop3850(){}int noop3851(){}int noop3852(){}int noop3853(){}int noop3854(){}int noop3855(){}int noop3856(){}int noop3857(){}int noop3858(){}int noop3859(){}int noop3860(){}int noop3861(){}int noop3862(){}int noop3863(){}int noop3864(){}int noop3865(){}int noop3866(){}int noop3867(){}int noop3868(){}int noop3869(){}int noop3870(){}int noop3871(){}int noop3872(){}int noop3873(){}int noop3874(){}int noop3875(){}int noop3876(){}int noop3877(){}int noop3878(){}int noop3879(){}int noop3880(){}int noop3881(){}int noop3882(){}int noop3883(){}int noop3884(){}int noop3885(){}int noop3886(){}int noop3887(){}int noop3888(){}int noop3889(){}int noop3890(){}int noop3891(){}int noop3892(){}int noop3893(){}int noop3894(){}int noop3895(){}int noop3896(){}int noop3897(){}int noop3898(){}int noop3899(){}int noop3900(){}int noop3901(){}int noop3902(){}int noop3903(){}int noop3904(){}int noop3905(){}int noop3906(){}int noop3907(){}int noop3908(){}int noop3909(){}int noop3910(){}int noop3911(){}int noop3912(){}int noop3913(){}int noop3914(){}int noop3915(){}int noop3916(){}int noop3917(){}int noop3918(){}int noop3919(){}int noop3920(){}int noop3921(){}int noop3922(){}int noop3923(){}int noop3924(){}int noop3925(){}int noop3926(){}int noop3927(){}int noop3928(){}int noop3929(){}int noop3930(){}int noop3931(){}int noop3932(){}int noop3933(){}int noop3934(){}int noop3935(){}int noop3936(){}int noop3937(){}int noop3938(){}int noop3939(){}int noop3940(){}int noop3941(){}int noop3942(){}int noop3943(){}int noop3944(){}int noop3945(){}int noop3946(){}int noop3947(){}int noop3948(){}int noop3949(){}int noop3950(){}int noop3951(){}int noop3952(){}int noop3953(){}int noop3954(){}int noop3955(){}int noop3956(){}int noop3957(){}int noop3958(){}int noop3959(){}int noop3960(){}int noop3961(){}int noop3962(){}int noop3963(){}int noop3964(){}int noop3965(){}int noop3966(){}int noop3967(){}int noop3968(){}int noop3969(){}int noop3970(){}int noop3971(){}int noop3972(){}int noop3973(){}int noop3974(){}int noop3975(){}int noop3976(){}int noop3977(){}int noop3978(){}int noop3979(){}int noop3980(){}int noop3981(){}int noop3982(){}int noop3983(){}int noop3984(){}int noop3985(){}int noop3986(){}int noop3987(){}int noop3988(){}int noop3989(){}int noop3990(){}int noop3991(){}int noop3992(){}int noop3993(){}int noop3994(){}int noop3995(){}int noop3996(){}int noop3997(){}int noop3998(){}int noop3999(){}int noop4000(){}int noop4001(){}int noop4002(){}int noop4003(){}int noop4004(){}int noop4005(){}int noop4006(){}int noop4007(){}int noop4008(){}int noop4009(){}int noop4010(){}int noop4011(){}int noop4012(){}int noop4013(){}int noop4014(){}int noop4015(){}int noop4016(){}int noop4017(){}int noop4018(){}int noop4019(){}int noop4020(){}int noop4021(){}int noop4022(){}int noop4023(){}int noop4024(){}int noop4025(){}int noop4026(){}int noop4027(){}int noop4028(){}int noop4029(){}int noop4030(){}int noop4031(){}int noop4032(){}int noop4033(){}int noop4034(){}int noop4035(){}int noop4036(){}int noop4037(){}int noop4038(){}int noop4039(){}int noop4040(){}int noop4041(){}int noop4042(){}int noop4043(){}int noop4044(){}int noop4045(){}int noop4046(){}int noop4047(){}int noop4048(){}int noop4049(){}int noop4050(){}int noop4051(){}int noop4052(){}int noop4053(){}int noop4054(){}int noop4055(){}int noop4056(){}int noop4057(){}int noop4058(){}int noop4059(){}int noop4060(){}int noop4061(){}int noop4062(){}int noop4063(){}int noop4064(){}int noop4065(){}int noop4066(){}int noop4067(){}int noop4068(){}int noop4069(){}int noop4070(){}int noop4071(){}int noop4072(){}int noop4073(){}int noop4074(){}int noop4075(){}int noop4076(){}int noop4077(){}int noop4078(){}int noop4079(){}int noop4080(){}int noop4081(){}int noop4082(){}int noop4083(){}int noop4084(){}int noop4085(){}int noop4086(){}int noop4087(){}int noop4088(){}int noop4089(){}int noop4090(){}int noop4091(){}int noop4092(){}int noop4093(){}int noop4094(){}int noop4095(){}int noop4096(){}int noop4097(){}int noop4098(){}int noop4099(){}int noop4100(){}int noop4101(){}int noop4102(){}int noop4103(){}int noop4104(){}int noop4105(){}int noop4106(){}int noop4107(){}int noop4108(){}int noop4109(){}int noop4110(){}int noop4111(){}int noop4112(){}int noop4113(){}int noop4114(){}int noop4115(){}int noop4116(){}int noop4117(){}int noop4118(){}int noop4119(){}int noop4120(){}int noop4121(){}int noop4122(){}int noop4123(){}int noop4124(){}int noop4125(){}int noop4126(){}int noop4127(){}int noop4128(){}int noop4129(){}int noop4130(){}int noop4131(){}int noop4132(){}int noop4133(){}int noop4134(){}int noop4135(){}int noop4136(){}int noop4137(){}int noop4138(){}int noop4139(){}int noop4140(){}int noop4141(){}int noop4142(){}int noop4143(){}int noop4144(){}int noop4145(){}int noop4146(){}int noop4147(){}int noop4148(){}int noop4149(){}int noop4150(){}int noop4151(){}int noop4152(){}int noop4153(){}int noop4154(){}int noop4155(){}int noop4156(){}int noop4157(){}int noop4158(){}int noop4159(){}int noop4160(){}int noop4161(){}int noop4162(){}int noop4163(){}int noop4164(){}int noop4165(){}int noop4166(){}int noop4167(){}int noop4168(){}int noop4169(){}int noop4170(){}int noop4171(){}int noop4172(){}int noop4173(){}int noop4174(){}int noop4175(){}int noop4176(){}int noop4177(){}int noop4178(){}int noop4179(){}int noop4180(){}int noop4181(){}int noop4182(){}int noop4183(){}int noop4184(){}int noop4185(){}int noop4186(){}int noop4187(){}int noop4188(){}int noop4189(){}int noop4190(){}int noop4191(){}int noop4192(){}int noop4193(){}int noop4194(){}int noop4195(){}int noop4196(){}int noop4197(){}int noop4198(){}int noop4199(){}int noop4200(){}int noop4201(){}int noop4202(){}int noop4203(){}int noop4204(){}int noop4205(){}int noop4206(){}int noop4207(){}int noop4208(){}int noop4209(){}int noop4210(){}int noop4211(){}int noop4212(){}int noop4213(){}int noop4214(){}int noop4215(){}int noop4216(){}int noop4217(){}int noop4218(){}int noop4219(){}int noop4220(){}int noop4221(){}int noop4222(){}int noop4223(){}int noop4224(){}int noop4225(){}int noop4226(){}int noop4227(){}int noop4228(){}int noop4229(){}int noop4230(){}int noop4231(){}int noop4232(){}int noop4233(){}int noop4234(){}int noop4235(){}int noop4236(){}int noop4237(){}int noop4238(){}int noop4239(){}int noop4240(){}int noop4241(){}int noop4242(){}int noop4243(){}int noop4244(){}int noop4245(){}int noop4246(){}int noop4247(){}int noop4248(){}int noop4249(){}int noop4250(){}int noop4251(){}int noop4252(){}int noop4253(){}int noop4254(){}int noop4255(){}int noop4256(){}int noop4257(){}int noop4258(){}int noop4259(){}int noop4260(){}int noop4261(){}int noop4262(){}int noop4263(){}int noop4264(){}int noop4265(){}int noop4266(){}int noop4267(){}int noop4268(){}int noop4269(){}int noop4270(){}int noop4271(){}int noop4272(){}int noop4273(){}int noop4274(){}int noop4275(){}int noop4276(){}int noop4277(){}int noop4278(){}int noop4279(){}int noop4280(){}int noop4281(){}int noop4282(){}int noop4283(){}int noop4284(){}int noop4285(){}int noop4286(){}int noop4287(){}int noop4288(){}int noop4289(){}int noop4290(){}int noop4291(){}int noop4292(){}int noop4293(){}int noop4294(){}int noop4295(){}int noop4296(){}int noop4297(){}int noop4298(){}int noop4299(){}int noop4300(){}int noop4301(){}int noop4302(){}int noop4303(){}int noop4304(){}int noop4305(){}int noop4306(){}int noop4307(){}int noop4308(){}int noop4309(){}int noop4310(){}int noop4311(){}int noop4312(){}int noop4313(){}int noop4314(){}int noop4315(){}int noop4316(){}int noop4317(){}int noop4318(){}int noop4319(){}int noop4320(){}int noop4321(){}int noop4322(){}int noop4323(){}int noop4324(){}int noop4325(){}int noop4326(){}int noop4327(){}int noop4328(){}int noop4329(){}int noop4330(){}int noop4331(){}int noop4332(){}int noop4333(){}int noop4334(){}int noop4335(){}int noop4336(){}int noop4337(){}int noop4338(){}int noop4339(){}int noop4340(){}int noop4341(){}int noop4342(){}int noop4343(){}int noop4344(){}int noop4345(){}int noop4346(){}int noop4347(){}int noop4348(){}int noop4349(){}int noop4350(){}int noop4351(){}int noop4352(){}int noop4353(){}int noop4354(){}int noop4355(){}int noop4356(){}int noop4357(){}int noop4358(){}int noop4359(){}int noop4360(){}int noop4361(){}int noop4362(){}int noop4363(){}int noop4364(){}int noop4365(){}int noop4366(){}int noop4367(){}int noop4368(){}int noop4369(){}int noop4370(){}int noop4371(){}int noop4372(){}int noop4373(){}int noop4374(){}int noop4375(){}int noop4376(){}int noop4377(){}int noop4378(){}int noop4379(){}int noop4380(){}int noop4381(){}int noop4382(){}int noop4383(){}int noop4384(){}int noop4385(){}int noop4386(){}int noop4387(){}int noop4388(){}int noop4389(){}int noop4390(){}int noop4391(){}int noop4392(){}int noop4393(){}int noop4394(){}int noop4395(){}int noop4396(){}int noop4397(){}int noop4398(){}int noop4399(){}int noop4400(){}int noop4401(){}int noop4402(){}int noop4403(){}int noop4404(){}int noop4405(){}int noop4406(){}int noop4407(){}int noop4408(){}int noop4409(){}int noop4410(){}int noop4411(){}int noop4412(){}int noop4413(){}int noop4414(){}int noop4415(){}int noop4416(){}int noop4417(){}int noop4418(){}int noop4419(){}int noop4420(){}int noop4421(){}int noop4422(){}int noop4423(){}int noop4424(){}int noop4425(){}int noop4426(){}int noop4427(){}int noop4428(){}int noop4429(){}int noop4430(){}int noop4431(){}int noop4432(){}int noop4433(){}int noop4434(){}int noop4435(){}int noop4436(){}int noop4437(){}int noop4438(){}int noop4439(){}int noop4440(){}int noop4441(){}int noop4442(){}int noop4443(){}int noop4444(){}int noop4445(){}int noop4446(){}int noop4447(){}int noop4448(){}int noop4449(){}int noop4450(){}int noop4451(){}int noop4452(){}int noop4453(){}int noop4454(){}int noop4455(){}int noop4456(){}int noop4457(){}int noop4458(){}int noop4459(){}int noop4460(){}int noop4461(){}int noop4462(){}int noop4463(){}int noop4464(){}int noop4465(){}int noop4466(){}int noop4467(){}int noop4468(){}int noop4469(){}int noop4470(){}int noop4471(){}int noop4472(){}int noop4473(){}int noop4474(){}int noop4475(){}int noop4476(){}int noop4477(){}int noop4478(){}int noop4479(){}int noop4480(){}int noop4481(){}int noop4482(){}int noop4483(){}int noop4484(){}int noop4485(){}int noop4486(){}int noop4487(){}int noop4488(){}int noop4489(){}int noop4490(){}int noop4491(){}int noop4492(){}int noop4493(){}int noop4494(){}int noop4495(){}int noop4496(){}int noop4497(){}int noop4498(){}int noop4499(){}int noop4500(){}int noop4501(){}int noop4502(){}int noop4503(){}int noop4504(){}int noop4505(){}int noop4506(){}int noop4507(){}int noop4508(){}int noop4509(){}int noop4510(){}int noop4511(){}int noop4512(){}int noop4513(){}int noop4514(){}int noop4515(){}int noop4516(){}int noop4517(){}int noop4518(){}int noop4519(){}int noop4520(){}int noop4521(){}int noop4522(){}int noop4523(){}int noop4524(){}int noop4525(){}int noop4526(){}int noop4527(){}int noop4528(){}int noop4529(){}int noop4530(){}int noop4531(){}int noop4532(){}int noop4533(){}int noop4534(){}int noop4535(){}int noop4536(){}int noop4537(){}int noop4538(){}int noop4539(){}int noop4540(){}int noop4541(){}int noop4542(){}int noop4543(){}int noop4544(){}int noop4545(){}int noop4546(){}int noop4547(){}int noop4548(){}int noop4549(){}int noop4550(){}int noop4551(){}int noop4552(){}int noop4553(){}int noop4554(){}int noop4555(){}int noop4556(){}int noop4557(){}int noop4558(){}int noop4559(){}int noop4560(){}int noop4561(){}int noop4562(){}int noop4563(){}int noop4564(){}int noop4565(){}int noop4566(){}int noop4567(){}int noop4568(){}int noop4569(){}int noop4570(){}int noop4571(){}int noop4572(){}int noop4573(){}int noop4574(){}int noop4575(){}int noop4576(){}int noop4577(){}int noop4578(){}int noop4579(){}int noop4580(){}int noop4581(){}int noop4582(){}int noop4583(){}int noop4584(){}int noop4585(){}int noop4586(){}int noop4587(){}int noop4588(){}int noop4589(){}int noop4590(){}int noop4591(){}int noop4592(){}int noop4593(){}int noop4594(){}int noop4595(){}int noop4596(){}int noop4597(){}int noop4598(){}int noop4599(){}int noop4600(){}int noop4601(){}int noop4602(){}int noop4603(){}int noop4604(){}int noop4605(){}int noop4606(){}int noop4607(){}int noop4608(){}int noop4609(){}int noop4610(){}int noop4611(){}int noop4612(){}int noop4613(){}int noop4614(){}int noop4615(){}int noop4616(){}int noop4617(){}int noop4618(){}int noop4619(){}int noop4620(){}int noop4621(){}int noop4622(){}int noop4623(){}int noop4624(){}int noop4625(){}int noop4626(){}int noop4627(){}int noop4628(){}int noop4629(){}int noop4630(){}int noop4631(){}int noop4632(){}int noop4633(){}int noop4634(){}int noop4635(){}int noop4636(){}int noop4637(){}int noop4638(){}int noop4639(){}int noop4640(){}int noop4641(){}int noop4642(){}int noop4643(){}int noop4644(){}int noop4645(){}int noop4646(){}int noop4647(){}int noop4648(){}int noop4649(){}int noop4650(){}int noop4651(){}int noop4652(){}int noop4653(){}int noop4654(){}int noop4655(){}int noop4656(){}int noop4657(){}int noop4658(){}int noop4659(){}int noop4660(){}int noop4661(){}int noop4662(){}int noop4663(){}int noop4664(){}int noop4665(){}int noop4666(){}int noop4667(){}int noop4668(){}int noop4669(){}int noop4670(){}int noop4671(){}int noop4672(){}int noop4673(){}int noop4674(){}int noop4675(){}int noop4676(){}int noop4677(){}int noop4678(){}int noop4679(){}int noop4680(){}int noop4681(){}int noop4682(){}int noop4683(){}int noop4684(){}int noop4685(){}int noop4686(){}int noop4687(){}int noop4688(){}int noop4689(){}int noop4690(){}int noop4691(){}int noop4692(){}int noop4693(){}int noop4694(){}int noop4695(){}int noop4696(){}int noop4697(){}int noop4698(){}int noop4699(){}int noop4700(){}int noop4701(){}int noop4702(){}int noop4703(){}int noop4704(){}int noop4705(){}int noop4706(){}int noop4707(){}int noop4708(){}int noop4709(){}int noop4710(){}int noop4711(){}int noop4712(){}int noop4713(){}int noop4714(){}int noop4715(){}int noop4716(){}int noop4717(){}int noop4718(){}int noop4719(){}int noop4720(){}int noop4721(){}int noop4722(){}int noop4723(){}int noop4724(){}int noop4725(){}int noop4726(){}int noop4727(){}int noop4728(){}int noop4729(){}int noop4730(){}int noop4731(){}int noop4732(){}int noop4733(){}int noop4734(){}int noop4735(){}int noop4736(){}int noop4737(){}int noop4738(){}int noop4739(){}int noop4740(){}int noop4741(){}int noop4742(){}int noop4743(){}int noop4744(){}int noop4745(){}int noop4746(){}int noop4747(){}int noop4748(){}int noop4749(){}int noop4750(){}int noop4751(){}int noop4752(){}int noop4753(){}int noop4754(){}int noop4755(){}int noop4756(){}int noop4757(){}int noop4758(){}int noop4759(){}int noop4760(){}int noop4761(){}int noop4762(){}int noop4763(){}int noop4764(){}int noop4765(){}int noop4766(){}int noop4767(){}int noop4768(){}int noop4769(){}int noop4770(){}int noop4771(){}int noop4772(){}int noop4773(){}int noop4774(){}int noop4775(){}int noop4776(){}int noop4777(){}int noop4778(){}int noop4779(){}int noop4780(){}int noop4781(){}int noop4782(){}int noop4783(){}int noop4784(){}int noop4785(){}int noop4786(){}int noop4787(){}int noop4788(){}int noop4789(){}int noop4790(){}int noop4791(){}int noop4792(){}int noop4793(){}int noop4794(){}int noop4795(){}int noop4796(){}int noop4797(){}int noop4798(){}int noop4799(){}int noop4800(){}int noop4801(){}int noop4802(){}int noop4803(){}int noop4804(){}int noop4805(){}int noop4806(){}int noop4807(){}int noop4808(){}int noop4809(){}int noop4810(){}int noop4811(){}int noop4812(){}int noop4813(){}int noop4814(){}int noop4815(){}int noop4816(){}int noop4817(){}int noop4818(){}int noop4819(){}int noop4820(){}int noop4821(){}int noop4822(){}int noop4823(){}int noop4824(){}int noop4825(){}int noop4826(){}int noop4827(){}int noop4828(){}int noop4829(){}int noop4830(){}int noop4831(){}int noop4832(){}int noop4833(){}int noop4834(){}int noop4835(){}int noop4836(){}int noop4837(){}int noop4838(){}int noop4839(){}int noop4840(){}int noop4841(){}int noop4842(){}int noop4843(){}int noop4844(){}int noop4845(){}int noop4846(){}int noop4847(){}int noop4848(){}int noop4849(){}int noop4850(){}int noop4851(){}int noop4852(){}int noop4853(){}int noop4854(){}int noop4855(){}int noop4856(){}int noop4857(){}int noop4858(){}int noop4859(){}int noop4860(){}int noop4861(){}int noop4862(){}int noop4863(){}int noop4864(){}int noop4865(){}int noop4866(){}int noop4867(){}int noop4868(){}int noop4869(){}int noop4870(){}int noop4871(){}int noop4872(){}int noop4873(){}int noop4874(){}int noop4875(){}int noop4876(){}int noop4877(){}int noop4878(){}int noop4879(){}int noop4880(){}int noop4881(){}int noop4882(){}int noop4883(){}int noop4884(){}int noop4885(){}int noop4886(){}int noop4887(){}int noop4888(){}int noop4889(){}int noop4890(){}int noop4891(){}int noop4892(){}int noop4893(){}int noop4894(){}int noop4895(){}int noop4896(){}int noop4897(){}int noop4898(){}int noop4899(){}int noop4900(){}int noop4901(){}int noop4902(){}int noop4903(){}int noop4904(){}int noop4905(){}int noop4906(){}int noop4907(){}int noop4908(){}int noop4909(){}int noop4910(){}int noop4911(){}int noop4912(){}int noop4913(){}int noop4914(){}int noop4915(){}int noop4916(){}int noop4917(){}int noop4918(){}int noop4919(){}int noop4920(){}int noop4921(){}int noop4922(){}int noop4923(){}int noop4924(){}int noop4925(){}int noop4926(){}int noop4927(){}int noop4928(){}int noop4929(){}int noop4930(){}int noop4931(){}int noop4932(){}int noop4933(){}int noop4934(){}int noop4935(){}int noop4936(){}int noop4937(){}int noop4938(){}int noop4939(){}int noop4940(){}int noop4941(){}int noop4942(){}int noop4943(){}int noop4944(){}int noop4945(){}int noop4946(){}int noop4947(){}int noop4948(){}int noop4949(){}int noop4950(){}int noop4951(){}int noop4952(){}int noop4953(){}int noop4954(){}int noop4955(){}int noop4956(){}int noop4957(){}int noop4958(){}int noop4959(){}int noop4960(){}int noop4961(){}int noop4962(){}int noop4963(){}int noop4964(){}int noop4965(){}int noop4966(){}int noop4967(){}int noop4968(){}int noop4969(){}int noop4970(){}int noop4971(){}int noop4972(){}int noop4973(){}int noop4974(){}int noop4975(){}int noop4976(){}int noop4977(){}int noop4978(){}int noop4979(){}int noop4980(){}int noop4981(){}int noop4982(){}int noop4983(){}int noop4984(){}int noop4985(){}int noop4986(){}int noop4987(){}int noop4988(){}int noop4989(){}int noop4990(){}int noop4991(){}int noop4992(){}int noop4993(){}int noop4994(){}int noop4995(){}int noop4996(){}int noop4997(){}int noop4998(){}int noop4999(){}int noop5000(){}int noop5001(){}int noop5002(){}int noop5003(){}int noop5004(){}int noop5005(){}int noop5006(){}int noop5007(){}int noop5008(){}int noop5009(){}int noop5010(){}int noop5011(){}int noop5012(){}int noop5013(){}int noop5014(){}int noop5015(){}int noop5016(){}int noop5017(){}int noop5018(){}int noop5019(){}int noop5020(){}int noop5021(){}int noop5022(){}int noop5023(){}int noop5024(){}int noop5025(){}int noop5026(){}int noop5027(){}int noop5028(){}int noop5029(){}int noop5030(){}int noop5031(){}int noop5032(){}int noop5033(){}int noop5034(){}int noop5035(){}int noop5036(){}int noop5037(){}int noop5038(){}int noop5039(){}int noop5040(){}int noop5041(){}int noop5042(){}int noop5043(){}int noop5044(){}int noop5045(){}int noop5046(){}int noop5047(){}int noop5048(){}int noop5049(){}int noop5050(){}int noop5051(){}int noop5052(){}int noop5053(){}int noop5054(){}int noop5055(){}int noop5056(){}int noop5057(){}int noop5058(){}int noop5059(){}int noop5060(){}int noop5061(){}int noop5062(){}int noop5063(){}int noop5064(){}int noop5065(){}int noop5066(){}int noop5067(){}int noop5068(){}int noop5069(){}int noop5070(){}int noop5071(){}int noop5072(){}int noop5073(){}int noop5074(){}int noop5075(){}int noop5076(){}int noop5077(){}int noop5078(){}int noop5079(){}int noop5080(){}int noop5081(){}int noop5082(){}int noop5083(){}int noop5084(){}int noop5085(){}int noop5086(){}int noop5087(){}int noop5088(){}int noop5089(){}int noop5090(){}int noop5091(){}int noop5092(){}int noop5093(){}int noop5094(){}int noop5095(){}int noop5096(){}int noop5097(){}int noop5098(){}int noop5099(){}int noop5100(){}int noop5101(){}int noop5102(){}int noop5103(){}int noop5104(){}int noop5105(){}int noop5106(){}int noop5107(){}int noop5108(){}int noop5109(){}int noop5110(){}int noop5111(){}int noop5112(){}int noop5113(){}int noop5114(){}int noop5115(){}int noop5116(){}int noop5117(){}int noop5118(){}int noop5119(){}int noop5120(){}int noop5121(){}int noop5122(){}int noop5123(){}int noop5124(){}int noop5125(){}int noop5126(){}int noop5127(){}int noop5128(){}int noop5129(){}int noop5130(){}int noop5131(){}int noop5132(){}int noop5133(){}int noop5134(){}int noop5135(){}int noop5136(){}int noop5137(){}int noop5138(){}int noop5139(){}int noop5140(){}int noop5141(){}int noop5142(){}int noop5143(){}int noop5144(){}int noop5145(){}int noop5146(){}int noop5147(){}int noop5148(){}int noop5149(){}int noop5150(){}int noop5151(){}int noop5152(){}int noop5153(){}int noop5154(){}int noop5155(){}int noop5156(){}int noop5157(){}int noop5158(){}int noop5159(){}int noop5160(){}int noop5161(){}int noop5162(){}int noop5163(){}int noop5164(){}int noop5165(){}int noop5166(){}int noop5167(){}int noop5168(){}int noop5169(){}int noop5170(){}int noop5171(){}int noop5172(){}int noop5173(){}int noop5174(){}int noop5175(){}int noop5176(){}int noop5177(){}int noop5178(){}int noop5179(){}int noop5180(){}int noop5181(){}int noop5182(){}int noop5183(){}int noop5184(){}int noop5185(){}int noop5186(){}int noop5187(){}int noop5188(){}int noop5189(){}int noop5190(){}int noop5191(){}int noop5192(){}int noop5193(){}int noop5194(){}int noop5195(){}int noop5196(){}int noop5197(){}int noop5198(){}int noop5199(){}int noop5200(){}int noop5201(){}int noop5202(){}int noop5203(){}int noop5204(){}int noop5205(){}int noop5206(){}int noop5207(){}int noop5208(){}int noop5209(){}int noop5210(){}int noop5211(){}int noop5212(){}int noop5213(){}int noop5214(){}int noop5215(){}int noop5216(){}int noop5217(){}int noop5218(){}int noop5219(){}int noop5220(){}int noop5221(){}int noop5222(){}int noop5223(){}int noop5224(){}int noop5225(){}int noop5226(){}int noop5227(){}int noop5228(){}int noop5229(){}int noop5230(){}int noop5231(){}int noop5232(){}int noop5233(){}int noop5234(){}int noop5235(){}int noop5236(){}int noop5237(){}int noop5238(){}int noop5239(){}int noop5240(){}int noop5241(){}int noop5242(){}int noop5243(){}int noop5244(){}int noop5245(){}int noop5246(){}int noop5247(){}int noop5248(){}int noop5249(){}int noop5250(){}int noop5251(){}int noop5252(){}int noop5253(){}int noop5254(){}int noop5255(){}int noop5256(){}int noop5257(){}int noop5258(){}int noop5259(){}int noop5260(){}int noop5261(){}int noop5262(){}int noop5263(){}int noop5264(){}int noop5265(){}int noop5266(){}int noop5267(){}int noop5268(){}int noop5269(){}int noop5270(){}int noop5271(){}int noop5272(){}int noop5273(){}int noop5274(){}int noop5275(){}int noop5276(){}int noop5277(){}int noop5278(){}int noop5279(){}int noop5280(){}int noop5281(){}int noop5282(){}int noop5283(){}int noop5284(){}int noop5285(){}int noop5286(){}int noop5287(){}int noop5288(){}int noop5289(){}int noop5290(){}int noop5291(){}int noop5292(){}int noop5293(){}int noop5294(){}int noop5295(){}int noop5296(){}int noop5297(){}int noop5298(){}int noop5299(){}int noop5300(){}int noop5301(){}int noop5302(){}int noop5303(){}int noop5304(){}int noop5305(){}int noop5306(){}int noop5307(){}int noop5308(){}int noop5309(){}int noop5310(){}int noop5311(){}int noop5312(){}int noop5313(){}int noop5314(){}int noop5315(){}int noop5316(){}int noop5317(){}int noop5318(){}int noop5319(){}int noop5320(){}int noop5321(){}int noop5322(){}int noop5323(){}int noop5324(){}int noop5325(){}int noop5326(){}int noop5327(){}int noop5328(){}int noop5329(){}int noop5330(){}int noop5331(){}int noop5332(){}int noop5333(){}int noop5334(){}int noop5335(){}int noop5336(){}int noop5337(){}int noop5338(){}int noop5339(){}int noop5340(){}int noop5341(){}int noop5342(){}int noop5343(){}int noop5344(){}int noop5345(){}int noop5346(){}int noop5347(){}int noop5348(){}int noop5349(){}int noop5350(){}int noop5351(){}int noop5352(){}int noop5353(){}int noop5354(){}int noop5355(){}int noop5356(){}int noop5357(){}int noop5358(){}int noop5359(){}int noop5360(){}int noop5361(){}int noop5362(){}int noop5363(){}int noop5364(){}int noop5365(){}int noop5366(){}int noop5367(){}int noop5368(){}int noop5369(){}int noop5370(){}int noop5371(){}int noop5372(){}int noop5373(){}int noop5374(){}int noop5375(){}int noop5376(){}int noop5377(){}int noop5378(){}int noop5379(){}int noop5380(){}int noop5381(){}int noop5382(){}int noop5383(){}int noop5384(){}int noop5385(){}int noop5386(){}int noop5387(){}int noop5388(){}int noop5389(){}int noop5390(){}int noop5391(){}int noop5392(){}int noop5393(){}int noop5394(){}int noop5395(){}int noop5396(){}int noop5397(){}int noop5398(){}int noop5399(){}int noop5400(){}int noop5401(){}int noop5402(){}int noop5403(){}int noop5404(){}int noop5405(){}int noop5406(){}int noop5407(){}int noop5408(){}int noop5409(){}int noop5410(){}int noop5411(){}int noop5412(){}int noop5413(){}int noop5414(){}int noop5415(){}int noop5416(){}int noop5417(){}int noop5418(){}int noop5419(){}int noop5420(){}int noop5421(){}int noop5422(){}int noop5423(){}int noop5424(){}int noop5425(){}int noop5426(){}int noop5427(){}int noop5428(){}int noop5429(){}int noop5430(){}int noop5431(){}int noop5432(){}int noop5433(){}int noop5434(){}int noop5435(){}int noop5436(){}int noop5437(){}int noop5438(){}int noop5439(){}int noop5440(){}int noop5441(){}int noop5442(){}int noop5443(){}int noop5444(){}int noop5445(){}int noop5446(){}int noop5447(){}int noop5448(){}int noop5449(){}int noop5450(){}int noop5451(){}int noop5452(){}int noop5453(){}int noop5454(){}int noop5455(){}int noop5456(){}int noop5457(){}int noop5458(){}int noop5459(){}int noop5460(){}int noop5461(){}int noop5462(){}int noop5463(){}int noop5464(){}int noop5465(){}int noop5466(){}int noop5467(){}int noop5468(){}int noop5469(){}int noop5470(){}int noop5471(){}int noop5472(){}int noop5473(){}int noop5474(){}int noop5475(){}int noop5476(){}int noop5477(){}int noop5478(){}int noop5479(){}int noop5480(){}int noop5481(){}int noop5482(){}int noop5483(){}int noop5484(){}int noop5485(){}int noop5486(){}int noop5487(){}int noop5488(){}int noop5489(){}int noop5490(){}int noop5491(){}int noop5492(){}int noop5493(){}int noop5494(){}int noop5495(){}int noop5496(){}int noop5497(){}int noop5498(){}int noop5499(){}int noop5500(){}int noop5501(){}int noop5502(){}int noop5503(){}int noop5504(){}int noop5505(){}int noop5506(){}int noop5507(){}int noop5508(){}int noop5509(){}int noop5510(){}int noop5511(){}int noop5512(){}int noop5513(){}int noop5514(){}int noop5515(){}int noop5516(){}int noop5517(){}int noop5518(){}int noop5519(){}int noop5520(){}int noop5521(){}int noop5522(){}int noop5523(){}int noop5524(){}int noop5525(){}int noop5526(){}int noop5527(){}int noop5528(){}int noop5529(){}int noop5530(){}int noop5531(){}int noop5532(){}int noop5533(){}int noop5534(){}int noop5535(){}int noop5536(){}int noop5537(){}int noop5538(){}int noop5539(){}int noop5540(){}int noop5541(){}int noop5542(){}int noop5543(){}int noop5544(){}int noop5545(){}int noop5546(){}int noop5547(){}int noop5548(){}int noop5549(){}int noop5550(){}int noop5551(){}int noop5552(){}int noop5553(){}int noop5554(){}int noop5555(){}int noop5556(){}int noop5557(){}int noop5558(){}int noop5559(){}int noop5560(){}int noop5561(){}int noop5562(){}int noop5563(){}int noop5564(){}int noop5565(){}int noop5566(){}int noop5567(){}int noop5568(){}int noop5569(){}int noop5570(){}int noop5571(){}int noop5572(){}int noop5573(){}int noop5574(){}int noop5575(){}int noop5576(){}int noop5577(){}int noop5578(){}int noop5579(){}int noop5580(){}int noop5581(){}int noop5582(){}int noop5583(){}int noop5584(){}int noop5585(){}int noop5586(){}int noop5587(){}int noop5588(){}int noop5589(){}int noop5590(){}int noop5591(){}int noop5592(){}int noop5593(){}int noop5594(){}int noop5595(){}int noop5596(){}int noop5597(){}int noop5598(){}int noop5599(){}int noop5600(){}int noop5601(){}int noop5602(){}int noop5603(){}int noop5604(){}int noop5605(){}int noop5606(){}int noop5607(){}int noop5608(){}int noop5609(){}int noop5610(){}int noop5611(){}int noop5612(){}int noop5613(){}int noop5614(){}int noop5615(){}int noop5616(){}int noop5617(){}int noop5618(){}int noop5619(){}int noop5620(){}int noop5621(){}int noop5622(){}int noop5623(){}int noop5624(){}int noop5625(){}int noop5626(){}int noop5627(){}int noop5628(){}int noop5629(){}int noop5630(){}int noop5631(){}int noop5632(){}int noop5633(){}int noop5634(){}int noop5635(){}int noop5636(){}int noop5637(){}int noop5638(){}int noop5639(){}int noop5640(){}int noop5641(){}int noop5642(){}int noop5643(){}int noop5644(){}int noop5645(){}int noop5646(){}int noop5647(){}int noop5648(){}int noop5649(){}int noop5650(){}int noop5651(){}int noop5652(){}int noop5653(){}int noop5654(){}int noop5655(){}int noop5656(){}int noop5657(){}int noop5658(){}int noop5659(){}int noop5660(){}int noop5661(){}int noop5662(){}int noop5663(){}int noop5664(){}int noop5665(){}int noop5666(){}int noop5667(){}int noop5668(){}int noop5669(){}int noop5670(){}int noop5671(){}int noop5672(){}int noop5673(){}int noop5674(){}int noop5675(){}int noop5676(){}int noop5677(){}int noop5678(){}int noop5679(){}int noop5680(){}int noop5681(){}int noop5682(){}int noop5683(){}int noop5684(){}int noop5685(){}int noop5686(){}int noop5687(){}int noop5688(){}int noop5689(){}int noop5690(){}int noop5691(){}int noop5692(){}int noop5693(){}int noop5694(){}int noop5695(){}int noop5696(){}int noop5697(){}int noop5698(){}int noop5699(){}int noop5700(){}int noop5701(){}int noop5702(){}int noop5703(){}int noop5704(){}int noop5705(){}int noop5706(){}int noop5707(){}int noop5708(){}int noop5709(){}int noop5710(){}int noop5711(){}int noop5712(){}int noop5713(){}int noop5714(){}int noop5715(){}int noop5716(){}int noop5717(){}int noop5718(){}int noop5719(){}int noop5720(){}int noop5721(){}int noop5722(){}int noop5723(){}int noop5724(){}int noop5725(){}int noop5726(){}int noop5727(){}int noop5728(){}int noop5729(){}int noop5730(){}int noop5731(){}int noop5732(){}int noop5733(){}int noop5734(){}int noop5735(){}int noop5736(){}int noop5737(){}int noop5738(){}int noop5739(){}int noop5740(){}int noop5741(){}int noop5742(){}int noop5743(){}int noop5744(){}int noop5745(){}int noop5746(){}int noop5747(){}int noop5748(){}int noop5749(){}int noop5750(){}int noop5751(){}int noop5752(){}int noop5753(){}int noop5754(){}int noop5755(){}int noop5756(){}int noop5757(){}int noop5758(){}int noop5759(){}int noop5760(){}int noop5761(){}int noop5762(){}int noop5763(){}int noop5764(){}int noop5765(){}int noop5766(){}int noop5767(){}int noop5768(){}int noop5769(){}int noop5770(){}int noop5771(){}int noop5772(){}int noop5773(){}int noop5774(){}int noop5775(){}int noop5776(){}int noop5777(){}int noop5778(){}int noop5779(){}int noop5780(){}int noop5781(){}int noop5782(){}int noop5783(){}int noop5784(){}int noop5785(){}int noop5786(){}int noop5787(){}int noop5788(){}int noop5789(){}int noop5790(){}int noop5791(){}int noop5792(){}int noop5793(){}int noop5794(){}int noop5795(){}int noop5796(){}int noop5797(){}int noop5798(){}int noop5799(){}int noop5800(){}int noop5801(){}int noop5802(){}int noop5803(){}int noop5804(){}int noop5805(){}int noop5806(){}int noop5807(){}int noop5808(){}int noop5809(){}int noop5810(){}int noop5811(){}int noop5812(){}int noop5813(){}int noop5814(){}int noop5815(){}int noop5816(){}int noop5817(){}int noop5818(){}int noop5819(){}int noop5820(){}int noop5821(){}int noop5822(){}int noop5823(){}int noop5824(){}int noop5825(){}int noop5826(){}int noop5827(){}int noop5828(){}int noop5829(){}int noop5830(){}int noop5831(){}int noop5832(){}int noop5833(){}int noop5834(){}int noop5835(){}int noop5836(){}int noop5837(){}int noop5838(){}int noop5839(){}int noop5840(){}int noop5841(){}int noop5842(){}int noop5843(){}int noop5844(){}int noop5845(){}int noop5846(){}int noop5847(){}int noop5848(){}int noop5849(){}int noop5850(){}int noop5851(){}int noop5852(){}int noop5853(){}int noop5854(){}int noop5855(){}int noop5856(){}int noop5857(){}int noop5858(){}int noop5859(){}int noop5860(){}int noop5861(){}int noop5862(){}int noop5863(){}int noop5864(){}int noop5865(){}int noop5866(){}int noop5867(){}int noop5868(){}int noop5869(){}int noop5870(){}int noop5871(){}int noop5872(){}int noop5873(){}int noop5874(){}int noop5875(){}int noop5876(){}int noop5877(){}int noop5878(){}int noop5879(){}int noop5880(){}int noop5881(){}int noop5882(){}int noop5883(){}int noop5884(){}int noop5885(){}int noop5886(){}int noop5887(){}int noop5888(){}int noop5889(){}int noop5890(){}int noop5891(){}int noop5892(){}int noop5893(){}int noop5894(){}int noop5895(){}int noop5896(){}int noop5897(){}int noop5898(){}int noop5899(){}int noop5900(){}int noop5901(){}int noop5902(){}int noop5903(){}int noop5904(){}int noop5905(){}int noop5906(){}int noop5907(){}int noop5908(){}int noop5909(){}int noop5910(){}int noop5911(){}int noop5912(){}int noop5913(){}int noop5914(){}int noop5915(){}int noop5916(){}int noop5917(){}int noop5918(){}int noop5919(){}int noop5920(){}int noop5921(){}int noop5922(){}int noop5923(){}int noop5924(){}int noop5925(){}int noop5926(){}int noop5927(){}int noop5928(){}int noop5929(){}int noop5930(){}int noop5931(){}int noop5932(){}int noop5933(){}int noop5934(){}int noop5935(){}int noop5936(){}int noop5937(){}int noop5938(){}int noop5939(){}int noop5940(){}int noop5941(){}int noop5942(){}int noop5943(){}int noop5944(){}int noop5945(){}int noop5946(){}int noop5947(){}int noop5948(){}int noop5949(){}int noop5950(){}int noop5951(){}int noop5952(){}int noop5953(){}int noop5954(){}int noop5955(){}int noop5956(){}int noop5957(){}int noop5958(){}int noop5959(){}int noop5960(){}int noop5961(){}int noop5962(){}int noop5963(){}int noop5964(){}int noop5965(){}int noop5966(){}int noop5967(){}int noop5968(){}int noop5969(){}int noop5970(){}int noop5971(){}int noop5972(){}int noop5973(){}int noop5974(){}int noop5975(){}int noop5976(){}int noop5977(){}int noop5978(){}int noop5979(){}int noop5980(){}int noop5981(){}int noop5982(){}int noop5983(){}int noop5984(){}int noop5985(){}int noop5986(){}int noop5987(){}int noop5988(){}int noop5989(){}int noop5990(){}int noop5991(){}int noop5992(){}int noop5993(){}int noop5994(){}int noop5995(){}int noop5996(){}int noop5997(){}int noop5998(){}int noop5999(){}int noop6000(){}int noop6001(){}int noop6002(){}int noop6003(){}int noop6004(){}int noop6005(){}int noop6006(){}int noop6007(){}int noop6008(){}int noop6009(){}int noop6010(){}int noop6011(){}int noop6012(){}int noop6013(){}int noop6014(){}int noop6015(){}int noop6016(){}int noop6017(){}int noop6018(){}int noop6019(){}int noop6020(){}int noop6021(){}int noop6022(){}int noop6023(){}int noop6024(){}int noop6025(){}int noop6026(){}int noop6027(){}int noop6028(){}int noop6029(){}int noop6030(){}int noop6031(){}int noop6032(){}int noop6033(){}int noop6034(){}int noop6035(){}int noop6036(){}int noop6037(){}int noop6038(){}int noop6039(){}int noop6040(){}int noop6041(){}int noop6042(){}int noop6043(){}int noop6044(){}int noop6045(){}int noop6046(){}int noop6047(){}int noop6048(){}int noop6049(){}int noop6050(){}int noop6051(){}int noop6052(){}int noop6053(){}int noop6054(){}int noop6055(){}int noop6056(){}int noop6057(){}int noop6058(){}int noop6059(){}int noop6060(){}int noop6061(){}int noop6062(){}int noop6063(){}int noop6064(){}int noop6065(){}int noop6066(){}int noop6067(){}int noop6068(){}int noop6069(){}int noop6070(){}int noop6071(){}int noop6072(){}int noop6073(){}int noop6074(){}int noop6075(){}int noop6076(){}int noop6077(){}int noop6078(){}int noop6079(){}int noop6080(){}int noop6081(){}int noop6082(){}int noop6083(){}int noop6084(){}int noop6085(){}int noop6086(){}int noop6087(){}int noop6088(){}int noop6089(){}int noop6090(){}int noop6091(){}int noop6092(){}int noop6093(){}int noop6094(){}int noop6095(){}int noop6096(){}int noop6097(){}int noop6098(){}int noop6099(){}int noop6100(){}int noop6101(){}int noop6102(){}int noop6103(){}int noop6104(){}int noop6105(){}int noop6106(){}int noop6107(){}int noop6108(){}int noop6109(){}int noop6110(){}int noop6111(){}int noop6112(){}int noop6113(){}int noop6114(){}int noop6115(){}int noop6116(){}int noop6117(){}int noop6118(){}int noop6119(){}int noop6120(){}int noop6121(){}int noop6122(){}int noop6123(){}int noop6124(){}int noop6125(){}int noop6126(){}int noop6127(){}int noop6128(){}int noop6129(){}int noop6130(){}int noop6131(){}int noop6132(){}int noop6133(){}int noop6134(){}int noop6135(){}int noop6136(){}int noop6137(){}int noop6138(){}int noop6139(){}int noop6140(){}int noop6141(){}int noop6142(){}int noop6143(){}int noop6144(){}int noop6145(){}int noop6146(){}int noop6147(){}int noop6148(){}int noop6149(){}int noop6150(){}int noop6151(){}int noop6152(){}int noop6153(){}int noop6154(){}int noop6155(){}int noop6156(){}int noop6157(){}int noop6158(){}int noop6159(){}int noop6160(){}int noop6161(){}int noop6162(){}int noop6163(){}int noop6164(){}int noop6165(){}int noop6166(){}int noop6167(){}int noop6168(){}int noop6169(){}int noop6170(){}int noop6171(){}int noop6172(){}int noop6173(){}int noop6174(){}int noop6175(){}int noop6176(){}int noop6177(){}int noop6178(){}int noop6179(){}int noop6180(){}int noop6181(){}int noop6182(){}int noop6183(){}int noop6184(){}int noop6185(){}int noop6186(){}int noop6187(){}int noop6188(){}int noop6189(){}int noop6190(){}int noop6191(){}int noop6192(){}int noop6193(){}int noop6194(){}int noop6195(){}int noop6196(){}int noop6197(){}int noop6198(){}int noop6199(){}int noop6200(){}int noop6201(){}int noop6202(){}int noop6203(){}int noop6204(){}int noop6205(){}int noop6206(){}int noop6207(){}int noop6208(){}int noop6209(){}int noop6210(){}int noop6211(){}int noop6212(){}int noop6213(){}int noop6214(){}int noop6215(){}int noop6216(){}int noop6217(){}int noop6218(){}int noop6219(){}int noop6220(){}int noop6221(){}int noop6222(){}int noop6223(){}int noop6224(){}int noop6225(){}int noop6226(){}int noop6227(){}int noop6228(){}int noop6229(){}int noop6230(){}int noop6231(){}int noop6232(){}int noop6233(){}int noop6234(){}int noop6235(){}int noop6236(){}int noop6237(){}int noop6238(){}int noop6239(){}int noop6240(){}int noop6241(){}int noop6242(){}int noop6243(){}int noop6244(){}int noop6245(){}int noop6246(){}int noop6247(){}int noop6248(){}int noop6249(){}int noop6250(){}int noop6251(){}int noop6252(){}int noop6253(){}int noop6254(){}int noop6255(){}int noop6256(){}int noop6257(){}int noop6258(){}int noop6259(){}int noop6260(){}int noop6261(){}int noop6262(){}int noop6263(){}int noop6264(){}int noop6265(){}int noop6266(){}int noop6267(){}int noop6268(){}int noop6269(){}int noop6270(){}int noop6271(){}int noop6272(){}int noop6273(){}int noop6274(){}int noop6275(){}int noop6276(){}int noop6277(){}int noop6278(){}int noop6279(){}int noop6280(){}int noop6281(){}int noop6282(){}int noop6283(){}int noop6284(){}int noop6285(){}int noop6286(){}int noop6287(){}int noop6288(){}int noop6289(){}int noop6290(){}int noop6291(){}int noop6292(){}int noop6293(){}int noop6294(){}int noop6295(){}int noop6296(){}int noop6297(){}int noop6298(){}int noop6299(){}int noop6300(){}int noop6301(){}int noop6302(){}int noop6303(){}int noop6304(){}int noop6305(){}int noop6306(){}int noop6307(){}int noop6308(){}int noop6309(){}int noop6310(){}int noop6311(){}int noop6312(){}int noop6313(){}int noop6314(){}int noop6315(){}int noop6316(){}int noop6317(){}int noop6318(){}int noop6319(){}int noop6320(){}int noop6321(){}int noop6322(){}int noop6323(){}int noop6324(){}int noop6325(){}int noop6326(){}int noop6327(){}int noop6328(){}int noop6329(){}int noop6330(){}int noop6331(){}int noop6332(){}int noop6333(){}int noop6334(){}int noop6335(){}int noop6336(){}int noop6337(){}int noop6338(){}int noop6339(){}int noop6340(){}int noop6341(){}int noop6342(){}int noop6343(){}int noop6344(){}int noop6345(){}int noop6346(){}int noop6347(){}int noop6348(){}int noop6349(){}int noop6350(){}int noop6351(){}int noop6352(){}int noop6353(){}int noop6354(){}int noop6355(){}int noop6356(){}int noop6357(){}int noop6358(){}int noop6359(){}int noop6360(){}int noop6361(){}int noop6362(){}int noop6363(){}int noop6364(){}int noop6365(){}int noop6366(){}int noop6367(){}int noop6368(){}int noop6369(){}int noop6370(){}int noop6371(){}int noop6372(){}int noop6373(){}int noop6374(){}int noop6375(){}int noop6376(){}int noop6377(){}int noop6378(){}int noop6379(){}int noop6380(){}int noop6381(){}int noop6382(){}int noop6383(){}int noop6384(){}int noop6385(){}int noop6386(){}int noop6387(){}int noop6388(){}int noop6389(){}int noop6390(){}int noop6391(){}int noop6392(){}int noop6393(){}int noop6394(){}int noop6395(){}int noop6396(){}int noop6397(){}int noop6398(){}int noop6399(){}int noop6400(){}int noop6401(){}int noop6402(){}int noop6403(){}int noop6404(){}int noop6405(){}int noop6406(){}int noop6407(){}int noop6408(){}int noop6409(){}int noop6410(){}int noop6411(){}int noop6412(){}int noop6413(){}int noop6414(){}int noop6415(){}int noop6416(){}int noop6417(){}int noop6418(){}int noop6419(){}int noop6420(){}int noop6421(){}int noop6422(){}int noop6423(){}int noop6424(){}int noop6425(){}int noop6426(){}int noop6427(){}int noop6428(){}int noop6429(){}int noop6430(){}int noop6431(){}int noop6432(){}int noop6433(){}int noop6434(){}int noop6435(){}int noop6436(){}int noop6437(){}int noop6438(){}int noop6439(){}int noop6440(){}int noop6441(){}int noop6442(){}int noop6443(){}int noop6444(){}int noop6445(){}int noop6446(){}int noop6447(){}int noop6448(){}int noop6449(){}int noop6450(){}int noop6451(){}int noop6452(){}int noop6453(){}int noop6454(){}int noop6455(){}int noop6456(){}int noop6457(){}int noop6458(){}int noop6459(){}int noop6460(){}int noop6461(){}int noop6462(){}int noop6463(){}int noop6464(){}int noop6465(){}int noop6466(){}int noop6467(){}int noop6468(){}int noop6469(){}int noop6470(){}int noop6471(){}int noop6472(){}int noop6473(){}int noop6474(){}int noop6475(){}int noop6476(){}int noop6477(){}int noop6478(){}int noop6479(){}int noop6480(){}int noop6481(){}int noop6482(){}int noop6483(){}int noop6484(){}int noop6485(){}int noop6486(){}int noop6487(){}int noop6488(){}int noop6489(){}int noop6490(){}int noop6491(){}int noop6492(){}int noop6493(){}int noop6494(){}int noop6495(){}int noop6496(){}int noop6497(){}int noop6498(){}int noop6499(){}int noop6500(){}int noop6501(){}int noop6502(){}int noop6503(){}int noop6504(){}int noop6505(){}int noop6506(){}int noop6507(){}int noop6508(){}int noop6509(){}int noop6510(){}int noop6511(){}int noop6512(){}int noop6513(){}int noop6514(){}int noop6515(){}int noop6516(){}int noop6517(){}int noop6518(){}int noop6519(){}int noop6520(){}int noop6521(){}int noop6522(){}int noop6523(){}int noop6524(){}int noop6525(){}int noop6526(){}int noop6527(){}int noop6528(){}int noop6529(){}int noop6530(){}int noop6531(){}int noop6532(){}int noop6533(){}int noop6534(){}int noop6535(){}int noop6536(){}int noop6537(){}int noop6538(){}int noop6539(){}int noop6540(){}int noop6541(){}int noop6542(){}int noop6543(){}int noop6544(){}int noop6545(){}int noop6546(){}int noop6547(){}int noop6548(){}int noop6549(){}int noop6550(){}int noop6551(){}int noop6552(){}int noop6553(){}int noop6554(){}int noop6555(){}int noop6556(){}int noop6557(){}int noop6558(){}int noop6559(){}int noop6560(){}int noop6561(){}int noop6562(){}int noop6563(){}int noop6564(){}int noop6565(){}int noop6566(){}int noop6567(){}int noop6568(){}int noop6569(){}int noop6570(){}int noop6571(){}int noop6572(){}int noop6573(){}int noop6574(){}int noop6575(){}int noop6576(){}int noop6577(){}int noop6578(){}int noop6579(){}int noop6580(){}int noop6581(){}int noop6582(){}int noop6583(){}int noop6584(){}int noop6585(){}int noop6586(){}int noop6587(){}int noop6588(){}int noop6589(){}int noop6590(){}int noop6591(){}int noop6592(){}int noop6593(){}int noop6594(){}int noop6595(){}int noop6596(){}int noop6597(){}int noop6598(){}int noop6599(){}int noop6600(){}int noop6601(){}int noop6602(){}int noop6603(){}int noop6604(){}int noop6605(){}int noop6606(){}int noop6607(){}int noop6608(){}int noop6609(){}int noop6610(){}int noop6611(){}int noop6612(){}int noop6613(){}int noop6614(){}int noop6615(){}int noop6616(){}int noop6617(){}int noop6618(){}int noop6619(){}int noop6620(){}int noop6621(){}int noop6622(){}int noop6623(){}int noop6624(){}int noop6625(){}int noop6626(){}int noop6627(){}int noop6628(){}int noop6629(){}int noop6630(){}int noop6631(){}int noop6632(){}int noop6633(){}int noop6634(){}int noop6635(){}int noop6636(){}int noop6637(){}int noop6638(){}int noop6639(){}int noop6640(){}int noop6641(){}int noop6642(){}int noop6643(){}int noop6644(){}int noop6645(){}int noop6646(){}int noop6647(){}int noop6648(){}int noop6649(){}int noop6650(){}int noop6651(){}int noop6652(){}int noop6653(){}int noop6654(){}int noop6655(){}int noop6656(){}int noop6657(){}int noop6658(){}int noop6659(){}int noop6660(){}int noop6661(){}int noop6662(){}int noop6663(){}int noop6664(){}int noop6665(){}int noop6666(){}int noop6667(){}int noop6668(){}int noop6669(){}int noop6670(){}int noop6671(){}int noop6672(){}int noop6673(){}int noop6674(){}int noop6675(){}int noop6676(){}int noop6677(){}int noop6678(){}int noop6679(){}int noop6680(){}int noop6681(){}int noop6682(){}int noop6683(){}int noop6684(){}int noop6685(){}int noop6686(){}int noop6687(){}int noop6688(){}int noop6689(){}int noop6690(){}int noop6691(){}int noop6692(){}int noop6693(){}int noop6694(){}int noop6695(){}int noop6696(){}int noop6697(){}int noop6698(){}int noop6699(){}int noop6700(){}int noop6701(){}int noop6702(){}int noop6703(){}int noop6704(){}int noop6705(){}int noop6706(){}int noop6707(){}int noop6708(){}int noop6709(){}int noop6710(){}int noop6711(){}int noop6712(){}int noop6713(){}int noop6714(){}int noop6715(){}int noop6716(){}int noop6717(){}int noop6718(){}int noop6719(){}int noop6720(){}int noop6721(){}int noop6722(){}int noop6723(){}int noop6724(){}int noop6725(){}int noop6726(){}int noop6727(){}int noop6728(){}int noop6729(){}int noop6730(){}int noop6731(){}int noop6732(){}int noop6733(){}int noop6734(){}int noop6735(){}int noop6736(){}int noop6737(){}int noop6738(){}int noop6739(){}int noop6740(){}int noop6741(){}int noop6742(){}int noop6743(){}int noop6744(){}int noop6745(){}int noop6746(){}int noop6747(){}int noop6748(){}int noop6749(){}int noop6750(){}int noop6751(){}int noop6752(){}int noop6753(){}int noop6754(){}int noop6755(){}int noop6756(){}int noop6757(){}int noop6758(){}int noop6759(){}int noop6760(){}int noop6761(){}int noop6762(){}int noop6763(){}int noop6764(){}int noop6765(){}int noop6766(){}int noop6767(){}int noop6768(){}int noop6769(){}int noop6770(){}int noop6771(){}int noop6772(){}int noop6773(){}int noop6774(){}int noop6775(){}int noop6776(){}int noop6777(){}int noop6778(){}int noop6779(){}int noop6780(){}int noop6781(){}int noop6782(){}int noop6783(){}int noop6784(){}int noop6785(){}int noop6786(){}int noop6787(){}int noop6788(){}int noop6789(){}int noop6790(){}int noop6791(){}int noop6792(){}int noop6793(){}int noop6794(){}int noop6795(){}int noop6796(){}int noop6797(){}int noop6798(){}int noop6799(){}int noop6800(){}int noop6801(){}int noop6802(){}int noop6803(){}int noop6804(){}int noop6805(){}int noop6806(){}int noop6807(){}int noop6808(){}int noop6809(){}int noop6810(){}int noop6811(){}int noop6812(){}int noop6813(){}int noop6814(){}int noop6815(){}int noop6816(){}int noop6817(){}int noop6818(){}int noop6819(){}int noop6820(){}int noop6821(){}int noop6822(){}int noop6823(){}int noop6824(){}int noop6825(){}int noop6826(){}int noop6827(){}int noop6828(){}int noop6829(){}int noop6830(){}int noop6831(){}int noop6832(){}int noop6833(){}int noop6834(){}int noop6835(){}int noop6836(){}int noop6837(){}int noop6838(){}int noop6839(){}int noop6840(){}int noop6841(){}int noop6842(){}int noop6843(){}int noop6844(){}int noop6845(){}int noop6846(){}int noop6847(){}int noop6848(){}int noop6849(){}int noop6850(){}int noop6851(){}int noop6852(){}int noop6853(){}int noop6854(){}int noop6855(){}int noop6856(){}int noop6857(){}int noop6858(){}int noop6859(){}int noop6860(){}int noop6861(){}int noop6862(){}int noop6863(){}int noop6864(){}int noop6865(){}int noop6866(){}int noop6867(){}int noop6868(){}int noop6869(){}int noop6870(){}int noop6871(){}int noop6872(){}int noop6873(){}int noop6874(){}int noop6875(){}int noop6876(){}int noop6877(){}int noop6878(){}int noop6879(){}int noop6880(){}int noop6881(){}int noop6882(){}int noop6883(){}int noop6884(){}int noop6885(){}int noop6886(){}int noop6887(){}int noop6888(){}int noop6889(){}int noop6890(){}int noop6891(){}int noop6892(){}int noop6893(){}int noop6894(){}int noop6895(){}int noop6896(){}int noop6897(){}int noop6898(){}int noop6899(){}int noop6900(){}int noop6901(){}int noop6902(){}int noop6903(){}int noop6904(){}int noop6905(){}int noop6906(){}int noop6907(){}int noop6908(){}int noop6909(){}int noop6910(){}int noop6911(){}int noop6912(){}int noop6913(){}int noop6914(){}int noop6915(){}int noop6916(){}int noop6917(){}int noop6918(){}int noop6919(){}int noop6920(){}int noop6921(){}int noop6922(){}int noop6923(){}int noop6924(){}int noop6925(){}int noop6926(){}int noop6927(){}int noop6928(){}int noop6929(){}int noop6930(){}int noop6931(){}int noop6932(){}int noop6933(){}int noop6934(){}int noop6935(){}int noop6936(){}int noop6937(){}int noop6938(){}int noop6939(){}int noop6940(){}int noop6941(){}int noop6942(){}int noop6943(){}int noop6944(){}int noop6945(){}int noop6946(){}int noop6947(){}int noop6948(){}int noop6949(){}int noop6950(){}int noop6951(){}int noop6952(){}int noop6953(){}int noop6954(){}int noop6955(){}int noop6956(){}int noop6957(){}int noop6958(){}int noop6959(){}int noop6960(){}int noop6961(){}int noop6962(){}int noop6963(){}int noop6964(){}int noop6965(){}int noop6966(){}int noop6967(){}int noop6968(){}int noop6969(){}int noop6970(){}int noop6971(){}int noop6972(){}int noop6973(){}int noop6974(){}int noop6975(){}int noop6976(){}int noop6977(){}int noop6978(){}int noop6979(){}int noop6980(){}int noop6981(){}int noop6982(){}int noop6983(){}int noop6984(){}int noop6985(){}int noop6986(){}int noop6987(){}int noop6988(){}int noop6989(){}int noop6990(){}int noop6991(){}int noop6992(){}int noop6993(){}int noop6994(){}int noop6995(){}int noop6996(){}int noop6997(){}int noop6998(){}int noop6999(){}int noop7000(){}int noop7001(){}int noop7002(){}int noop7003(){}int noop7004(){}int noop7005(){}int noop7006(){}int noop7007(){}int noop7008(){}int noop7009(){}int noop7010(){}int noop7011(){}int noop7012(){}int noop7013(){}int noop7014(){}int noop7015(){}int noop7016(){}int noop7017(){}int noop7018(){}int noop7019(){}int noop7020(){}int noop7021(){}int noop7022(){}int noop7023(){}int noop7024(){}int noop7025(){}int noop7026(){}int noop7027(){}int noop7028(){}int noop7029(){}int noop7030(){}int noop7031(){}int noop7032(){}int noop7033(){}int noop7034(){}int noop7035(){}int noop7036(){}int noop7037(){}int noop7038(){}int noop7039(){}int noop7040(){}int noop7041(){}int noop7042(){}int noop7043(){}int noop7044(){}int noop7045(){}int noop7046(){}int noop7047(){}int noop7048(){}int noop7049(){}int noop7050(){}int noop7051(){}int noop7052(){}int noop7053(){}int noop7054(){}int noop7055(){}int noop7056(){}int noop7057(){}int noop7058(){}int noop7059(){}int noop7060(){}int noop7061(){}int noop7062(){}int noop7063(){}int noop7064(){}int noop7065(){}int noop7066(){}int noop7067(){}int noop7068(){}int noop7069(){}int noop7070(){}int noop7071(){}int noop7072(){}int noop7073(){}int noop7074(){}int noop7075(){}int noop7076(){}int noop7077(){}int noop7078(){}int noop7079(){}int noop7080(){}int noop7081(){}int noop7082(){}int noop7083(){}int noop7084(){}int noop7085(){}int noop7086(){}int noop7087(){}int noop7088(){}int noop7089(){}int noop7090(){}int noop7091(){}int noop7092(){}int noop7093(){}int noop7094(){}int noop7095(){}int noop7096(){}int noop7097(){}int noop7098(){}int noop7099(){}int noop7100(){}int noop7101(){}int noop7102(){}int noop7103(){}int noop7104(){}int noop7105(){}int noop7106(){}int noop7107(){}int noop7108(){}int noop7109(){}int noop7110(){}int noop7111(){}int noop7112(){}int noop7113(){}int noop7114(){}int noop7115(){}int noop7116(){}int noop7117(){}int noop7118(){}int noop7119(){}int noop7120(){}int noop7121(){}int noop7122(){}int noop7123(){}int noop7124(){}int noop7125(){}int noop7126(){}int noop7127(){}int noop7128(){}int noop7129(){}int noop7130(){}int noop7131(){}int noop7132(){}int noop7133(){}int noop7134(){}int noop7135(){}int noop7136(){}int noop7137(){}int noop7138(){}int noop7139(){}int noop7140(){}int noop7141(){}int noop7142(){}int noop7143(){}int noop7144(){}int noop7145(){}int noop7146(){}int noop7147(){}int noop7148(){}int noop7149(){}int noop7150(){}int noop7151(){}int noop7152(){}int noop7153(){}int noop7154(){}int noop7155(){}int noop7156(){}int noop7157(){}int noop7158(){}int noop7159(){}int noop7160(){}int noop7161(){}int noop7162(){}int noop7163(){}int noop7164(){}int noop7165(){}int noop7166(){}int noop7167(){}int noop7168(){}int noop7169(){}int noop7170(){}int noop7171(){}int noop7172(){}int noop7173(){}int noop7174(){}int noop7175(){}int noop7176(){}int noop7177(){}int noop7178(){}int noop7179(){}int noop7180(){}int noop7181(){}int noop7182(){}int noop7183(){}int noop7184(){}int noop7185(){}int noop7186(){}int noop7187(){}int noop7188(){}int noop7189(){}int noop7190(){}int noop7191(){}int noop7192(){}int noop7193(){}int noop7194(){}int noop7195(){}int noop7196(){}int noop7197(){}int noop7198(){}int noop7199(){}int noop7200(){}int noop7201(){}int noop7202(){}int noop7203(){}int noop7204(){}int noop7205(){}int noop7206(){}int noop7207(){}int noop7208(){}int noop7209(){}int noop7210(){}int noop7211(){}int noop7212(){}int noop7213(){}int noop7214(){}int noop7215(){}int noop7216(){}int noop7217(){}int noop7218(){}int noop7219(){}int noop7220(){}int noop7221(){}int noop7222(){}int noop7223(){}int noop7224(){}int noop7225(){}int noop7226(){}int noop7227(){}int noop7228(){}int noop7229(){}int noop7230(){}int noop7231(){}int noop7232(){}int noop7233(){}int noop7234(){}int noop7235(){}int noop7236(){}int noop7237(){}int noop7238(){}int noop7239(){}int noop7240(){}int noop7241(){}int noop7242(){}int noop7243(){}int noop7244(){}int noop7245(){}int noop7246(){}int noop7247(){}int noop7248(){}int noop7249(){}int noop7250(){}int noop7251(){}int noop7252(){}int noop7253(){}int noop7254(){}int noop7255(){}int noop7256(){}int noop7257(){}int noop7258(){}int noop7259(){}int noop7260(){}int noop7261(){}int noop7262(){}int noop7263(){}int noop7264(){}int noop7265(){}int noop7266(){}int noop7267(){}int noop7268(){}int noop7269(){}int noop7270(){}int noop7271(){}int noop7272(){}int noop7273(){}int noop7274(){}int noop7275(){}int noop7276(){}int noop7277(){}int noop7278(){}int noop7279(){}int noop7280(){}int noop7281(){}int noop7282(){}int noop7283(){}int noop7284(){}int noop7285(){}int noop7286(){}int noop7287(){}int noop7288(){}int noop7289(){}int noop7290(){}int noop7291(){}int noop7292(){}int noop7293(){}int noop7294(){}int noop7295(){}int noop7296(){}int noop7297(){}int noop7298(){}int noop7299(){}int noop7300(){}int noop7301(){}int noop7302(){}int noop7303(){}int noop7304(){}int noop7305(){}int noop7306(){}int noop7307(){}int noop7308(){}int noop7309(){}int noop7310(){}int noop7311(){}int noop7312(){}int noop7313(){}int noop7314(){}int noop7315(){}int noop7316(){}int noop7317(){}int noop7318(){}int noop7319(){}int noop7320(){}int noop7321(){}int noop7322(){}int noop7323(){}int noop7324(){}int noop7325(){}int noop7326(){}int noop7327(){}int noop7328(){}int noop7329(){}int noop7330(){}int noop7331(){}int noop7332(){}int noop7333(){}int noop7334(){}int noop7335(){}int noop7336(){}int noop7337(){}int noop7338(){}int noop7339(){}int noop7340(){}int noop7341(){}int noop7342(){}int noop7343(){}int noop7344(){}int noop7345(){}int noop7346(){}int noop7347(){}int noop7348(){}int noop7349(){}int noop7350(){}int noop7351(){}int noop7352(){}int noop7353(){}int noop7354(){}int noop7355(){}int noop7356(){}int noop7357(){}int noop7358(){}int noop7359(){}int noop7360(){}int noop7361(){}int noop7362(){}int noop7363(){}int noop7364(){}int noop7365(){}int noop7366(){}int noop7367(){}int noop7368(){}int noop7369(){}int noop7370(){}int noop7371(){}int noop7372(){}int noop7373(){}int noop7374(){}int noop7375(){}int noop7376(){}int noop7377(){}int noop7378(){}int noop7379(){}int noop7380(){}int noop7381(){}int noop7382(){}int noop7383(){}int noop7384(){}int noop7385(){}int noop7386(){}int noop7387(){}int noop7388(){}int noop7389(){}int noop7390(){}int noop7391(){}int noop7392(){}int noop7393(){}int noop7394(){}int noop7395(){}int noop7396(){}int noop7397(){}int noop7398(){}int noop7399(){}int noop7400(){}int noop7401(){}int noop7402(){}int noop7403(){}int noop7404(){}int noop7405(){}int noop7406(){}int noop7407(){}int noop7408(){}int noop7409(){}int noop7410(){}int noop7411(){}int noop7412(){}int noop7413(){}int noop7414(){}int noop7415(){}int noop7416(){}int noop7417(){}int noop7418(){}int noop7419(){}int noop7420(){}int noop7421(){}int noop7422(){}int noop7423(){}int noop7424(){}int noop7425(){}int noop7426(){}int noop7427(){}int noop7428(){}int noop7429(){}int noop7430(){}int noop7431(){}int noop7432(){}int noop7433(){}int noop7434(){}int noop7435(){}int noop7436(){}int noop7437(){}int noop7438(){}int noop7439(){}int noop7440(){}int noop7441(){}int noop7442(){}int noop7443(){}int noop7444(){}int noop7445(){}int noop7446(){}int noop7447(){}int noop7448(){}int noop7449(){}int noop7450(){}int noop7451(){}int noop7452(){}int noop7453(){}int noop7454(){}int noop7455(){}int noop7456(){}int noop7457(){}int noop7458(){}int noop7459(){}int noop7460(){}int noop7461(){}int noop7462(){}int noop7463(){}int noop7464(){}int noop7465(){}int noop7466(){}int noop7467(){}int noop7468(){}int noop7469(){}int noop7470(){}int noop7471(){}int noop7472(){}int noop7473(){}int noop7474(){}int noop7475(){}int noop7476(){}int noop7477(){}int noop7478(){}int noop7479(){}int noop7480(){}int noop7481(){}int noop7482(){}int noop7483(){}int noop7484(){}int noop7485(){}int noop7486(){}int noop7487(){}int noop7488(){}int noop7489(){}int noop7490(){}int noop7491(){}int noop7492(){}int noop7493(){}int noop7494(){}int noop7495(){}int noop7496(){}int noop7497(){}int noop7498(){}int noop7499(){}int noop7500(){}int noop7501(){}int noop7502(){}int noop7503(){}int noop7504(){}int noop7505(){}int noop7506(){}int noop7507(){}int noop7508(){}int noop7509(){}int noop7510(){}int noop7511(){}int noop7512(){}int noop7513(){}int noop7514(){}int noop7515(){}int noop7516(){}int noop7517(){}int noop7518(){}int noop7519(){}int noop7520(){}int noop7521(){}int noop7522(){}int noop7523(){}int noop7524(){}int noop7525(){}int noop7526(){}int noop7527(){}int noop7528(){}int noop7529(){}int noop7530(){}int noop7531(){}int noop7532(){}int noop7533(){}int noop7534(){}int noop7535(){}int noop7536(){}int noop7537(){}int noop7538(){}int noop7539(){}int noop7540(){}int noop7541(){}int noop7542(){}int noop7543(){}int noop7544(){}int noop7545(){}int noop7546(){}int noop7547(){}int noop7548(){}int noop7549(){}int noop7550(){}int noop7551(){}int noop7552(){}int noop7553(){}int noop7554(){}int noop7555(){}int noop7556(){}int noop7557(){}int noop7558(){}int noop7559(){}int noop7560(){}int noop7561(){}int noop7562(){}int noop7563(){}int noop7564(){}int noop7565(){}int noop7566(){}int noop7567(){}int noop7568(){}int noop7569(){}int noop7570(){}int noop7571(){}int noop7572(){}int noop7573(){}int noop7574(){}int noop7575(){}int noop7576(){}int noop7577(){}int noop7578(){}int noop7579(){}int noop7580(){}int noop7581(){}int noop7582(){}int noop7583(){}int noop7584(){}int noop7585(){}int noop7586(){}int noop7587(){}int noop7588(){}int noop7589(){}int noop7590(){}int noop7591(){}int noop7592(){}int noop7593(){}int noop7594(){}int noop7595(){}int noop7596(){}int noop7597(){}int noop7598(){}int noop7599(){}int noop7600(){}int noop7601(){}int noop7602(){}int noop7603(){}int noop7604(){}int noop7605(){}int noop7606(){}int noop7607(){}int noop7608(){}int noop7609(){}int noop7610(){}int noop7611(){}int noop7612(){}int noop7613(){}int noop7614(){}int noop7615(){}int noop7616(){}int noop7617(){}int noop7618(){}int noop7619(){}int noop7620(){}int noop7621(){}int noop7622(){}int noop7623(){}int noop7624(){}int noop7625(){}int noop7626(){}int noop7627(){}int noop7628(){}int noop7629(){}int noop7630(){}int noop7631(){}int noop7632(){}int noop7633(){}int noop7634(){}int noop7635(){}int noop7636(){}int noop7637(){}int noop7638(){}int noop7639(){}int noop7640(){}int noop7641(){}int noop7642(){}int noop7643(){}int noop7644(){}int noop7645(){}int noop7646(){}int noop7647(){}int noop7648(){}int noop7649(){}int noop7650(){}int noop7651(){}int noop7652(){}int noop7653(){}int noop7654(){}int noop7655(){}int noop7656(){}int noop7657(){}int noop7658(){}int noop7659(){}int noop7660(){}int noop7661(){}int noop7662(){}int noop7663(){}int noop7664(){}int noop7665(){}int noop7666(){}int noop7667(){}int noop7668(){}int noop7669(){}int noop7670(){}int noop7671(){}int noop7672(){}int noop7673(){}int noop7674(){}int noop7675(){}int noop7676(){}int noop7677(){}int noop7678(){}int noop7679(){}int noop7680(){}int noop7681(){}int noop7682(){}int noop7683(){}int noop7684(){}int noop7685(){}int noop7686(){}int noop7687(){}int noop7688(){}int noop7689(){}int noop7690(){}int noop7691(){}int noop7692(){}int noop7693(){}int noop7694(){}int noop7695(){}int noop7696(){}int noop7697(){}int noop7698(){}int noop7699(){}int noop7700(){}int noop7701(){}int noop7702(){}int noop7703(){}int noop7704(){}int noop7705(){}int noop7706(){}int noop7707(){}int noop7708(){}int noop7709(){}int noop7710(){}int noop7711(){}int noop7712(){}int noop7713(){}int noop7714(){}int noop7715(){}int noop7716(){}int noop7717(){}int noop7718(){}int noop7719(){}int noop7720(){}int noop7721(){}int noop7722(){}int noop7723(){}int noop7724(){}int noop7725(){}int noop7726(){}int noop7727(){}int noop7728(){}int noop7729(){}int noop7730(){}int noop7731(){}int noop7732(){}int noop7733(){}int noop7734(){}int noop7735(){}int noop7736(){}int noop7737(){}int noop7738(){}int noop7739(){}int noop7740(){}int noop7741(){}int noop7742(){}int noop7743(){}int noop7744(){}int noop7745(){}int noop7746(){}int noop7747(){}int noop7748(){}int noop7749(){}int noop7750(){}int noop7751(){}int noop7752(){}int noop7753(){}int noop7754(){}int noop7755(){}int noop7756(){}int noop7757(){}int noop7758(){}int noop7759(){}int noop7760(){}int noop7761(){}int noop7762(){}int noop7763(){}int noop7764(){}int noop7765(){}int noop7766(){}int noop7767(){}int noop7768(){}int noop7769(){}int noop7770(){}int noop7771(){}int noop7772(){}int noop7773(){}int noop7774(){}int noop7775(){}int noop7776(){}int noop7777(){}int noop7778(){}int noop7779(){}int noop7780(){}int noop7781(){}int noop7782(){}int noop7783(){}int noop7784(){}int noop7785(){}int noop7786(){}int noop7787(){}int noop7788(){}int noop7789(){}int noop7790(){}int noop7791(){}int noop7792(){}int noop7793(){}int noop7794(){}int noop7795(){}int noop7796(){}int noop7797(){}int noop7798(){}int noop7799(){}int noop7800(){}int noop7801(){}int noop7802(){}int noop7803(){}int noop7804(){}int noop7805(){}int noop7806(){}int noop7807(){}int noop7808(){}int noop7809(){}int noop7810(){}int noop7811(){}int noop7812(){}int noop7813(){}int noop7814(){}int noop7815(){}int noop7816(){}int noop7817(){}int noop7818(){}int noop7819(){}int noop7820(){}int noop7821(){}int noop7822(){}int noop7823(){}int noop7824(){}int noop7825(){}int noop7826(){}int noop7827(){}int noop7828(){}int noop7829(){}int noop7830(){}int noop7831(){}int noop7832(){}int noop7833(){}int noop7834(){}int noop7835(){}int noop7836(){}int noop7837(){}int noop7838(){}int noop7839(){}int noop7840(){}int noop7841(){}int noop7842(){}int noop7843(){}int noop7844(){}int noop7845(){}int noop7846(){}int noop7847(){}int noop7848(){}int noop7849(){}int noop7850(){}int noop7851(){}int noop7852(){}int noop7853(){}int noop7854(){}int noop7855(){}int noop7856(){}int noop7857(){}int noop7858(){}int noop7859(){}int noop7860(){}int noop7861(){}int noop7862(){}int noop7863(){}int noop7864(){}int noop7865(){}int noop7866(){}int noop7867(){}int noop7868(){}int noop7869(){}int noop7870(){}int noop7871(){}int noop7872(){}int noop7873(){}int noop7874(){}int noop7875(){}int noop7876(){}int noop7877(){}int noop7878(){}int noop7879(){}int noop7880(){}int noop7881(){}int noop7882(){}int noop7883(){}int noop7884(){}int noop7885(){}int noop7886(){}int noop7887(){}int noop7888(){}int noop7889(){}int noop7890(){}int noop7891(){}int noop7892(){}int noop7893(){}int noop7894(){}int noop7895(){}int noop7896(){}int noop7897(){}int noop7898(){}int noop7899(){}int noop7900(){}int noop7901(){}int noop7902(){}int noop7903(){}int noop7904(){}int noop7905(){}int noop7906(){}int noop7907(){}int noop7908(){}int noop7909(){}int noop7910(){}int noop7911(){}int noop7912(){}int noop7913(){}int noop7914(){}int noop7915(){}int noop7916(){}int noop7917(){}int noop7918(){}int noop7919(){}int noop7920(){}int noop7921(){}int noop7922(){}int noop7923(){}int noop7924(){}int noop7925(){}int noop7926(){}int noop7927(){}int noop7928(){}int noop7929(){}int noop7930(){}int noop7931(){}int noop7932(){}int noop7933(){}int noop7934(){}int noop7935(){}int noop7936(){}int noop7937(){}int noop7938(){}int noop7939(){}int noop7940(){}int noop7941(){}int noop7942(){}int noop7943(){}int noop7944(){}int noop7945(){}int noop7946(){}int noop7947(){}int noop7948(){}int noop7949(){}int noop7950(){}int noop7951(){}int noop7952(){}int noop7953(){}int noop7954(){}int noop7955(){}int noop7956(){}int noop7957(){}int noop7958(){}int noop7959(){}int noop7960(){}int noop7961(){}int noop7962(){}int noop7963(){}int noop7964(){}int noop7965(){}int noop7966(){}int noop7967(){}int noop7968(){}int noop7969(){}int noop7970(){}int noop7971(){}int noop7972(){}int noop7973(){}int noop7974(){}int noop7975(){}int noop7976(){}int noop7977(){}int noop7978(){}int noop7979(){}int noop7980(){}int noop7981(){}int noop7982(){}int noop7983(){}int noop7984(){}int noop7985(){}int noop7986(){}int noop7987(){}int noop7988(){}int noop7989(){}int noop7990(){}int noop7991(){}int noop7992(){}int noop7993(){}int noop7994(){}int noop7995(){}int noop7996(){}int noop7997(){}int noop7998(){}int noop7999(){} + +int foo() { + return 12; +} + +int bar() { + return 24; +} diff --git a/ofrak_core/pytest_ofrak/elf/assets/large_elf.o b/ofrak_core/pytest_ofrak/elf/assets/large_elf.o new file mode 100644 index 000000000..3b9f4bad9 --- /dev/null +++ b/ofrak_core/pytest_ofrak/elf/assets/large_elf.o @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2db2270116021033d2435bb6d1a6b747cbc95814d0132cc076fa5685a9b6f36e +size 768408 diff --git a/ofrak_core/pytest_ofrak/elf/assets/program b/ofrak_core/pytest_ofrak/elf/assets/program new file mode 100755 index 000000000..7639d499f --- /dev/null +++ b/ofrak_core/pytest_ofrak/elf/assets/program @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b42e12c133290d1abfc45340831bb4186c9310af84eb8dcc8f6e94ea667f05b4 +size 16664 diff --git a/ofrak_core/pytest_ofrak/elf/assets/program.c b/ofrak_core/pytest_ofrak/elf/assets/program.c new file mode 100644 index 000000000..005b50805 --- /dev/null +++ b/ofrak_core/pytest_ofrak/elf/assets/program.c @@ -0,0 +1,18 @@ + +#include + +int foo(); +int bar(); + +int main() { + printf("Hello, World!\n"); + return foo(); +} + +int foo() { + return 12; +} + +int bar() { + return 24; +} diff --git a/ofrak_core/pytest_ofrak/elf/assets/program.o b/ofrak_core/pytest_ofrak/elf/assets/program.o new file mode 100644 index 000000000..0f22c5333 --- /dev/null +++ b/ofrak_core/pytest_ofrak/elf/assets/program.o @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6dc7b39c8e0ac9760d1107f13344665c2a82280f4fd7aec3ba30b5c3c01242b7 +size 1400 diff --git a/ofrak_core/pytest_ofrak/elf/assets/program_no_reloc b/ofrak_core/pytest_ofrak/elf/assets/program_no_reloc new file mode 100755 index 000000000..d1e50f447 --- /dev/null +++ b/ofrak_core/pytest_ofrak/elf/assets/program_no_reloc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:74dc73057919a393dbaebdc60cb712436125a44993b4dc42b4b838ee70d846d8 +size 16472 diff --git a/ofrak_core/pytest_ofrak/elf/assets/source_dir/patch.c b/ofrak_core/pytest_ofrak/elf/assets/source_dir/patch.c new file mode 100644 index 000000000..9ef5bafee --- /dev/null +++ b/ofrak_core/pytest_ofrak/elf/assets/source_dir/patch.c @@ -0,0 +1,8 @@ + +int noop0(); + +int baz() +{ + noop0(); + return 36; +} diff --git a/ofrak_core/pytest_ofrak/elf/fixtures.py b/ofrak_core/pytest_ofrak/elf/fixtures.py index 87464000d..99bbab873 100644 --- a/ofrak_core/pytest_ofrak/elf/fixtures.py +++ b/ofrak_core/pytest_ofrak/elf/fixtures.py @@ -1,165 +1,164 @@ import os -import subprocess + +# import subprocess import pytest -MAKEFILE_CONTENTS = """ -CC=gcc -default: program +# MAKEFILE_CONTENTS = """ +# CC=gcc + +# default: program + +# program.o: program.c $(HEADERS) +# $(CC) -c program.c -fno-asynchronous-unwind-tables -o program.o -program.o: program.c $(HEADERS) - $(CC) -c program.c -fno-asynchronous-unwind-tables -o program.o +# program: program.o +# $(CC) program.o -o program -program: program.o - $(CC) program.o -o program +# program_no_reloc: program.o +# $(CC) program.o -no-pie -o program_no_reloc -program_no_reloc: program.o - $(CC) program.o -no-pie -o program_no_reloc +# program_relocated: program_relocated.o +# $(CC) program_relocated.o -o program_relocated -program_relocated: program_relocated.o - $(CC) program_relocated.o -o program_relocated +# large_elf.o: large_elf.c $(HEADERS) +# $(CC) -c large_elf.c -o large_elf.o -large_elf.o: large_elf.c $(HEADERS) - $(CC) -c large_elf.c -o large_elf.o +# large_elf: large_elf.o +# $(CC) large_elf.o -no-pie -o large_elf +# """ -large_elf: large_elf.o - $(CC) large_elf.o -no-pie -o large_elf -""" +# C_SOURCE_CONTENTS = """ +# #include -C_SOURCE_CONTENTS = """ -#include +# int foo(); +# int bar(); -int foo(); -int bar(); +# int main() { +# printf("Hello, World!\\n"); +# return foo(); +# } -int main() { - printf("Hello, World!\\n"); - return foo(); -} +# int foo() { +# return 12; +# } -int foo() { - return 12; -} +# int bar() { +# return 24; +# } -int bar() { - return 24; -} +# """ -""" +# LARGE_SOURCE_CONTENTS_HEADER = """ +# int foo(); +# int bar(); -LARGE_SOURCE_CONTENTS_HEADER = """ -int foo(); -int bar(); +# int main() { +# return bar(); +# } -int main() { - return bar(); -} +# """ -""" +# LARGE_SOURCE_CONTENTS_FOOTER = """ -LARGE_SOURCE_CONTENTS_FOOTER = """ +# int foo() { +# return 12; +# } -int foo() { - return 12; -} +# int bar() { +# return 24; +# } -int bar() { - return 24; -} +# """ -""" +# PATCH_CONTENTS = """ +# int noop0(); -PATCH_CONTENTS = """ -int noop0(); +# int baz() +# { +# noop0(); +# return 36; +# } +# """ -int baz() -{ - noop0(); - return 36; -} -""" +# def create_noops(): +# noops = [] -def create_noops(): - noops = [] +# i = 0 - i = 0 +# for i in range(8000): +# instruction = f"int noop{i}(){{}}" +# noops.append(instruction) - for i in range(8000): - instruction = f"int noop{i}(){{}}" - noops.append(instruction) +# return noops - return noops +@pytest.fixture(scope="session") +def elf_test_directory(): + return os.path.join(os.path.dirname(__file__), "assets") -@pytest.fixture -def elf_test_directory(tmpdir): - makefile_path = os.path.join(tmpdir, "Makefile") - c_source_path = os.path.join(tmpdir, "program.c") - large_source_path = os.path.join(tmpdir, "large_elf.c") + # makefile_path = os.path.join(tmpdir, "Makefile") + # c_source_path = os.path.join(tmpdir, "program.c") + # large_source_path = os.path.join(tmpdir, "large_elf.c") - patch_dir = os.path.join(tmpdir, "source_dir") - if not os.path.exists(patch_dir): - os.mkdir(patch_dir) - patch_path = os.path.join(patch_dir, "patch.c") + # patch_dir = os.path.join(tmpdir, "source_dir") + # if not os.path.exists(patch_dir): + # os.mkdir(patch_dir) + # patch_path = os.path.join(patch_dir, "patch.c") - noops = create_noops() + # noops = create_noops() - LARGE_SOURCE_CONTENTS = LARGE_SOURCE_CONTENTS_HEADER - for noop in noops: - LARGE_SOURCE_CONTENTS += noop - LARGE_SOURCE_CONTENTS += LARGE_SOURCE_CONTENTS_FOOTER + # LARGE_SOURCE_CONTENTS = LARGE_SOURCE_CONTENTS_HEADER + # for noop in noops: + # LARGE_SOURCE_CONTENTS += noop + # LARGE_SOURCE_CONTENTS += LARGE_SOURCE_CONTENTS_FOOTER - with open(makefile_path, "w") as f: - f.write(MAKEFILE_CONTENTS) - with open(c_source_path, "w") as f: - f.write(C_SOURCE_CONTENTS) - with open(large_source_path, "w") as f: - f.write(LARGE_SOURCE_CONTENTS) - with open(patch_path, "w") as f: - f.write(PATCH_CONTENTS) + # with open(makefile_path, "w") as f: + # f.write(MAKEFILE_CONTENTS) + # with open(c_source_path, "w") as f: + # f.write(C_SOURCE_CONTENTS) + # with open(large_source_path, "w") as f: + # f.write(LARGE_SOURCE_CONTENTS) + # with open(patch_path, "w") as f: + # f.write(PATCH_CONTENTS) - return tmpdir + # return tmpdir -@pytest.fixture +@pytest.fixture(scope="session") def elf_object_file(elf_test_directory): - subprocess.run(["make", "-C", elf_test_directory, "program.o"]) return os.path.join(elf_test_directory, "program.o") -@pytest.fixture +@pytest.fixture(scope="session") def elf_executable_file(elf_test_directory): - subprocess.run(["make", "-C", elf_test_directory, "program"]) return os.path.join(elf_test_directory, "program") -@pytest.fixture +@pytest.fixture(scope="session") def elf_no_pie_executable_file(elf_test_directory): - subprocess.run(["make", "-C", elf_test_directory, "program_no_reloc"]) return os.path.join(elf_test_directory, "program_no_reloc") -@pytest.fixture +@pytest.fixture(scope="session") def large_elf_source_file(elf_test_directory): return os.path.join(elf_test_directory, "large_elf.c") -@pytest.fixture +@pytest.fixture(scope="session") def large_elf_object_file(elf_test_directory): - subprocess.run(["make", "-C", elf_test_directory, "large_elf.o"]) return os.path.join(elf_test_directory, "large_elf.o") -@pytest.fixture +@pytest.fixture(scope="session") def large_elf_file(elf_test_directory): - subprocess.run(["make", "-C", elf_test_directory, "large_elf"]) return os.path.join(elf_test_directory, "large_elf") -@pytest.fixture +@pytest.fixture(scope="session") def patch_file(elf_test_directory): return os.path.join(elf_test_directory, "source_dir", "patch.c") diff --git a/ofrak_core/pytest_ofrak/fixtures.py b/ofrak_core/pytest_ofrak/fixtures.py index bed04e2e9..a922c120e 100644 --- a/ofrak_core/pytest_ofrak/fixtures.py +++ b/ofrak_core/pytest_ofrak/fixtures.py @@ -20,7 +20,7 @@ def ofrak_id_service(): @pytest.fixture def ofrak(ofrak_injector, ofrak_id_service): - ofrak = OFRAK(logging.INFO) + ofrak = OFRAK(logging.INFO, exclude_components_missing_dependencies=True) ofrak.injector = ofrak_injector ofrak.set_id_service(ofrak_id_service) diff --git a/ofrak_core/pytest_ofrak/mark.py b/ofrak_core/pytest_ofrak/mark.py new file mode 100644 index 000000000..3f73abc96 --- /dev/null +++ b/ofrak_core/pytest_ofrak/mark.py @@ -0,0 +1,98 @@ +import asyncio +from typing import Mapping, Sequence, Type, Tuple +import sys +import pytest + +from ofrak.model.component_model import ComponentExternalTool +from ofrak.component.abstract import AbstractComponent + + +async def _check_deps_installed( + deps: Sequence[ComponentExternalTool], +) -> Mapping[ComponentExternalTool, bool]: + return dict(zip(deps, await asyncio.gather(*(dep.is_tool_installed() for dep in deps)))) + + +def _handle_skipif_missing_deps( + deps_installed_data: Mapping[ComponentExternalTool, bool], + components: Sequence[Type[AbstractComponent]], +) -> Tuple[bool, str]: + """ + :param deps_installed_data: a precomputed mapping of all tools to their installed status + :params components: the components a test case uses + + :return: a ``skipif`` marker for skipping a test function, module, or class if not all + dependencies of a component are satisfied. + """ + + missing_messages = [] + skip = False + for component in components: + missing = [ + dep.tool for dep in component.external_dependencies if not deps_installed_data[dep] + ] + if missing: + skip = True + missing_messages.append(f"{', '.join(missing)} of {component.__name__}") + return pytest.mark.skipif( + skip, reason=f"Missing external dependencies: {'; '.join(missing_messages)}" + ) + + +# https://docs.pytest.org/en/latest/example/simple.html#control-skipping-of-tests-according-to-command-line-option +def pytest_addoption(parser): + parser.addoption( + "--skip-tests-missing-deps", + action="store_true", + default=False, + help="skip tests whose required external dependencies are missing", + ) + + +def pytest_configure(config): + config.addinivalue_line( + "markers", + ( + "skipif_missing_deps(component_classes): skip the test function, module, or class if not all dependencies of a component class(es) are installed. " + "This marker has to take an iterable of classes rather than args otherwise pytest's decorator magic will think the mark was applied to the component " + "class not the actual test function. " + "Example: @skipif_missing_deps([StringsAnalyzer]) would skip a test if the linux `strings` command is unavailable because StringsAnalyzer calls `strings`." + ), + ) + config.addinivalue_line( + "markers", + "skipif_windows: skip the test if running on windows. Equivalent to @skipif(sys.platform == 'win32')", + ) + + +def _all_required_components(item) -> Sequence[Type[AbstractComponent]]: + return [ + component + for mark in item.iter_markers(name="skipif_missing_deps") + for component in mark.args[0] + ] + + +def pytest_collection_modifyitems(config, items): + if config.getoption("--skip-tests-missing-deps"): + deps_installed_data = asyncio.run( + _check_deps_installed( + { + dep + for item in items + for component in _all_required_components(item) + for dep in component.external_dependencies + } + ) + ) + + for item in items: + if components := _all_required_components(item): + item.add_marker(_handle_skipif_missing_deps(deps_installed_data, components)) + + if sys.platform == "win32": + windows_skip_marker = pytest.mark.skip(reason="Test cannot run on Windows.") + + for item in items: + if "skipif_windows" in item.keywords: + item.add_marker(windows_skip_marker) diff --git a/ofrak_core/pytest_ofrak/mock_component_types.py b/ofrak_core/pytest_ofrak/mock_component_types.py index a4cb84074..78d21eabb 100644 --- a/ofrak_core/pytest_ofrak/mock_component_types.py +++ b/ofrak_core/pytest_ofrak/mock_component_types.py @@ -21,3 +21,11 @@ def __init__(self): async def unpack(self, resource, config=None): pass + + +class MockRunnableUnpacker(Unpacker[None]): + targets = () + children = () + + async def unpack(self, resource, config=None): + pass diff --git a/ofrak_core/pytest_ofrak/mock_library3.py b/ofrak_core/pytest_ofrak/mock_library3.py index 1be2f1654..1b3997ee2 100644 --- a/ofrak_core/pytest_ofrak/mock_library3.py +++ b/ofrak_core/pytest_ofrak/mock_library3.py @@ -1,32 +1,22 @@ -from ofrak.resource import ResourceFactory +import sys from ofrak.model.component_model import ComponentExternalTool -from ofrak.service.component_locator_i import ComponentLocatorInterface -from ofrak.service.data_service_i import DataServiceInterface -from ofrak.service.resource_service_i import ResourceServiceInterface -from pytest_ofrak.mock_component_types import MockUnpacker - - -class _MockComponentA(MockUnpacker): - def __init__( - self, - resource_factory: ResourceFactory, - data_service: DataServiceInterface, - resource_service: ResourceServiceInterface, - component_locator: ComponentLocatorInterface, - ): - super(MockUnpacker, self).__init__( - resource_factory, data_service, resource_service, component_locator - ) +from pytest_ofrak.mock_component_types import MockRunnableUnpacker + +class _MockComponentA(MockRunnableUnpacker): external_dependencies = (ComponentExternalTool("tool_a", "tool_a.com", "--help", "tool_a_apt"),) -class _MockComponentB(MockUnpacker): +class _MockComponentB(MockRunnableUnpacker): external_dependencies = ( ComponentExternalTool("tool_b", "tool_b.com", "--help", None, "tool_a_brew"), ) -class _MockComponentC(MockUnpacker): +class _MockComponentC(MockRunnableUnpacker): pass + + +class _MockComponentSysExec(MockRunnableUnpacker): + external_dependencies = (ComponentExternalTool(sys.executable, "", "--version", None, ""),) diff --git a/ofrak_core/requirements.txt b/ofrak_core/requirements.txt index 79c11c67f..8fb088bae 100644 --- a/ofrak_core/requirements.txt +++ b/ofrak_core/requirements.txt @@ -19,6 +19,7 @@ python-magic-bin;platform_system=="Windows" reedsolo==1.7.0 sortedcontainers==2.2.2 synthol~=0.1.1 +tempfile312~=1.0.1 typeguard~=2.13.3 ubi-reader==0.8.5 xattr==0.10.1;platform_system!="Windows" diff --git a/ofrak_core/test_ofrak/components/assets/README.md b/ofrak_core/test_ofrak/components/assets/README.md index ec52f584c..6d267aca1 100644 --- a/ofrak_core/test_ofrak/components/assets/README.md +++ b/ofrak_core/test_ofrak/components/assets/README.md @@ -5,3 +5,4 @@ - jumpnbump.exe: main executable from [Jump'n'Bump](https://www.icculus.org/jumpnbump/) version 1.51, the game is open-source and GPLv2-licensed - kernel32.dll: [https://www.dlldownloader.com/kernel32-dll/](https://www.dlldownloader.com/kernel32-dll/) - kernel_address_space.out: used for the x64 Kernel address space unpacker tests, source and build command are in kernel_address_space_build.sh +- string_test.out: used for the AsciiStringAnalyzer test in test_string.py, built with `gcc string_test.c -o string_test.out` diff --git a/ofrak_core/test_ofrak/components/assets/string_test.c b/ofrak_core/test_ofrak/components/assets/string_test.c new file mode 100644 index 000000000..50b419545 --- /dev/null +++ b/ofrak_core/test_ofrak/components/assets/string_test.c @@ -0,0 +1,38 @@ + +#include + + +extern int longString(void); +extern int shortString(void); + +// Generate bytes that look like a long ascii string (21 bytes) that will be matched as a string +// by the AsciiUnpacker. Assumes running on x86. +__asm__(".global longString\n\t" + ".type longString, @function\n\t" + "push %r15\n\t" + "push %r15\n\t" + "push %r15\n\t" + "push %r15\n\t" + "push %r15\n\t" + "push %r15\n\t" + "push %r15\n\t" + "push %r15\n\t" + "and 0, %r15\n\t" +); + +// Generate bytes that look like a short ascii string (7 bytes) that will not be matched as a string +// by the AsciiUnpacker because of the min length requirement. Assumes running on x86. +__asm__(".global shortString\n\t" + ".type shortString, @function\n\t" + "push %r15\n\t" + "and 0, %r15\n\t" +); + + +int main() { + printf("O"); + printf("h, hi"); + printf(" Marc!"); + printf("You are tearing me apart, Lisa!"); + return 0; +} diff --git a/ofrak_core/test_ofrak/components/assets/string_test.out b/ofrak_core/test_ofrak/components/assets/string_test.out new file mode 100755 index 000000000..9f6709d84 --- /dev/null +++ b/ofrak_core/test_ofrak/components/assets/string_test.out @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6362fe0a2954e363e28faead8351c4d65f65ffec4a62d21970064329233d09bc +size 16664 diff --git a/ofrak_core/test_ofrak/components/test_apk.py b/ofrak_core/test_ofrak/components/test_apk.py index 51eabdd0f..ef12d4900 100644 --- a/ofrak_core/test_ofrak/components/test_apk.py +++ b/ofrak_core/test_ofrak/components/test_apk.py @@ -3,10 +3,11 @@ from ofrak import OFRAKContext from ofrak.resource import Resource -from ofrak.core.apk import Apk, ApkPacker, ApkPackerConfig +from ofrak.core.apk import Apk, ApkPacker, ApkPackerConfig, ApkUnpacker from pytest_ofrak.patterns.unpack_modify_pack import UnpackPackPattern +@pytest.mark.skipif_missing_deps([ApkPacker, ApkUnpacker]) class TestApkUnpackPack(UnpackPackPattern): """ Tag an APK and unpack it, assert that it has contents, repack it, and unpack it again. diff --git a/ofrak_core/test_ofrak/components/test_binwalk_component.py b/ofrak_core/test_ofrak/components/test_binwalk_component.py index 8cc7c4cea..ca7ad7c8c 100644 --- a/ofrak_core/test_ofrak/components/test_binwalk_component.py +++ b/ofrak_core/test_ofrak/components/test_binwalk_component.py @@ -4,7 +4,7 @@ import os import pytest -from ofrak.core.binwalk import BinwalkAttributes +from ofrak.core.binwalk import BinwalkAnalyzer, BinwalkAttributes import test_ofrak.components BINWALK_ASSETS_PATH = os.path.join(test_ofrak.components.ASSETS_DIR, "binwalk_assets") @@ -54,6 +54,7 @@ class BinwalkTestCase: ] +@pytest.mark.skipif_missing_deps([BinwalkAnalyzer]) @pytest.mark.parametrize("test_case", BINWALK_TEST_CASES, ids=lambda tc: tc.filename) async def test_binwalk_component(ofrak_context, test_case): asset_path = os.path.join(BINWALK_ASSETS_PATH, test_case.filename) diff --git a/ofrak_core/test_ofrak/components/test_cpio_component.py b/ofrak_core/test_ofrak/components/test_cpio_component.py index efbe2c3de..b3a2d9ad5 100644 --- a/ofrak_core/test_ofrak/components/test_cpio_component.py +++ b/ofrak_core/test_ofrak/components/test_cpio_component.py @@ -1,10 +1,13 @@ +import asyncio import os import subprocess -import tempfile +import tempfile312 as tempfile + +import pytest from ofrak import OFRAKContext from ofrak.resource import Resource -from ofrak.core.cpio import CpioFilesystem +from ofrak.core.cpio import CpioFilesystem, CpioPacker, CpioUnpacker from ofrak.core.strings import StringPatchingConfig, StringPatchingModifier from pytest_ofrak.patterns.unpack_modify_pack import UnpackModifyPackPattern @@ -14,6 +17,7 @@ CPIO_ENTRY_NAME = "hello_cpio_file" +@pytest.mark.skipif_missing_deps([CpioUnpacker, CpioPacker]) class TestCpioUnpackModifyPack(UnpackModifyPackPattern): async def create_root_resource(self, ofrak_context: OFRAKContext) -> Resource: with tempfile.TemporaryDirectory() as tmpdir: @@ -23,9 +27,20 @@ async def create_root_resource(self, ofrak_context: OFRAKContext) -> Resource: # Create a CPIO file from the current directory with open(CPIO_ENTRY_NAME, "wb") as f: f.write(INITIAL_DATA) - command = f"find {CPIO_ENTRY_NAME} -print | cpio -o > {TARGET_CPIO_FILE}" - subprocess.run(command, check=True, capture_output=True, shell=True) - result = await ofrak_context.create_root_resource_from_file(TARGET_CPIO_FILE) + cmd = ["cpio", "-o"] + proc = await asyncio.create_subprocess_exec( + *cmd, + cwd=tmpdir, + stdin=asyncio.subprocess.PIPE, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE + ) + stdout, stderr = await proc.communicate(CPIO_ENTRY_NAME.encode()) + if proc.returncode: + raise subprocess.CalledProcessError( + returncode=proc.returncode, cmd=cmd, stdout=stdout, stderr=stderr + ) + result = await ofrak_context.create_root_resource(name=TARGET_CPIO_FILE, data=stdout) os.chdir(wd) return result @@ -43,13 +58,20 @@ async def repack(self, cpio_resource: Resource) -> None: await cpio_resource.pack_recursively() async def verify(self, repacked_cpio_resource: Resource) -> None: - resource_data = await repacked_cpio_resource.get_data() - with tempfile.NamedTemporaryFile() as temp_file: - temp_file.write(resource_data) - temp_file.flush() - with tempfile.TemporaryDirectory() as temp_flush_dir: - command = f"(cd {temp_flush_dir} && cpio -id < {temp_file.name})" - subprocess.run(command, check=True, capture_output=True, shell=True) - with open(os.path.join(temp_flush_dir, CPIO_ENTRY_NAME), "rb") as f: - patched_data = f.read() - assert patched_data == EXPECTED_DATA + with tempfile.TemporaryDirectory() as temp_flush_dir: + cmd = ["cpio", "-id"] + proc = await asyncio.create_subprocess_exec( + *cmd, + cwd=temp_flush_dir, + stdin=asyncio.subprocess.PIPE, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE + ) + stdout, stderr = await proc.communicate(await repacked_cpio_resource.get_data()) + if proc.returncode: + raise subprocess.CalledProcessError( + returncode=proc.returncode, cmd=cmd, stdout=stdout, stderr=stderr + ) + with open(os.path.join(temp_flush_dir, CPIO_ENTRY_NAME), "rb") as f: + patched_data = f.read() + assert patched_data == EXPECTED_DATA diff --git a/ofrak_core/test_ofrak/components/test_elf_load_aligment_modifier.py b/ofrak_core/test_ofrak/components/test_elf_load_aligment_modifier.py index 504fbe4df..c73f9b0fa 100644 --- a/ofrak_core/test_ofrak/components/test_elf_load_aligment_modifier.py +++ b/ofrak_core/test_ofrak/components/test_elf_load_aligment_modifier.py @@ -1,6 +1,6 @@ import os import subprocess -import tempfile +import tempfile312 as tempfile from dataclasses import dataclass, field from typing import List, Optional @@ -96,6 +96,7 @@ async def verify_modifier_result(test_case: ElfModifierTestCase, output_path: st assert process.stdout == test_case.expect_stdout +@pytest.mark.skipif_windows class TestElfModifiers: @pytest.mark.parametrize( "test_case", diff --git a/ofrak_core/test_ofrak/components/test_elf_modifiers.py b/ofrak_core/test_ofrak/components/test_elf_modifiers.py index b302e45cc..21429c696 100644 --- a/ofrak_core/test_ofrak/components/test_elf_modifiers.py +++ b/ofrak_core/test_ofrak/components/test_elf_modifiers.py @@ -74,6 +74,7 @@ async def test_elf_add_symbols( assert result.returncode == 12 +@pytest.mark.skipif_windows async def test_elf_force_relocation( ofrak_context: OFRAKContext, elf_object_file, elf_test_directory ): diff --git a/ofrak_core/test_ofrak/components/test_extfs_component.py b/ofrak_core/test_ofrak/components/test_extfs_component.py index 503bd7d14..5bff6acbe 100644 --- a/ofrak_core/test_ofrak/components/test_extfs_component.py +++ b/ofrak_core/test_ofrak/components/test_extfs_component.py @@ -16,6 +16,9 @@ import test_ofrak.components +pytestmark = pytest.mark.skipif_missing_deps([ExtUnpacker]) + + @dataclass class ExtUnpackerTestCase(UnpackAndVerifyTestCase[str, bytes]): filename: str diff --git a/ofrak_core/test_ofrak/components/test_filesystem_component.py b/ofrak_core/test_ofrak/components/test_filesystem_component.py index 2dc2b088e..12773a2d9 100644 --- a/ofrak_core/test_ofrak/components/test_filesystem_component.py +++ b/ofrak_core/test_ofrak/components/test_filesystem_component.py @@ -4,7 +4,7 @@ import subprocess import sys import warnings -import tempfile +import tempfile312 as tempfile import pytest @@ -52,7 +52,7 @@ def filesystem_root_directory(tmp_path) -> str: if not os.path.exists(child_fifo): os.mkfifo(child_fifo) - if hasattr(os, "mkdev"): + if hasattr(os, "makedev"): block_device = os.path.join(tmp_path, DEVICE_NAME) if not os.path.exists(block_device): os.makedev(1, 2) @@ -175,6 +175,7 @@ async def test_remove_file(self, filesystem_root: FilesystemRoot): assert CHILD_TEXTFILE_NAME not in updated_list_dir_output +@pytest.mark.skipif_windows class TestFilesystemEntry: """ Test FilesystemEntry methods. @@ -327,7 +328,8 @@ def create_broken_symlink(self, root: str): async def create_root_resource(self, ofrak_context: OFRAKContext, directory: str) -> Resource: # Pack with command line `tar` because it supports symbolic links - with tempfile.NamedTemporaryFile(suffix=".tar") as archive: + with tempfile.NamedTemporaryFile(suffix=".tar", delete_on_close=False) as archive: + archive.close() command = ["tar", "--xattrs", "-C", directory, "-cf", archive.name, "."] subprocess.run(command, check=True, capture_output=True) @@ -340,12 +342,8 @@ async def repack(self, root_resource: Resource): await root_resource.pack_recursively() async def extract(self, root_resource: Resource, extract_dir: str): - with tempfile.NamedTemporaryFile(suffix=".tar") as tar: - data = await root_resource.get_data() - tar.write(data) - tar.flush() - - command = ["tar", "--xattrs", "-C", extract_dir, "-xf", tar.name] + async with root_resource.temp_to_disk(suffix=".tar") as tar_path: + command = ["tar", "--xattrs", "-C", extract_dir, "-xf", tar_path] subprocess.run(command, check=True, capture_output=True) diff --git a/ofrak_core/test_ofrak/components/test_general_filesystems.py b/ofrak_core/test_ofrak/components/test_general_filesystems.py index 27d8a5a74..f39da5084 100644 --- a/ofrak_core/test_ofrak/components/test_general_filesystems.py +++ b/ofrak_core/test_ofrak/components/test_general_filesystems.py @@ -1,5 +1,5 @@ import os -import tempfile +import tempfile312 as tempfile from abc import ABC from typing import Type, List @@ -9,9 +9,9 @@ from ofrak.core import FilesystemRoot, StringPatchingConfig, StringPatchingModifier from ofrak.model.viewable_tag_model import AttributesType from ofrak.resource import RV -from ofrak.core.cpio import CpioFilesystem, CpioArchiveType -from ofrak.core.tar import TarArchive -from ofrak.core.zip import ZipArchive +from ofrak.core.cpio import CpioFilesystem, CpioArchiveType, CpioPacker, CpioUnpacker +from ofrak.core.tar import TarArchive, TarPacker, TarUnpacker +from ofrak.core.zip import ZipArchive, ZipPacker, ZipUnpacker from pytest_ofrak.patterns.unpack_modify_pack import UnpackModifyPackPattern CHILD_TEXT = "Hello World\n" @@ -29,9 +29,13 @@ EXPECTED_SUBCHILD_TEXT = "Goodbye OFrak\n" TAGS = [ - (ZipArchive, []), - (TarArchive, []), - (CpioFilesystem, [AttributesType[CpioFilesystem](CpioArchiveType.BINARY)]), + pytest.param(ZipArchive, [], marks=pytest.mark.skipif_missing_deps([ZipUnpacker, ZipPacker])), + pytest.param(TarArchive, [], marks=pytest.mark.skipif_missing_deps([TarUnpacker, TarPacker])), + pytest.param( + CpioFilesystem, + [AttributesType[CpioFilesystem](CpioArchiveType.BINARY)], + marks=pytest.mark.skipif_missing_deps([CpioUnpacker, CpioPacker]), + ), ] diff --git a/ofrak_core/test_ofrak/components/test_gzip_component.py b/ofrak_core/test_ofrak/components/test_gzip_component.py index 9abc7ccb7..3bd17e112 100644 --- a/ofrak_core/test_ofrak/components/test_gzip_component.py +++ b/ofrak_core/test_ofrak/components/test_gzip_component.py @@ -11,7 +11,7 @@ from ofrak.ofrak_context import OFRAKContext from ofrak.resource import Resource -from ofrak.core.gzip import GzipData +from ofrak.core.gzip import GzipData, PIGZ from pytest_ofrak.patterns.compressed_filesystem_unpack_modify_pack import ( CompressedFileUnpackModifyPackPattern, ) @@ -59,7 +59,7 @@ def create_test_file(self, gzip_test_input: Tuple[bytes, bytes, bool], tmp_path: async def test_unpack_modify_pack(self, ofrak_context: OFRAKContext): with patch("asyncio.create_subprocess_exec", wraps=create_subprocess_exec) as mock_exec: - if self.EXPECT_PIGZ: + if self.EXPECT_PIGZ and await PIGZ.is_tool_installed(): await super().test_unpack_modify_pack(ofrak_context) assert any( args[0][0] == "pigz" and args[0][1] == "-c" for args in mock_exec.call_args_list diff --git a/ofrak_core/test_ofrak/components/test_ihex.py b/ofrak_core/test_ofrak/components/test_ihex.py index 2d8074b1f..dfe9cfae0 100644 --- a/ofrak_core/test_ofrak/components/test_ihex.py +++ b/ofrak_core/test_ofrak/components/test_ihex.py @@ -1,6 +1,7 @@ import os from dataclasses import dataclass +from ofrak.core.ihex import IhexPacker, IhexUnpacker import pytest from ofrak import OFRAKContext, Resource, ResourceFilter, ResourceAttributeRangeFilter @@ -25,6 +26,7 @@ class IhexTestCase(UnpackAndVerifyTestCase): ] +@pytest.mark.skipif_missing_deps([IhexPacker, IhexUnpacker]) class TestIhexUnpackPack(UnpackModifyPackPattern): REPLACEMENT_STRING = b"deadbeef ofrak" @@ -64,6 +66,7 @@ async def verify(self, repacked_root_resource: Resource) -> None: await repacked_root_resource.unpack_recursively() +@pytest.mark.skipif_missing_deps([IhexPacker, IhexUnpacker]) @pytest.mark.parametrize("ihex_file", IHEX_TEST_FILES) async def test_ihex_analyzer(ofrak_context: OFRAKContext, ihex_file): from bincopy import BinFile diff --git a/ofrak_core/test_ofrak/components/test_iso_component.py b/ofrak_core/test_ofrak/components/test_iso_component.py index 834353253..79e843bb3 100644 --- a/ofrak_core/test_ofrak/components/test_iso_component.py +++ b/ofrak_core/test_ofrak/components/test_iso_component.py @@ -11,6 +11,8 @@ ISO9660Entry, ISO9660Image, ISO9660ImageAttributes, + ISO9660Packer, + ISO9660Unpacker, ) from ofrak.core.strings import StringPatchingConfig, StringPatchingModifier from pytest_ofrak.patterns.compressed_filesystem_unpack_modify_pack import ( @@ -18,6 +20,7 @@ ) +@pytest.mark.skipif_missing_deps([ISO9660Packer, ISO9660Unpacker]) class Iso9660UnpackModifyPackPattern(CompressedFileUnpackModifyPackPattern): TEST_ISO_NAME = "test.iso" TEST_DIR_NAME = "/TEST" diff --git a/ofrak_core/test_ofrak/components/test_jffs2_component.py b/ofrak_core/test_ofrak/components/test_jffs2_component.py index cf987054e..f97f644e9 100644 --- a/ofrak_core/test_ofrak/components/test_jffs2_component.py +++ b/ofrak_core/test_ofrak/components/test_jffs2_component.py @@ -1,10 +1,12 @@ import os import subprocess -import tempfile +import tempfile312 as tempfile + +import pytest from ofrak import OFRAKContext from ofrak.resource import Resource -from ofrak.core.jffs2 import Jffs2Filesystem +from ofrak.core.jffs2 import Jffs2Filesystem, Jffs2Packer, Jffs2Unpacker from ofrak.core.strings import StringPatchingConfig, StringPatchingModifier from pytest_ofrak.patterns.unpack_modify_pack import UnpackModifyPackPattern @@ -14,6 +16,7 @@ JFFS2_ENTRY_NAME = "hello_jffs2_file" +@pytest.mark.skipif_missing_deps([Jffs2Packer, Jffs2Unpacker]) class TestJffs2UnpackModifyPack(UnpackModifyPackPattern): async def create_root_resource(self, ofrak_context: OFRAKContext) -> Resource: with tempfile.TemporaryDirectory() as tmpdir: @@ -41,12 +44,9 @@ async def repack(self, jffs2_resource: Resource) -> None: await jffs2_resource.pack_recursively() async def verify(self, repacked_jffs2_resource: Resource) -> None: - resource_data = await repacked_jffs2_resource.get_data() - with tempfile.NamedTemporaryFile() as temp_file: - temp_file.write(resource_data) - temp_file.flush() + async with repacked_jffs2_resource.temp_to_disk() as temp_path: with tempfile.TemporaryDirectory() as temp_flush_dir: - command = ["jefferson", "-f", "-d", temp_flush_dir, temp_file.name] + command = ["jefferson", "-f", "-d", temp_flush_dir, temp_path] subprocess.run(command, check=True, capture_output=True) with open(os.path.join(temp_flush_dir, JFFS2_ENTRY_NAME), "rb") as f: patched_data = f.read() diff --git a/ofrak_core/test_ofrak/components/test_lzo_component.py b/ofrak_core/test_ofrak/components/test_lzo_component.py index 7aacb5473..1249f608c 100644 --- a/ofrak_core/test_ofrak/components/test_lzo_component.py +++ b/ofrak_core/test_ofrak/components/test_lzo_component.py @@ -1,6 +1,6 @@ import subprocess -import tempfile +from ofrak.core.lzo import LzoPacker, LzoUnpacker import pytest from ofrak.resource import Resource @@ -9,6 +9,7 @@ ) +@pytest.mark.skipif_missing_deps([LzoUnpacker, LzoPacker]) class TestLzoUnpackModifyPack(CompressedFileUnpackModifyPackPattern): @pytest.fixture(autouse=True) def create_test_file(self, tmpdir): @@ -24,12 +25,8 @@ def create_test_file(self, tmpdir): self._test_file = compressed_filename async def verify(self, repacked_root_resource: Resource) -> None: - compressed_data = await repacked_root_resource.get_data() - with tempfile.NamedTemporaryFile(suffix=".lzo") as compressed_file: - compressed_file.write(compressed_data) - compressed_file.flush() - - command = ["lzop", "-d", "-f", "-c", compressed_file.name] + async with repacked_root_resource.temp_to_disk() as temp_path: + command = ["lzop", "-d", "-f", "-c", temp_path] result = subprocess.run(command, check=True, capture_output=True) assert result.stdout == self.EXPECTED_REPACKED_DATA diff --git a/ofrak_core/test_ofrak/components/test_openwrt_component.py b/ofrak_core/test_ofrak/components/test_openwrt_component.py index 5e37844ac..2ae9eb741 100644 --- a/ofrak_core/test_ofrak/components/test_openwrt_component.py +++ b/ofrak_core/test_ofrak/components/test_openwrt_component.py @@ -45,8 +45,6 @@ async def modify(self, resource: Resource) -> None: async def repack(self, resource: Resource) -> None: await resource.pack_recursively() - with open("/tmp/repacked", "wb") as f: - f.write(await resource.get_data()) async def verify(self, resource: Resource) -> None: resource_data = await resource.get_data() diff --git a/ofrak_core/test_ofrak/components/test_patch_symbol_resolution.py b/ofrak_core/test_ofrak/components/test_patch_symbol_resolution.py index 98505e2f7..6e42239cf 100644 --- a/ofrak_core/test_ofrak/components/test_patch_symbol_resolution.py +++ b/ofrak_core/test_ofrak/components/test_patch_symbol_resolution.py @@ -1,5 +1,5 @@ import pytest -import tempfile +import tempfile312 as tempfile from dataclasses import dataclass from immutabledict import immutabledict diff --git a/ofrak_core/test_ofrak/components/test_rar_unpacker.py b/ofrak_core/test_ofrak/components/test_rar_unpacker.py index b17c7cac9..2380e70cb 100644 --- a/ofrak_core/test_ofrak/components/test_rar_unpacker.py +++ b/ofrak_core/test_ofrak/components/test_rar_unpacker.py @@ -8,7 +8,7 @@ from ofrak.resource import Resource from ofrak import OFRAKContext -from ofrak.core.rar import RarArchive +from ofrak.core.rar import RarArchive, RarUnpacker from pytest_ofrak.patterns.unpack_verify import ( UnpackAndVerifyPattern, UnpackAndVerifyTestCase, @@ -26,6 +26,7 @@ class RarUnpackerTestCase(UnpackAndVerifyTestCase[str, bytes]): ] +@pytest.mark.skipif_missing_deps([RarUnpacker]) class TestRarUnpackAndVerify(UnpackAndVerifyPattern): @pytest.fixture(params=RAR_UNPACKER_TEST_CASES, ids=lambda tc: tc.label) async def unpack_verify_test_case(self, request) -> RarUnpackerTestCase: diff --git a/ofrak_core/test_ofrak/components/test_seven_zip_component.py b/ofrak_core/test_ofrak/components/test_seven_zip_component.py index f977bc4a4..4e02f9685 100644 --- a/ofrak_core/test_ofrak/components/test_seven_zip_component.py +++ b/ofrak_core/test_ofrak/components/test_seven_zip_component.py @@ -1,10 +1,12 @@ import os import subprocess -import tempfile +import tempfile312 as tempfile + +import pytest from ofrak import OFRAKContext from ofrak.resource import Resource -from ofrak.core.seven_zip import SevenZFilesystem +from ofrak.core.seven_zip import SevenZFilesystem, SevenZUnpacker, SevenzPacker from ofrak.core.strings import StringPatchingConfig, StringPatchingModifier from pytest_ofrak.patterns.unpack_modify_pack import UnpackModifyPackPattern @@ -15,6 +17,7 @@ SEVEN_ZIP_ENTRY_NAME = "hello_7z_file" +@pytest.mark.skipif_missing_deps([SevenZUnpacker, SevenzPacker]) class TestPzUnpackModifyPack(UnpackModifyPackPattern): async def create_root_resource(self, ofrak_context: OFRAKContext) -> Resource: with tempfile.TemporaryDirectory() as d: @@ -43,13 +46,9 @@ async def repack(self, seven_zip_resource: Resource) -> None: await seven_zip_resource.pack_recursively() async def verify(self, repacked_seven_zip_resource: Resource) -> None: - resource_data = await repacked_seven_zip_resource.get_data() - with tempfile.NamedTemporaryFile() as temp_file: - temp_file.write(resource_data) - temp_file.flush() - + async with repacked_seven_zip_resource.temp_to_disk(suffix=".7z") as temp_path: with tempfile.TemporaryDirectory() as temp_flush_dir: - command = ["7zz", "x", f"-o{temp_flush_dir}", temp_file.name] + command = ["7zz", "x", f"-o{temp_flush_dir}", temp_path] subprocess.run(command, check=True, capture_output=True) with open(os.path.join(temp_flush_dir, SEVEN_ZIP_ENTRY_NAME), "rb") as f: patched_data = f.read() diff --git a/ofrak_core/test_ofrak/components/test_squashfs_component.py b/ofrak_core/test_ofrak/components/test_squashfs_component.py index 3002d246e..6a0fd85fe 100644 --- a/ofrak_core/test_ofrak/components/test_squashfs_component.py +++ b/ofrak_core/test_ofrak/components/test_squashfs_component.py @@ -1,10 +1,12 @@ import os import subprocess -import tempfile +import tempfile312 as tempfile + +import pytest from ofrak import OFRAKContext from ofrak.resource import Resource -from ofrak.core.squashfs import SquashfsFilesystem +from ofrak.core.squashfs import SquashfsFilesystem, SquashfsPacker, SquashfsUnpacker from ofrak.core.strings import StringPatchingConfig, StringPatchingModifier from pytest_ofrak.patterns.unpack_modify_pack import UnpackModifyPackPattern @@ -14,6 +16,7 @@ SQUASH_ENTRY_NAME = "hello_squash_file" +@pytest.mark.skipif_missing_deps([SquashfsUnpacker, SquashfsPacker]) class TestSquashfsUnpackModifyPack(UnpackModifyPackPattern): async def create_root_resource(self, ofrak_context: OFRAKContext) -> Resource: with tempfile.TemporaryDirectory() as tmpdir: @@ -40,12 +43,9 @@ async def repack(self, squashfs_resource: Resource) -> None: await squashfs_resource.pack_recursively() async def verify(self, repacked_squashfs_resource: Resource) -> None: - resource_data = await repacked_squashfs_resource.get_data() - with tempfile.NamedTemporaryFile() as temp_file: - temp_file.write(resource_data) - temp_file.flush() + async with repacked_squashfs_resource.temp_to_disk() as temp_path: with tempfile.TemporaryDirectory() as temp_flush_dir: - command = ["unsquashfs", "-f", "-d", temp_flush_dir, temp_file.name] + command = ["unsquashfs", "-f", "-d", temp_flush_dir, temp_path] subprocess.run(command, check=True, capture_output=True) with open(os.path.join(temp_flush_dir, SQUASH_ENTRY_NAME), "rb") as f: patched_data = f.read() diff --git a/ofrak_core/test_ofrak/components/test_string.py b/ofrak_core/test_ofrak/components/test_string.py index df5f249fc..66ca9c8e8 100644 --- a/ofrak_core/test_ofrak/components/test_string.py +++ b/ofrak_core/test_ofrak/components/test_string.py @@ -1,6 +1,5 @@ -import os +from pathlib import Path import pytest -import subprocess from typing import List @@ -19,44 +18,6 @@ StringFindReplaceModifier, ) -STRING_TEST_C_SOURCE = r""" -#include - -extern int longString(void); -extern int shortString(void); - -// Generate bytes that look like a long ascii string (21 bytes) that will be matched as a string -// by the AsciiUnpacker. Assumes running on x86. -__asm__(".global longString\n\t" - ".type longString, @function\n\t" - "push %r15\n\t" - "push %r15\n\t" - "push %r15\n\t" - "push %r15\n\t" - "push %r15\n\t" - "push %r15\n\t" - "push %r15\n\t" - "push %r15\n\t" - "and 0, %r15\n\t" -); - -// Generate bytes that look like a short ascii string (7 bytes) that will not be matched as a string -// by the AsciiUnpacker because of the min length requirement. Assumes running on x86. -__asm__(".global shortString\n\t" - ".type shortString, @function\n\t" - "push %r15\n\t" - "and 0, %r15\n\t" -); - -int main() { - printf("O"); - printf("h, hi"); - printf(" Marc!"); - printf("You are tearing me apart, Lisa!"); - return 0; -} -""" - @pytest.fixture async def resource(ofrak_context: OFRAKContext) -> Resource: @@ -74,21 +35,8 @@ async def resource(ofrak_context: OFRAKContext) -> Resource: @pytest.fixture -def string_test_directory(tmpdir): - c_source_path = os.path.join(tmpdir, "string_test.c") - - with open(c_source_path, "w") as f: - f.write(STRING_TEST_C_SOURCE) - - return tmpdir - - -@pytest.fixture -def executable_file(string_test_directory): - source = os.path.join(string_test_directory, "string_test.c") - executable = os.path.join(string_test_directory, "string_test.out") - subprocess.run(["gcc", "-o", executable, source]) - return executable +def executable_file(): + return Path(__file__).parent / "assets" / "string_test.out" @pytest.fixture diff --git a/ofrak_core/test_ofrak/components/test_strings_analyzer.py b/ofrak_core/test_ofrak/components/test_strings_analyzer.py index f7a318167..bde3c969f 100644 --- a/ofrak_core/test_ofrak/components/test_strings_analyzer.py +++ b/ofrak_core/test_ofrak/components/test_strings_analyzer.py @@ -49,6 +49,7 @@ async def test_case( ) +@pytest.mark.skipif_missing_deps([StringsAnalyzer]) class TestStringsAnalyzer(AnalyzerTests): async def test_resource_analyzer(self, test_case: PopulatedAnalyzerTestCase): with pytest.raises( diff --git a/ofrak_core/test_ofrak/components/test_tar_component.py b/ofrak_core/test_ofrak/components/test_tar_component.py index dbf52ecc9..e42a18b48 100644 --- a/ofrak_core/test_ofrak/components/test_tar_component.py +++ b/ofrak_core/test_ofrak/components/test_tar_component.py @@ -1,6 +1,6 @@ import os import subprocess -import tempfile +import tempfile312 as tempfile import pytest @@ -8,13 +8,15 @@ from ofrak.component.unpacker import UnpackerError from ofrak.resource import Resource from ofrak.core.strings import StringPatchingConfig, StringPatchingModifier -from ofrak.core.tar import TarArchive +from ofrak.core.tar import TarArchive, TarPacker, TarUnpacker from pytest_ofrak.patterns.pack_unpack_filesystem import ( FilesystemPackUnpackVerifyPattern, ) from pytest_ofrak.patterns.unpack_modify_pack import UnpackModifyPackPattern import test_ofrak.components +pytestmark = pytest.mark.skipif_missing_deps([TarUnpacker, TarPacker]) + class TestTarSingleFileUnpackModifyPack(UnpackModifyPackPattern): INITIAL_DATA = b"hello world" @@ -113,7 +115,8 @@ def setup(self): self.check_stat = False async def create_root_resource(self, ofrak_context: OFRAKContext, directory: str) -> Resource: - with tempfile.NamedTemporaryFile(suffix=".tar") as archive: + with tempfile.NamedTemporaryFile(suffix=".tar", delete_on_close=False) as archive: + archive.close() command = ["tar", "--xattrs", "-C", directory, "-cf", archive.name, "."] subprocess.run(command, check=True, capture_output=True) @@ -126,12 +129,8 @@ async def repack(self, root_resource: Resource): await root_resource.pack_recursively() async def extract(self, root_resource: Resource, extract_dir: str): - with tempfile.NamedTemporaryFile(suffix=".tar") as tar: - data = await root_resource.get_data() - tar.write(data) - tar.flush() - - command = ["tar", "--xattrs", "-C", extract_dir, "-xf", tar.name] + async with root_resource.temp_to_disk(suffix=".tar") as tar_path: + command = ["tar", "--xattrs", "-C", extract_dir, "-xf", tar_path] subprocess.run(command, check=True, capture_output=True) @@ -221,10 +220,6 @@ async def repack(self, root_resource: Resource): await root_resource.pack_recursively() async def extract(self, root_resource: Resource, extract_dir: str): - with tempfile.NamedTemporaryFile(suffix=".tar") as tar: - data = await root_resource.get_data() - tar.write(data) - tar.flush() - - command = ["tar", "--xattrs", "-C", extract_dir, "-xf", tar.name] + async with root_resource.temp_to_disk(suffix=".tar") as tar_path: + command = ["tar", "--xattrs", "-C", extract_dir, "-xf", tar_path] subprocess.run(command, check=True, capture_output=True) diff --git a/ofrak_core/test_ofrak/components/test_ubi.py b/ofrak_core/test_ofrak/components/test_ubi.py index c6c1bd9b2..a8abb496b 100644 --- a/ofrak_core/test_ofrak/components/test_ubi.py +++ b/ofrak_core/test_ofrak/components/test_ubi.py @@ -1,9 +1,11 @@ import hashlib import os +import pytest + from ofrak import OFRAKContext, ResourceSort from ofrak.resource import Resource -from ofrak.core.ubi import Ubi, UbiVolume +from ofrak.core.ubi import Ubi, UbiPacker, UbiUnpacker, UbiVolume from pytest_ofrak.patterns.compressed_filesystem_unpack_modify_pack import ( CompressedFileUnpackModifyPackPattern, @@ -20,6 +22,7 @@ ) +@pytest.mark.skipif_missing_deps([UbiUnpacker, UbiPacker]) class TestUbiUnpackModifyPack(CompressedFileUnpackModifyPackPattern): async def create_root_resource(self, ofrak_context: OFRAKContext) -> Resource: """ diff --git a/ofrak_core/test_ofrak/components/test_ubifs.py b/ofrak_core/test_ofrak/components/test_ubifs.py index 8c703c9e5..7d044428e 100644 --- a/ofrak_core/test_ofrak/components/test_ubifs.py +++ b/ofrak_core/test_ofrak/components/test_ubifs.py @@ -1,13 +1,17 @@ import subprocess -import tempfile +import tempfile312 as tempfile + +import pytest from ofrak import OFRAKContext +from ofrak.core.ubifs import UbifsPacker, UbifsUnpacker from ofrak.resource import Resource from pytest_ofrak.patterns.pack_unpack_filesystem import FilesystemPackUnpackVerifyPattern # from pytest_ofrak.patterns.unpack_modify_pack import UnpackPackPattern +@pytest.mark.skipif_missing_deps([UbifsUnpacker, UbifsPacker]) class TestUbifsUnpackRepack(FilesystemPackUnpackVerifyPattern): def setup(self): super().setup() @@ -18,7 +22,8 @@ async def create_root_resource(self, ofrak_context: OFRAKContext, directory: str """ Generated the test UBIFS image with the assistance of the FilesystemPackUnpackVerify test pattern. """ - with tempfile.NamedTemporaryFile() as ubifs_blob: + with tempfile.NamedTemporaryFile(delete_on_close=False) as ubifs_blob: + ubifs_blob.close() command = [ "mkfs.ubifs", "-m", @@ -46,11 +51,7 @@ async def extract(self, root_resource: Resource, extract_dir: str) -> None: expected by the FilesystemPackUnpackVerify pattern. """ - with tempfile.NamedTemporaryFile() as ubifs_blob: - data = await root_resource.get_data() - ubifs_blob.write(data) - ubifs_blob.flush() - - command = ["ubireader_extract_files", "-k", "-o", extract_dir, ubifs_blob.name] + async with root_resource.temp_to_disk() as ubifs_blob_path: + command = ["ubireader_extract_files", "-k", "-o", extract_dir, ubifs_blob_path] subprocess.run(command, check=True, capture_output=True) diff --git a/ofrak_core/test_ofrak/components/test_uefi_component.py b/ofrak_core/test_ofrak/components/test_uefi_component.py index 77b292189..69db1947d 100644 --- a/ofrak_core/test_ofrak/components/test_uefi_component.py +++ b/ofrak_core/test_ofrak/components/test_uefi_component.py @@ -2,7 +2,7 @@ import os.path from dataclasses import dataclass from typing import Dict -from ofrak.core.uefi import Uefi +from ofrak.core.uefi import Uefi, UefiUnpacker from ofrak.core.filesystem import File, FilesystemEntry from ofrak.resource import Resource from ofrak import OFRAKContext @@ -36,6 +36,7 @@ class UefiComponentTestCase(UnpackAndVerifyTestCase[str, bytes]): ] +@pytest.mark.skipif_missing_deps([UefiUnpacker]) class TestUefiComponent(UnpackAndVerifyPattern): @pytest.fixture(params=UEFI_COMPONENT_TEST_CASE, ids=lambda tc: tc.label) async def unpack_verify_test_case(self, request) -> UnpackAndVerifyTestCase: diff --git a/ofrak_core/test_ofrak/components/test_uf2_component.py b/ofrak_core/test_ofrak/components/test_uf2_component.py index ca0801653..cbdd689c5 100644 --- a/ofrak_core/test_ofrak/components/test_uf2_component.py +++ b/ofrak_core/test_ofrak/components/test_uf2_component.py @@ -1,4 +1,5 @@ import logging +import pytest from ofrak.core.addressable import Addressable from ofrak.core.memory_region import MemoryRegion from pathlib import Path @@ -6,7 +7,7 @@ from ofrak.ofrak_context import OFRAKContext from ofrak.resource import Resource from ofrak.service.resource_service_i import ResourceAttributeRangeFilter, ResourceFilter -from ofrak.core.uf2 import Uf2File +from ofrak.core.uf2 import Uf2File, Uf2FilePacker, Uf2Unpacker from ofrak.core.strings import StringPatchingModifier, StringPatchingConfig import test_ofrak.components @@ -25,6 +26,7 @@ async def test_uf2_identify(ofrak_context: OFRAKContext) -> None: assert root_resource.has_tag(Uf2File), "Expected resource to have tag Uf2File" +@pytest.mark.skipif_missing_deps([Uf2FilePacker, Uf2Unpacker]) class TestUf2UnpackModifyPack(UnpackModifyPackPattern): async def create_root_resource(self, ofrak_context: OFRAKContext) -> Resource: asset_path = Path(test_ofrak.components.ASSETS_DIR, FILENAME) diff --git a/ofrak_core/test_ofrak/components/test_uimage_component.py b/ofrak_core/test_ofrak/components/test_uimage_component.py index aa0cfd17c..efe50cafc 100644 --- a/ofrak_core/test_ofrak/components/test_uimage_component.py +++ b/ofrak_core/test_ofrak/components/test_uimage_component.py @@ -1,5 +1,6 @@ import os import subprocess +import shutil import pytest @@ -37,6 +38,9 @@ async def uimage_resource(ofrak_context, request) -> Resource: return await ofrak_context.create_root_resource_from_file(uimage_path) +@pytest.mark.skipif( + shutil.which("mkimage") is None, reason="Test requires mkimage from u-boot-tools" +) async def test_uimage_unpack_modify_pack(uimage_resource: Resource, tmpdir): """Test unpacking, modifying and then repacking a UImage file.""" await uimage_resource.unpack_recursively() diff --git a/ofrak_core/test_ofrak/components/test_zstd_component.py b/ofrak_core/test_ofrak/components/test_zstd_component.py index 3064ed158..c0b5ea884 100644 --- a/ofrak_core/test_ofrak/components/test_zstd_component.py +++ b/ofrak_core/test_ofrak/components/test_zstd_component.py @@ -1,6 +1,7 @@ import subprocess -import tempfile +import tempfile312 as tempfile +from ofrak.core.zstd import ZstdUnpacker, ZstdPacker import pytest from ofrak.resource import Resource @@ -9,6 +10,7 @@ ) +@pytest.mark.skipif_missing_deps([ZstdUnpacker, ZstdPacker]) class TestZstdUnpackModifyPack(CompressedFileUnpackModifyPackPattern): @pytest.fixture(autouse=True) def create_test_file(self, tmpdir): @@ -24,13 +26,10 @@ def create_test_file(self, tmpdir): self._test_file = compressed_filename async def verify(self, repacked_root_resource: Resource) -> None: - compressed_data = await repacked_root_resource.get_data() - with tempfile.NamedTemporaryFile(suffix=".zstd") as compressed_file: - compressed_file.write(compressed_data) - compressed_file.flush() + async with repacked_root_resource.temp_to_disk(suffix=".zstd") as compressed_file_path: output_filename = tempfile.mktemp() - command = ["zstd", "-d", "-k", compressed_file.name, "-o", output_filename] + command = ["zstd", "-d", "-k", compressed_file_path, "-o", output_filename] subprocess.run(command, check=True, capture_output=True) with open(output_filename, "rb") as f: result = f.read() diff --git a/ofrak_core/test_ofrak/conftest.py b/ofrak_core/test_ofrak/conftest.py index 41b447e0e..15aebc86b 100644 --- a/ofrak_core/test_ofrak/conftest.py +++ b/ofrak_core/test_ofrak/conftest.py @@ -1 +1 @@ -pytest_plugins = ["pytest_ofrak.fixtures", "pytest_ofrak.elf.fixtures"] +pytest_plugins = ["pytest_ofrak.fixtures", "pytest_ofrak.elf.fixtures", "pytest_ofrak.mark"] diff --git a/ofrak_core/test_ofrak/unit/component/test_component_external_tool.py b/ofrak_core/test_ofrak/unit/component/test_component_external_tool.py index 70e910bbd..141c45ebe 100644 --- a/ofrak_core/test_ofrak/unit/component/test_component_external_tool.py +++ b/ofrak_core/test_ofrak/unit/component/test_component_external_tool.py @@ -1,5 +1,7 @@ import os.path import subprocess +import os +import sys import pytest @@ -81,7 +83,7 @@ class _MockComponent(Unpacker): children = () async def unpack(self, resource, config=None): - subprocess.run(["cat", os.path.join(tmpdir, "nonexistant_file")], check=True) + subprocess.run([sys.executable, os.path.join(tmpdir, "nonexistent_script")], check=True) return unpacker = _MockComponent( @@ -106,8 +108,8 @@ async def unpack(self, resource, config=None): async def test_tool_install_check(mock_dependency): assert not await mock_dependency.is_tool_installed() - echo_tool = ComponentExternalTool("echo", "", install_check_arg=".") - assert await echo_tool.is_tool_installed() + cd_tool = ComponentExternalTool(sys.executable, "", install_check_arg="-v") + assert await cd_tool.is_tool_installed() async def test_bad_tool_install_check(bad_dependency): diff --git a/ofrak_core/test_ofrak/unit/test_ofrak_context.py b/ofrak_core/test_ofrak/unit/test_ofrak_context.py index 93eb23ca9..9f187799d 100644 --- a/ofrak_core/test_ofrak/unit/test_ofrak_context.py +++ b/ofrak_core/test_ofrak/unit/test_ofrak_context.py @@ -5,12 +5,11 @@ from tempfile import TemporaryDirectory import os from ofrak import OFRAK, OFRAKContext -from ofrak.core.apk import ApkIdentifier from ofrak.resource import Resource from ofrak.ofrak_context import get_current_ofrak_context from ofrak_type.error import NotFoundError, InvalidStateError from pytest_ofrak import mock_library3 -from pytest_ofrak.mock_library3 import _MockComponentA +from pytest_ofrak.mock_library3 import _MockComponentA, _MockComponentSysExec from ofrak.core.filesystem import FilesystemRoot @@ -42,7 +41,7 @@ async def run_component_with_bad_dependency(ofrak_context: OFRAKContext): async def run_component_with_installed_dependency(ofrak_context: OFRAKContext): resource = await ofrak_context.create_root_resource("test_binary", b"") - await resource.run(ApkIdentifier) + await resource.run(_MockComponentSysExec) ofrak = OFRAK(logging_level=logging.WARNING, exclude_components_missing_dependencies=True) ofrak.discover(mock_library3) diff --git a/ofrak_core/test_ofrak/unit/test_resource.py b/ofrak_core/test_ofrak/unit/test_resource.py index efcb9ea03..445de6a06 100644 --- a/ofrak_core/test_ofrak/unit/test_resource.py +++ b/ofrak_core/test_ofrak/unit/test_resource.py @@ -1,4 +1,4 @@ -import tempfile +import tempfile312 as tempfile from dataclasses import dataclass from io import BytesIO from typing import List, Tuple @@ -209,7 +209,9 @@ async def test_flush_to_disk_pack(ofrak_context: OFRAKContext): # this should not fail because pack_recursively was suppressed await root_resource.write_to(buffer, pack=False) - with tempfile.NamedTemporaryFile() as t: + with tempfile.NamedTemporaryFile(delete_on_close=False) as t: + t.close() + # again, should fail because the packer is run automatically with pytest.raises(MockFailException): await root_resource.flush_data_to_disk(t.name)