codebread 1.0.1__py3-none-any.whl → 1.0.2__py3-none-any.whl

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.
codebread/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """CodeBread — slice open a codebase and see its internal structure."""
2
2
 
3
- __version__ = "1.0.1"
3
+ __version__ = "1.0.2"
codebread/analyzer.py CHANGED
@@ -34,8 +34,12 @@ def analyze(root: str,
34
34
  info.warnings.append(err)
35
35
  info.layer = classify(info, text)
36
36
  if info.parsed or info.language in ("html", "css"):
37
- info.source = text if len(text) <= 300_000 else \
37
+ src = text if len(text) <= 300_000 else \
38
38
  text[:300_000] + "\n… (truncated)"
39
+ if info.language == "config":
40
+ from .parsers.generic_parser import redact_secrets
41
+ src = redact_secrets(src)
42
+ info.source = src
39
43
  parsed.append(info)
40
44
  for w in info.warnings:
41
45
  if w.startswith("Unsupported:"):
@@ -286,3 +286,17 @@ def parse_config(info: FileInfo, text: str) -> None:
286
286
  value = value[:57] + "..."
287
287
  info.db_config.append(f"{key} = {value}")
288
288
  info.db_config = info.db_config[:20]
289
+
290
+
291
+ def redact_secrets(text: str) -> str:
292
+ """Mask secret-looking values line by line. Used on config-file source
293
+ before it's stored/exported, so the raw "IDE view" / JSON export can't
294
+ leak what the DB-config summary already redacts."""
295
+ out = []
296
+ for line in text.splitlines():
297
+ m = re.match(r"^(\s*[\"']?[\w.\-]+[\"']?\s*[:=]\s*)(.+)$", line)
298
+ if m and SECRET_KEY_RE.search(m.group(1)):
299
+ out.append(m.group(1) + "•••masked•••")
300
+ else:
301
+ out.append(URL_CREDS_RE.sub("://***:***@", line))
302
+ return "\n".join(out)
codebread/server.py CHANGED
@@ -10,6 +10,7 @@ from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
10
10
  from typing import Dict
11
11
 
12
12
  WEB_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "web")
13
+ WEB_ROOT = os.path.realpath(WEB_DIR)
13
14
 
