ShadowB 0.1__tar.gz → 0.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. {shadowb-0.1 → shadowb-0.3}/PKG-INFO +14 -3
  2. {shadowb-0.1 → shadowb-0.3}/README.md +5 -2
  3. {shadowb-0.1 → shadowb-0.3}/ShadowB/GetD/scan.py +3 -15
  4. {shadowb-0.1 → shadowb-0.3}/ShadowB/__init__.py +0 -1
  5. {shadowb-0.1 → shadowb-0.3}/ShadowB/core.py +2 -14
  6. {shadowb-0.1 → shadowb-0.3}/ShadowB.egg-info/PKG-INFO +14 -3
  7. {shadowb-0.1 → shadowb-0.3}/ShadowB.egg-info/SOURCES.txt +2 -7
  8. shadowb-0.3/ShadowB.egg-info/requires.txt +8 -0
  9. {shadowb-0.1 → shadowb-0.3}/pyproject.toml +13 -1
  10. shadowb-0.1/ShadowB/Qrcode/scan.py +0 -26
  11. shadowb-0.1/ShadowB/Safe/clean.py +0 -127
  12. shadowb-0.1/ShadowB/Safe/cleanText.py +0 -37
  13. shadowb-0.1/ShadowB/Safe/ext.py +0 -5
  14. shadowb-0.1/ShadowB/Safe/filename.py +0 -6
  15. shadowb-0.1/ShadowB/Safe/safeFile.py +0 -171
  16. {shadowb-0.1 → shadowb-0.3}/LICENSE +0 -0
  17. {shadowb-0.1 → shadowb-0.3}/ShadowB/Core/fileorg.py +0 -0
  18. {shadowb-0.1 → shadowb-0.3}/ShadowB/Core/randwords.py +0 -0
  19. {shadowb-0.1 → shadowb-0.3}/ShadowB/GetD/make_cookies.py +0 -0
  20. {shadowb-0.1 → shadowb-0.3}/ShadowB/GetD/my_data.py +0 -0
  21. {shadowb-0.1 → shadowb-0.3}/ShadowB/GetD/my_ip.py +0 -0
  22. {shadowb-0.1 → shadowb-0.3}/ShadowB/Image/check_image.py +0 -0
  23. {shadowb-0.1 → shadowb-0.3}/ShadowB/Image/export_metadata.py +0 -0
  24. {shadowb-0.1 → shadowb-0.3}/ShadowB/Image/extr_hidden_files.py +0 -0
  25. {shadowb-0.1 → shadowb-0.3}/ShadowB/Image/extr_hidden_text.py +0 -0
  26. {shadowb-0.1 → shadowb-0.3}/ShadowB/Image/makeFile.py +0 -0
  27. {shadowb-0.1 → shadowb-0.3}/ShadowB/Image/makeText.py +0 -0
  28. {shadowb-0.1 → shadowb-0.3}/ShadowB/Image/remove_metadata.py +0 -0
  29. {shadowb-0.1 → shadowb-0.3}/ShadowB/Mail/make_mail.py +0 -0
  30. {shadowb-0.1 → shadowb-0.3}/ShadowB/Mail/res_msj.py +0 -0
  31. {shadowb-0.1 → shadowb-0.3}/ShadowB/Mail/send_msj.py +0 -0
  32. {shadowb-0.1 → shadowb-0.3}/ShadowB/Qrcode/generate.py +0 -0
  33. {shadowb-0.1 → shadowb-0.3}/ShadowB/captcha.py +0 -0
  34. {shadowb-0.1 → shadowb-0.3}/ShadowB/getD.py +0 -0
  35. {shadowb-0.1 → shadowb-0.3}/ShadowB/image.py +0 -0
  36. {shadowb-0.1 → shadowb-0.3}/ShadowB/mail.py +0 -0
  37. {shadowb-0.1 → shadowb-0.3}/ShadowB/passwords.py +0 -0
  38. {shadowb-0.1 → shadowb-0.3}/ShadowB/qrcode.py +0 -0
  39. {shadowb-0.1 → shadowb-0.3}/ShadowB/safe.py +0 -0
  40. {shadowb-0.1 → shadowb-0.3}/ShadowB/search.py +0 -0
  41. {shadowb-0.1 → shadowb-0.3}/ShadowB.egg-info/dependency_links.txt +0 -0
  42. {shadowb-0.1 → shadowb-0.3}/ShadowB.egg-info/top_level.txt +0 -0
  43. {shadowb-0.1 → shadowb-0.3}/setup.cfg +0 -0
