Skip to content

Commit d78a030

Browse files
fix: Crashing when files field is empty (#166)
* Fix issue with managing challenges with an empty files section --------- Signed-off-by: AlexNg <[email protected]>
1 parent 763c2de commit d78a030

File tree

1 file changed

+22
-15
lines changed

1 file changed

+22
-15
lines changed

ctfcli/core/challenge.py

+22-15
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,8 @@ def _load_challenge_id(self):
251251
raise RemoteChallengeNotFound(f"Could not load remote challenge with name '{self['name']}'")
252252

253253
def _validate_files(self):
254-
# if the challenge defines files, make sure they exist before making any changes to the challenge
255-
for challenge_file in self.get("files", []):
254+
files = self.get("files") or []
255+
for challenge_file in files:
256256
if not (self.challenge_directory / challenge_file).exists():
257257
raise InvalidChallengeFile(f"File {challenge_file} could not be loaded")
258258

@@ -364,7 +364,9 @@ def _create_file(self, local_path: Path):
364364

365365
def _create_all_files(self):
366366
new_files = []
367-
for challenge_file in self["files"]:
367+
368+
files = self.get("files") or []
369+
for challenge_file in files:
368370
new_files.append(("file", open(self.challenge_directory / challenge_file, mode="rb")))
369371

370372
files_payload = {"challenge_id": self.challenge_id, "type": "challenge"}
@@ -587,9 +589,12 @@ def sync(self, ignore: Tuple[str] = ()) -> None:
587589

588590
# Create / Upload files
589591
if "files" not in ignore:
592+
self["files"] = self.get("files") or []
593+
remote_challenge["files"] = remote_challenge.get("files") or []
594+
590595
# Get basenames of local files to compare against remote files
591-
local_files = {f.split("/")[-1]: f for f in self.get("files", [])}
592-
remote_files = self._normalize_remote_files(remote_challenge.get("files", []))
596+
local_files = {f.split("/")[-1]: f for f in self["files"]}
597+
remote_files = self._normalize_remote_files(remote_challenge["files"])
593598

594599
# Delete remote files which are no longer defined locally
595600
for remote_file in remote_files:
@@ -761,8 +766,8 @@ def lint(self, skip_hadolint=False, flag_format="flag{") -> bool:
761766
click.secho("Skipping Hadolint", fg="yellow")
762767

763768
# Check that all files exist
764-
challenge_files = challenge.get("files", [])
765-
for challenge_file in challenge_files:
769+
files = self.get("files") or []
770+
for challenge_file in files:
766771
challenge_file_path = self.challenge_directory / challenge_file
767772

768773
if challenge_file_path.is_file() is False:
@@ -771,8 +776,7 @@ def lint(self, skip_hadolint=False, flag_format="flag{") -> bool:
771776
)
772777

773778
# Check that files don't have a flag in them
774-
challenge_files = challenge.get("files", [])
775-
for challenge_file in challenge_files:
779+
for challenge_file in files:
776780
challenge_file_path = self.challenge_directory / challenge_file
777781

778782
if not challenge_file_path.exists():
@@ -794,9 +798,12 @@ def mirror(self, files_directory_name: str = "dist", ignore: Tuple[str] = ()) ->
794798
remote_challenge = self.load_installed_challenge(self.challenge_id)
795799
challenge = self._normalize_challenge(remote_challenge)
796800

801+
remote_challenge["files"] = remote_challenge.get("files") or []
802+
challenge["files"] = challenge.get("files") or []
803+
797804
# Add files which are not handled in _normalize_challenge
798805
if "files" not in ignore:
799-
local_files = {Path(f).name: f for f in challenge.get("files", [])}
806+
local_files = {Path(f).name: f for f in challenge["files"]}
800807

801808
# Update files
802809
for remote_file in remote_challenge["files"]:
@@ -813,9 +820,6 @@ def mirror(self, files_directory_name: str = "dist", ignore: Tuple[str] = ()) ->
813820
challenge_files_directory.mkdir(parents=True, exist_ok=True)
814821

815822
(challenge_files_directory / remote_file_name).write_bytes(r.content)
816-
if "files" not in challenge:
817-
challenge["files"] = []
818-
819823
challenge["files"].append(f"{files_directory_name}/{remote_file_name}")
820824

821825
# The file is already present in the challenge.yml - we know the desired path
@@ -827,7 +831,7 @@ def mirror(self, files_directory_name: str = "dist", ignore: Tuple[str] = ()) ->
827831
# Soft-Delete files that are not present on the remote
828832
# Remove them from challenge.yml but do not delete them from disk
829833
remote_file_names = [f.split("/")[-1].split("?token=")[0] for f in remote_challenge["files"]]
830-
challenge["files"] = [f for f in challenge.get("files", []) if Path(f).name in remote_file_names]
834+
challenge["files"] = [f for f in challenge["files"] if Path(f).name in remote_file_names]
831835

832836
for key in challenge.keys():
833837
if key not in ignore:
@@ -841,6 +845,9 @@ def verify(self, ignore: Tuple[str] = ()) -> bool:
841845
remote_challenge = self.load_installed_challenge(self.challenge_id)
842846
normalized_challenge = self._normalize_challenge(remote_challenge)
843847

848+
remote_challenge["files"] = remote_challenge.get("files") or []
849+
challenge["files"] = challenge.get("files") or []
850+
844851
for key in normalized_challenge:
845852
if key in ignore:
846853
continue
@@ -865,7 +872,7 @@ def verify(self, ignore: Tuple[str] = ()) -> bool:
865872
# Check if files defined in challenge.yml are present
866873
try:
867874
self._validate_files()
868-
local_files = {Path(f).name: f for f in challenge.get("files", [])}
875+
local_files = {Path(f).name: f for f in challenge["files"]}
869876
except InvalidChallengeFile:
870877
return False
871878

0 commit comments

Comments
 (0)