14
15
  MIME = {".html": "text/html; charset=utf-8",
15
16
  ".js": "application/javascript; charset=utf-8",
@@ -45,11 +46,19 @@ def serve(graph: Dict, port: int = 8137, open_browser: bool = True) -> None:
45
46
  self._file(path.lstrip("/"))
46
47
 
47
48
  def _file(self, rel: str):
48
- rel = os.path.normpath(rel).replace("\\", "/")
49
- if rel.startswith("..") or rel.startswith("/"):
49
+ # Resolve against WEB_DIR and verify the *result* is still inside
50
+ # it. String-prefix checks on `rel` alone aren't enough: on
51
+ # Windows, os.path.join(WEB_DIR, "C:/some/file") silently
52
+ # discards WEB_DIR because the second argument is drive-absolute,
53
+ # which would otherwise let a request read any file on disk.
54
+ full = os.path.realpath(os.path.join(WEB_DIR, rel))
55
+ try:
56
+ inside = os.path.commonpath([full, WEB_ROOT]) == WEB_ROOT
57
+ except ValueError:
58
+ inside = False # e.g. different drives on Windows
59
+ if not inside:
50
60
  self.send_error(403)
51
61
  return
52
- full = os.path.join(WEB_DIR, rel)
53
62
  if not os.path.isfile(full):
54
63
  self.send_error(404)
55
64
  return
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codebread
3
- Version: 1.0.1
3
+ Version: 1.0.2
4
4
  Summary: Interactive codebase analyzer & visualizer — slice open a project and see how it's wired together.
5
5
  Author: Danial Irsyad
6
6
  License: MIT
@@ -22,7 +22,7 @@ Dynamic: license-file
22
22
  </p>
23
23
 
24
24
  <p align="center">
25
- <img alt="version" src="https://img.shields.io/badge/version-1.0.1-2dd4bf">
25
+ <img alt="version" src="https://img.shields.io/badge/version-1.0.2-2dd4bf">
26
26
  <img alt="python" src="https://img.shields.io/badge/python-3.9%2B-0284c7">
27
27
  <img alt="deps" src="https://img.shields.io/badge/required%20dependencies-none-2dd4bf">
28
28
  <img alt="license" src="https://img.shields.io/badge/license-MIT-8b5cf6">
@@ -1,5 +1,5 @@
1
- codebread/__init__.py,sha256=zaQz04FV7Jd-aoPIR3qYYkZq1BbI0XO3OWKdY1hjya0,97
2
- codebread/analyzer.py,sha256=7uf00Lw5jjtsA4-fb8x2bUsoZybyPNeVQsXSBx1bPhY,3061
1
+ codebread/__init__.py,sha256=InwUkpEmPv-mS3-33Vu1RXBTw1Zm4tYbe9RB4DAsW5s,97
2
+ codebread/analyzer.py,sha256=tCsV0Cwi1l-If5zbNLbMtsuKW3o-rl8mekNG-B7MXpY,3234
3
3
  codebread/classifier.py,sha256=jehD-XQ80CP_O4x9YRi4JQqzd4AaHxKpzI83wLG1yvM,4067
4
4
  codebread/cli.py,sha256=AMvwk29cOJDjsI-I07pCGbqogdtq1Y6HWnT52FHYyLs,4072
5
5
  codebread/connections.py,sha256=FN0c-W9_tnQUVetnF0eVyC6lllyBOyZ3512sXShpy7Q,16609
@@ -8,17 +8,17 @@ codebread/export.py,sha256=rKYmzuSEXYDrgcItnhdyXI_lo0LN2PSoMe0hYElzU88,1512
8
8
  codebread/languages.py,sha256=SKHy9v7QPreWZG6FbuX3B0-kq1jqVn-rmwNqJ9ESFqo,4494
9
9
  codebread/models.py,sha256=Sw2PJW63dKyl5RpWwfY2ZvCJLYttmjoQg4O5H5DtLgM,4214
10
10
  codebread/scanner.py,sha256=bEXSaoENmJ-C_oabj2IF1aWs9-LaIqMc80xXQvo7-eg,8020
11
- codebread/server.py,sha256=9MPHNx3b_KQV4YA4XGeW9vhfkiq4jz-j5f6M9RDyhSc,3020
11
+ codebread/server.py,sha256=H3kUXJaH8FkExNUwdwSD2HxBMceC_24o6pVSjJjFh8g,3543
12
12
  codebread/parsers/__init__.py,sha256=ovsvmXGClshiUlDdx6mkBmRu8__OZIqYos6-1eLb9eM,2285
13
- codebread/parsers/generic_parser.py,sha256=5XveP1AkCpIni9faEU9MRc93ZGHek7_R_TkQSZEOxts,11382
13
+ codebread/parsers/generic_parser.py,sha256=lz-wLsmQYERoDRM27lhEP3cvNYbomHfA--VI_3LmJ5E,11966
14
14
  codebread/parsers/javascript_parser.py,sha256=lVIlydQ3--Owd78816XIM77NntfQ97DeLzYvPrjd5GE,15916
15
15
  codebread/parsers/python_parser.py,sha256=QnhCLx01bKYLYqav33cI27qbEQNPUiXnS5uN7cb8poQ,11671
16
16
  codebread/web/app.js,sha256=P1zpCHNMyczAuLWL9zM5htl9E3wG3jJdpZ6orLhixTM,65672
17
17
  codebread/web/index.html,sha256=6YqjC_wO3pfqyG_11uIhvRM16Wagu2l8eSOs1FNc-UY,8693
18
18
  codebread/web/style.css,sha256=fiq1bC-I1bC6-6MxRn0blQwGOjO_fdClPrhf5W7zqPw,23729
19
- codebread-1.0.1.dist-info/licenses/LICENSE,sha256=okINupIvMgiuOlvMVpsM9DT5jb6QQmKBd--yfZq4bjc,1070
20
- codebread-1.0.1.dist-info/METADATA,sha256=jsimg1QlF58mJVpAOs4L2Oh12i7R_kE0GSDGgBhHCHM,11367
21
- codebread-1.0.1.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
22
- codebread-1.0.1.dist-info/entry_points.txt,sha256=ItG61aUP1YTvA_zA-jlUshBc5BPpJDpCyVnsyaxNXKA,49
23
- codebread-1.0.1.dist-info/top_level.txt,sha256=KctFB7UQb4tN9YotaJD95GuHWIQuoO5VqyLdo_gEswQ,10
24
- codebread-1.0.1.dist-info/RECORD,,
19
+ codebread-1.0.2.dist-info/licenses/LICENSE,sha256=okINupIvMgiuOlvMVpsM9DT5jb6QQmKBd--yfZq4bjc,1070
20
+ codebread-1.0.2.dist-info/METADATA,sha256=zWaglNGGhQUvXpPnyXwNdS_a6Og2jdIFhWImFNlGvAY,11367
21
+ codebread-1.0.2.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
22
+ codebread-1.0.2.dist-info/entry_points.txt,sha256=ItG61aUP1YTvA_zA-jlUshBc5BPpJDpCyVnsyaxNXKA,49
23
+ codebread-1.0.2.dist-info/top_level.txt,sha256=KctFB7UQb4tN9YotaJD95GuHWIQuoO5VqyLdo_gEswQ,10
24
+ codebread-1.0.2.dist-info/RECORD,,