@@ -1,14 +1,25 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ShadowB
3
- Version: 0.1
3
+ Version: 0.3
4
4
  Summary: ShadowB is an all-in-one Python toolkit that bundles a wide range of everyday utilities — system info, image steganography, temporary email, QR codes, CAPTCHA generation, password tools, file safety checks, and more — into a single, easy-to-import package.
5
5
  Author-email: Adem mzoughi <ademzoughi1312@gmail.com>
6
6
  Requires-Python: >=3.8
7
7
  Description-Content-Type: text/markdown
8
8
  License-File: LICENSE
9
+ Requires-Dist: requests
10
+ Requires-Dist: colorama
11
+ Requires-Dist: better_profanity
12
+ Requires-Dist: pillow
13
+ Requires-Dist: pypdf
14
+ Requires-Dist: qrcode
15
+ Requires-Dist: stepic
16
+ Requires-Dist: browser-cookie3
9
17
 
10
18
  # ShadowB
11
19
 
20
+ ![ShadowB Logo](https://raw.githubusercontent.com/erec2smith/ShadowB/main/shadowb.jpg)
21
+
22
+
12
23
  **ShadowB** is an all-in-one Python toolkit that bundles a wide range of everyday utilities — system info, image steganography, temporary email, QR codes, CAPTCHA generation, password tools, file safety checks, and more — into a single, easy-to-import package.
13
24
 
14
25
  Instead of installing and learning a dozen different libraries for a dozen small tasks, `ShadowB` collects the most commonly needed helper functions in one place.
@@ -48,7 +59,7 @@ Basic package metadata and bootstrapping.
48
59
  ```python
49
60
  from ShadowB import core
50
61
 
51
- core.start() # run core app fro : create passwords or usernames / organize the working files
62
+ core.start() # run core app for : create passwords or usernames / organize the working files
52
63
  core.owner() # -> "Adem mzoughi"
53
64
  core.team() # -> "Adem mzoughi, Berlin, Shadow"
54
65
  core.hp() # print help / usage info
@@ -109,7 +120,7 @@ Generate and read QR codes.
109
120
  from ShadowB import qrcode
110
121
 
111
122
  qrcode.generate_qrcode(text, "qr") # create a QR code image
112
- qrcode.scan_qrcode("qr.png") # -> decoded text (str)
123
+
113
124
  ```
114
125
 
115
126
  ---
@@ -1,5 +1,8 @@
1
1
  # ShadowB
2
2
 
3
+ ![ShadowB Logo](https://raw.githubusercontent.com/erec2smith/ShadowB/main/shadowb.jpg)
4
+
5
+
3
6
  **ShadowB** is an all-in-one Python toolkit that bundles a wide range of everyday utilities — system info, image steganography, temporary email, QR codes, CAPTCHA generation, password tools, file safety checks, and more — into a single, easy-to-import package.
4
7
 
5
8
  Instead of installing and learning a dozen different libraries for a dozen small tasks, `ShadowB` collects the most commonly needed helper functions in one place.
@@ -39,7 +42,7 @@ Basic package metadata and bootstrapping.
39
42
  ```python
40
43
  from ShadowB import core
41
44
 
42
- core.start() # run core app fro : create passwords or usernames / organize the working files
45
+ core.start() # run core app for : create passwords or usernames / organize the working files
43
46
  core.owner() # -> "Adem mzoughi"
44
47
  core.team() # -> "Adem mzoughi, Berlin, Shadow"
45
48
  core.hp() # print help / usage info
@@ -100,7 +103,7 @@ Generate and read QR codes.
100
103
  from ShadowB import qrcode
101
104
 
102
105
  qrcode.generate_qrcode(text, "qr") # create a QR code image
103
- qrcode.scan_qrcode("qr.png") # -> decoded text (str)
106
+
104
107
  ```
105
108
 
106
109
  ---
@@ -5,26 +5,14 @@ try:
5
5
  from colorama import Fore, Style, init
6
6
  init(autoreset=True)
7
7
  except ImportError:
8
- print("[-] 'colorama' library is missing. Attempting to install it now...")
9
- try:
10
-
11
- os.system(f"{sys.executable} -m pip install colorama")
12
- from colorama import Fore, Style, init
13
- init(autoreset=True)
14
- print("[+] 'colorama' installed successfully!\n")
15
- except Exception as e:
16
- print(f"[-] Failed to install the library: {e}. Proceeding without colors.")
17
-
18
- class Fore: GREEN = ''; RED = ''; RESET = ''
19
- class Style: BRIGHT = ''
8
+ os.system(f"{sys.executable} -m pip install colorama")
9
+ from colorama import Fore, Style, init
20
10
 
21
11
  import socket
22
12
  from datetime import datetime
23
13
 
24
14
  def scan(ip):
25
- """
26
- Scans a target IP address for open TCP ports.
27
- """
15
+
28
16
  print("-" * 50)
29
17
  print(f"{Fore.GREEN}Starting scan on target: {ip}")
30
18
  print(f"Time started: {str(datetime.now())}")
@@ -39,6 +39,5 @@ from .mail import send_msj
39
39
  from .captcha import generate_captcha
40
40
 
41
41
  from .qrcode import generate_qrcode
42
- from .qrcode import scan_qrcode
43
42
 
44
43
  from .search import search_by_username
@@ -82,7 +82,7 @@ def owner():
82
82
  print("Github : https://github.com/erec2smith")
83
83
 
84
84
  def vr():
85
- print("0.1")
85
+ print("0.2")
86
86
 
87
87
  def team():
88
88
  print("Adem")
@@ -90,17 +90,5 @@ def team():
90
90
  print("Berlin")
91
91
 
92
92
  def hp():
93
- print("""
94
- 1. At the beginning, you should call core like this: from ShadowB import core \n
95
- 2. After that, it calls the main function core , like that : core.owner() \n
96
- 3. Call any function you want, like (owner to get info about the library owner, or team to get \n info about the Shadow Boys team) example: core.owner() \n
97
- 4. All the functions currently available:\n
98
- owner() : To find out information about making the library \n
99
- team() : To find out information about the wamithe team \n
100
- start() : To start generating random words or organizing files \n
101
- hp() : To find out information about the library \n
102
- Example : from ShadowB import core \n
103
- core.start() \n
104
- 2026/06/17 python https://github.com/erec2smith
105
- """)
93
+ print("https://github.com/erec2smith/ShadowB")
106
94
 
@@ -1,14 +1,25 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ShadowB
3
- Version: 0.1
3
+ Version: 0.3
4
4
  Summary: ShadowB is an all-in-one Python toolkit that bundles a wide range of everyday utilities — system info, image steganography, temporary email, QR codes, CAPTCHA generation, password tools, file safety checks, and more — into a single, easy-to-import package.
5
5
  Author-email: Adem mzoughi <ademzoughi1312@gmail.com>
6
6
  Requires-Python: >=3.8
7
7
  Description-Content-Type: text/markdown
8
8
  License-File: LICENSE
9
+ Requires-Dist: requests
10
+ Requires-Dist: colorama
11
+ Requires-Dist: better_profanity
12
+ Requires-Dist: pillow
13
+ Requires-Dist: pypdf
14
+ Requires-Dist: qrcode
15
+ Requires-Dist: stepic
16
+ Requires-Dist: browser-cookie3
9
17
 
10
18
  # ShadowB
11
19
 
20
+ ![ShadowB Logo](https://raw.githubusercontent.com/erec2smith/ShadowB/main/shadowb.jpg)
21
+
22
+
12
23
  **ShadowB** is an all-in-one Python toolkit that bundles a wide range of everyday utilities — system info, image steganography, temporary email, QR codes, CAPTCHA generation, password tools, file safety checks, and more — into a single, easy-to-import package.
13
24
 
14
25
  Instead of installing and learning a dozen different libraries for a dozen small tasks, `ShadowB` collects the most commonly needed helper functions in one place.
@@ -48,7 +59,7 @@ Basic package metadata and bootstrapping.
48
59
  ```python
49
60
  from ShadowB import core
50
61
 
51
- core.start() # run core app fro : create passwords or usernames / organize the working files
62
+ core.start() # run core app for : create passwords or usernames / organize the working files
52
63
  core.owner() # -> "Adem mzoughi"
53
64
  core.team() # -> "Adem mzoughi, Berlin, Shadow"
54
65
  core.hp() # print help / usage info
@@ -109,7 +120,7 @@ Generate and read QR codes.
109
120
  from ShadowB import qrcode
110
121
 
111
122
  qrcode.generate_qrcode(text, "qr") # create a QR code image
112
- qrcode.scan_qrcode("qr.png") # -> decoded text (str)
123
+
113
124
  ```
114
125
 
115
126
  ---
@@ -14,6 +14,7 @@ ShadowB/search.py
14
14
  ShadowB.egg-info/PKG-INFO
15
15
  ShadowB.egg-info/SOURCES.txt
16
16
  ShadowB.egg-info/dependency_links.txt
17
+ ShadowB.egg-info/requires.txt
17
18
  ShadowB.egg-info/top_level.txt
18
19
  ShadowB/Core/fileorg.py
19
20
  ShadowB/Core/randwords.py
@@ -31,10 +32,4 @@ ShadowB/Image/remove_metadata.py
31
32
  ShadowB/Mail/make_mail.py
32
33
  ShadowB/Mail/res_msj.py
33
34
  ShadowB/Mail/send_msj.py
34
- ShadowB/Qrcode/generate.py
35
- ShadowB/Qrcode/scan.py
36
- ShadowB/Safe/clean.py
37
- ShadowB/Safe/cleanText.py
38
- ShadowB/Safe/ext.py
39
- ShadowB/Safe/filename.py
40
- ShadowB/Safe/safeFile.py
35
+ ShadowB/Qrcode/generate.py
@@ -0,0 +1,8 @@
1
+ requests
2
+ colorama
3
+ better_profanity
4
+ pillow
5
+ pypdf
6
+ qrcode
7
+ stepic
8
+ browser-cookie3
@@ -4,10 +4,22 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ShadowB"
7
- version = "0.1"
7
+ version = "0.3"
8
8
  authors = [
9
9
  {name = "Adem mzoughi", email = "ademzoughi1312@gmail.com"},
10
10
  ]
11
+
12
+ dependencies = [
13
+ "requests",
14
+ "colorama",
15
+ "better_profanity",
16
+ "pillow",
17
+ "pypdf",
18
+ "qrcode",
19
+ "stepic",
20
+ "browser-cookie3"
21
+ ]
22
+
11
23
  description = "ShadowB is an all-in-one Python toolkit that bundles a wide range of everyday utilities — system info, image steganography, temporary email, QR codes, CAPTCHA generation, password tools, file safety checks, and more — into a single, easy-to-import package."
12
24
  readme = "README.md"
13
25
  requires-python = ">=3.8"
@@ -1,26 +0,0 @@
1
- import sys
2
- import os
3
-
4
- try:
5
- import cv2
6
- except ImportError:
7
- os.system(f"{sys.executable} -m pip install opencv-python")
8
- import cv2
9
-
10
-
11
- def scan(qrcode_path):
12
- if not os.path.exists(qrcode_path):
13
- return None
14
-
15
- try:
16
- img = cv2.imread(qrcode_path)
17
- detector = cv2.QRCodeDetector()
18
- data, bbox, _ = detector.detectAndDecode(img)
19
-
20
- if bbox is not None and data:
21
- return data
22
- else:
23
- return None
24
-
25
- except Exception:
26
- return None
@@ -1,127 +0,0 @@
1
- import os
2
- import re
3
-
4
- try:
5
- from pypdf import PdfReader
6
- except:
7
- import os
8
- os.system("pip install pypdf")
9
- from pypdf import PdfReader
10
-
11
- try:
12
- from better_profanity import profanity
13
- except ImportError:
14
- import os
15
- os.system("pip install better_profanity")
16
- from better_profanity import profanity
17
-
18
- custom_bad_words = ["irheb","de3ch","israil","اسرائيل","trump","ارهاب","إرهاب","zab", "zebi", "asba","3asba","nyk","nayek","nik","nik omk","3asba lik","mnayek","fuck","shit","fuck you","fuck u","nik omo","t7chi fih","yatek asba","yatek 3asba","ya3tek 3asba","zok","omk","kiss","زبي","عصب","نيك","امك","برا نيك","يعطك عصبة","عصبة"]
19
-
20
- def normalize(text):
21
- text = text.lower()
22
- text = re.sub(r'[^a-zA-Z0-9\u0600-\u06FF]', '', text)
23
- return text
24
-
25
-
26
-
27
-
28
-
29
- def pdf_to_txt(file):
30
- try:
31
- if not file.lower().endswith(".pdf"):
32
- raise ValueError("Currently, the accepted files are .pdf and .txt")
33
-
34
- reader = PdfReader(file)
35
- text = ""
36
- for page in reader.pages:
37
- text += page.extract_text() or ""
38
-
39
- return text
40
-
41
- except Exception as e:
42
- print(e)
43
- return "error"
44
-
45
-
46
-
47
- def txt_to_text(file):
48
- try:
49
- if not file.lower().endswith(".txt"):
50
- raise ValueError("Currently, the accepted files are .pdf and .txt")
51
-
52
- with open(file, "r", encoding="utf-8") as f:
53
- text = f.read()
54
-
55
- return text
56
-
57
- except Exception as e:
58
- print(e)
59
- return "error"
60
-
61
-
62
-
63
- def is_clean(text,check_list=None):
64
- if not text:
65
- print("Maybe there's a mistake, no text was received!")
66
- return False
67
-
68
- normalized_text = normalize(text)
69
-
70
-
71
- for word in custom_bad_words:
72
- if word in normalized_text:
73
- return False
74
-
75
- if check_list:
76
- for w in check_list:
77
- if w in normalized_text:
78
- return False
79
-
80
-
81
- if profanity.contains_profanity(text):
82
- return False
83
-
84
- return True
85
-
86
-
87
-
88
- def cleann(file,check_list=None):
89
- if not file:
90
- print("Maybe there's a mistake, no file was received!")
91
- return False
92
-
93
-
94
-
95
- if file.lower().endswith(".pdf"):
96
- text = pdf_to_txt(file)
97
-
98
- elif file.lower().endswith(".txt"):
99
- text = txt_to_text(file)
100
-
101
- else:
102
- print("Currently, the accepted files are .pdf and .txt")
103
- return "Currently, the accepted files are .pdf and .txt"
104
-
105
- if text == "error":
106
- print("An error occurred: Please try again, making sure the file is in PDF format and that it is a text document, not a scanned copy or image!")
107
- return False
108
-
109
- normalized_text = normalize(text)
110
-
111
-
112
- for word in custom_bad_words:
113
- if word in normalized_text:
114
- return False
115
-
116
- if check_list:
117
- for w in check_list:
118
- if w in normalized_text:
119
- return False
120
-
121
-
122
- if profanity.contains_profanity(text):
123
- return False
124
-
125
- return True
126
-
127
-
@@ -1,37 +0,0 @@
1
- import os
2
- import re
3
- try:
4
- from better_profanity import profanity
5
- except ImportError:
6
- import os
7
- os.system("pip install better_profanity")
8
- from better_profanity import profanity
9
-
10
- custom_bad_words = ["irheb","ass","dick","cock","asshole","de3ch","israil","اسرائيل","trump","ارهاب","إرهاب","zab", "zebi", "asba","3asba","nyk","nayek","nik","nik omk","3asba lik","mnayek","fuck","shit","fuck you","fuck u","nik omo","t7chi fih","yatek asba","yatek 3asba","ya3tek 3asba","zok","omk","kiss","زبي","عصب","نيك","امك","برا نيك","يعطك عصبة","عصبة"]
11
-
12
- def normalize(text):
13
- text = text.lower()
14
- text = re.sub(r'[^a-zA-Z0-9\u0600-\u06FF]', '', text)
15
- return text
16
-
17
- def is_clean(text,check_list=None):
18
- if not text:
19
- return True
20
-
21
- normalized_text = normalize(text)
22
-
23
-
24
- for word in custom_bad_words:
25
- if word in normalized_text:
26
- return False
27
-
28
- if check_list:
29
- for w in check_list:
30
- if w in normalized_text:
31
- return False
32
-
33
-
34
- if profanity.contains_profanity(text):
35
- return False
36
-
37
- return True
@@ -1,5 +0,0 @@
1
- import os
2
-
3
- def real_ext(file):
4
- ext = os.path.splitext(file)[1].lower()
5
- return ext
@@ -1,6 +0,0 @@
1
- import os
2
-
3
- def real_filename(file):
4
- name = ext = os.path.splitext(os.path.basename(file))[0]
5
- return name
6
-
@@ -1,171 +0,0 @@
1
- import os
2
- import subprocess
3
- import sys
4
- import zipfile
5
-
6
-
7
- def _ensure_package(import_name, pip_name=None):
8
-
9
- pip_name = pip_name or import_name
10
- try:
11
- return __import__(import_name)
12
- except ImportError:
13
- try:
14
- subprocess.check_call(
15
- [sys.executable, "-m", "pip", "install",
16
- "--break-system-packages", pip_name],
17
- stdout=subprocess.DEVNULL,
18
- stderr=subprocess.DEVNULL,
19
- )
20
- except Exception:
21
- return None
22
- try:
23
- return __import__(import_name)
24
- except ImportError:
25
- return None
26
-
27
-
28
-
29
- magic = _ensure_package("magic", "python-magic")
30
-
31
-
32
- pyclamd = _ensure_package("pyclamd", "pyclamd")
33
-
34
-
35
- BLOCKED_EXTENSIONS = {
36
- "exe", "bat", "cmd", "apk", "cpp", "py", "js", "html",
37
- "css", "c", "java", "msi", "vbs", "ps1", "dll", "scr",
38
- "sh", "rb", "php", "pl", "go", "rs", "ts", "jar", "com",
39
- "pif", "reg", "hta", "wsf", "lnk"
40
- }
41
-
42
-
43
- EXECUTABLE_SIGNATURES = {
44
- b"MZ": "Windows PE/EXE",
45
- b"\x7fELF": "Linux ELF executable",
46
- b"\xfe\xed\xfa\xce": "Mach-O 32-bit executable",
47
- b"\xfe\xed\xfa\xcf": "Mach-O 64-bit executable",
48
- b"\xca\xfe\xba\xbe": "Mach-O fat binary / Java class",
49
- }
50
-
51
-
52
- EXECUTABLE_LIKE_EXTENSIONS = {"exe", "dll", "com", "scr", "msi"}
53
-
54
- MAX_ZIP_DEPTH = 1
55
- MAX_UNCOMPRESSED_SIZE = 200 * 1024 * 1024
56
- MAX_COMPRESSION_RATIO = 100
57
-
58
- ZIP_BASED_EXTENSIONS = {"zip", "jar", "apk", "docx", "xlsx", "pptx"}
59
-
60
-
61
- def _get_extension(file_path):
62
- return os.path.splitext(file_path)[1].lower().lstrip(".")
63
-
64
-
65
- def _read_header(file_path, n=8):
66
- try:
67
- with open(file_path, "rb") as f:
68
- return f.read(n)
69
- except OSError:
70
- return b""
71
-
72
-
73
- def _is_disguised_executable(file_path):
74
-
75
- header = _read_header(file_path, 8)
76
- ext = _get_extension(file_path)
77
-
78
- if ext in EXECUTABLE_LIKE_EXTENSIONS:
79
- return False
80
-
81
- for sig in EXECUTABLE_SIGNATURES:
82
- if header.startswith(sig):
83
- return True
84
- return False
85
-
86
-
87
- def _check_zip_bomb(file_path, depth=0):
88
-
89
- if depth > MAX_ZIP_DEPTH:
90
- return False
91
-
92
- try:
93
- with zipfile.ZipFile(file_path) as zf:
94
- total_uncompressed = 0
95
- for info in zf.infolist():
96
- total_uncompressed += info.file_size
97
- if total_uncompressed > MAX_UNCOMPRESSED_SIZE:
98
- return False
99
-
100
- if info.compress_size > 0:
101
- ratio = info.file_size / max(info.compress_size, 1)
102
- if ratio > MAX_COMPRESSION_RATIO:
103
- return False
104
-
105
- if info.filename.lower().endswith(".zip"):
106
- if depth + 1 > MAX_ZIP_DEPTH:
107
- return False
108
- tmp_path = f"{file_path}.__nested_{depth}.tmp"
109
- try:
110
- with zf.open(info) as nested_file:
111
- with open(tmp_path, "wb") as tmp:
112
- tmp.write(nested_file.read())
113
- nested_ok = _check_zip_bomb(tmp_path, depth + 1)
114
- if not nested_ok:
115
- return False
116
- except (zipfile.BadZipFile, OSError):
117
- return False
118
- finally:
119
- if os.path.exists(tmp_path):
120
- os.remove(tmp_path)
121
- except zipfile.BadZipFile:
122
- return False
123
- except OSError:
124
- return False
125
-
126
- return True
127
-
128
-
129
- def _clamav_scan(file_path):
130
-
131
- if pyclamd is None:
132
- return None
133
- try:
134
- cd = pyclamd.ClamdUnixSocket()
135
- if not cd.ping():
136
- cd = pyclamd.ClamdNetworkSocket()
137
- cd.ping()
138
- result = cd.scan_file(file_path)
139
- return result is None
140
- except Exception:
141
- return None
142
-
143
-
144
- def is_safe(file):
145
-
146
- if not file or not os.path.isfile(file):
147
- return False
148
-
149
- ext = _get_extension(file)
150
-
151
-
152
- if ext in BLOCKED_EXTENSIONS:
153
- return False
154
-
155
-
156
- if _is_disguised_executable(file):
157
- return False
158
-
159
-
160
- header = _read_header(file, 4)
161
- looks_like_zip = header.startswith(b"PK\x03\x04") or ext in ZIP_BASED_EXTENSIONS
162
- if looks_like_zip:
163
- if not _check_zip_bomb(file):
164
- return False
165
-
166
-
167
- av_result = _clamav_scan(file)
168
- if av_result is False:
169
- return False
170
-
171
- return True
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes