Skip to content

Commit 8eeab63

Browse files
committed
feat(docs): enhance security in command execution and improve error handling in scripts
1 parent a0f8b37 commit 8eeab63

File tree

3 files changed

+108
-11
lines changed

3 files changed

+108
-11
lines changed

.github/scripts/docs_build_examples.py

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,25 @@
7272

7373
def run_cmd(cmd, check=True, capture_output=False, text=True):
7474
"""Execute a shell command with error handling."""
75+
# Security: Ensure cmd is always a list to prevent command injection
76+
if isinstance(cmd, str):
77+
raise ValueError("cmd must be a list, not a string, to prevent command injection")
78+
if not isinstance(cmd, list) or not cmd:
79+
raise ValueError("cmd must be a non-empty list")
80+
# Validate all elements are strings
81+
if not all(isinstance(arg, str) for arg in cmd):
82+
raise ValueError("All cmd arguments must be strings")
83+
# Reject control characters that could alter argv parsing at the OS level
84+
for arg in cmd:
85+
if any(ch in arg for ch in ("\n", "\r", "\0")):
86+
raise ValueError("Command arguments must not contain control characters")
7587
try:
7688
return subprocess.run(
77-
cmd, check=check, capture_output=capture_output, text=text
89+
cmd,
90+
check=check,
91+
capture_output=capture_output,
92+
text=text,
93+
shell=False,
7894
)
7995
except subprocess.CalledProcessError as e:
8096
# CalledProcessError is raised only when check=True and the command exits non-zero
@@ -260,8 +276,8 @@ def cleanup_binaries():
260276
if not os.listdir(root):
261277
try:
262278
os.rmdir(root)
263-
except Exception:
264-
pass
279+
except Exception as e:
280+
print(f"WARNING: Failed to remove empty directory {root}: {e}")
265281
print("Cleanup completed")
266282

267283

@@ -284,7 +300,8 @@ def find_examples_with_upload_binary():
284300
data = yaml.safe_load(ci_yml.read_text())
285301
if "upload-binary" in data and data["upload-binary"]:
286302
res.append(str(ino))
287-
except Exception:
303+
except Exception as e:
304+
print(f"WARNING: Failed to parse ci.yml for {ci_yml}: {e}")
288305
continue
289306
return res
290307

docs/en/conf.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,3 @@
3131

3232
# Tracking ID for Google Analytics
3333
google_analytics_id = "G-F58JM78930"
34-
35-
# Documentation embedding settings
36-
# docs_embed_public_root = "https://docs.espressif.com/projects/arduino-esp32-wokwi-test"
37-
# docs_embed_esp32_relative_root = "../.."
38-
# docs_embed_launchpad_url = "https://espressif.github.io/esp-launchpad/"
39-
# docs_embed_github_base_url = "https://github.com/JakubAndrysek/arduino-esp32"
40-
# docs_embed_github_branch = "docs-embed"

docs/en/contributing.rst

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,93 @@ Also:
109109
const char * WIFI_FTM_SSID = "WiFi_FTM_Responder"; // SSID of AP that has FTM Enabled
110110
const char * WIFI_FTM_PASS = "ftm_responder"; // STA Password
111111
112+
113+
Examples
114+
********
115+
116+
All libraries in the Arduino ESP32 core has its own examples. You can found them in the ``libraries/<library_name>/examples/`` folder.
117+
118+
The purpose of these examples is to demonstrate how to use the library features and provide a starting point for users.
119+
120+
If you want to show the example in the documentation, you have two options:
121+
1. link just the source code file in the documentation using the ``literalinclude`` directive:
122+
123+
.. code-block:: rst
124+
125+
.. literalinclude:: ../../../libraries/<library_name>/examples/<example_name>/<example_name>.ino
126+
:language: arduino
127+
128+
2. Source code with Wokwi simulation embedded in the documentation using the ``wokwi-example`` directive:
129+
130+
.. code-block:: rst
131+
132+
.. wokwi-example:: libraries/<library_name>/examples/<example_name>/<example_name>.ino
133+
134+
To enable compiling the example in the CI system, you need to add a ``ci.yml`` file in the same folder as the sketch.
135+
The ``ci.yml`` file is used to specify some configurations for the CI system, like required configurations, supported targets, and more.
136+
You can enable compilation of the example by adding targets under the ``upload-binary`` directive in the ``ci.yml`` file.
137+
138+
Here is an example of a ``ci.yml`` file that enables compilation for ESP32 and ESP32-S3 targets.
139+
This configuration adds default diagrams for Wokwi simulations with just dev boards.
140+
141+
.. code-block:: yaml
142+
143+
upload-binary:
144+
targets:
145+
- esp32
146+
- esp32s3
147+
148+
If you want to add custom diagrams for Wokwi simulations, you can add the ``diagram.<target>.json`` file in the same folder as the sketch.
149+
The ``<target>`` is the target name (e.g., ``esp32``, ``esp32s3``, etc.). You can create the diagram using ``docs-embed`` tool installed together with documentation building tools.
150+
151+
To create the diagram, run the ``docs-embed init-diagram --platforms esp32`` command in the sketch folder.
152+
You can edit them and before you run the documentation build command, you have to convert the diagram config to the ``ci.yml`` file format by running:
153+
154+
.. code-block:: bash
155+
156+
docs-embed ci-from-diagram
157+
# OR
158+
docs-embed ci-from-diagram --override
159+
160+
There is also opposite command to generate diagram from ``ci.yml`` file:
161+
162+
.. code-block:: bash
163+
164+
docs-embed diagram-from-ci
165+
166+
167+
The documentation building tools is working only with `ci.yml` files, so `diagram.<target>.json` files are just for configuration using GUI tool.
168+
169+
Please keep in mind that the ``ci.yml`` does not store the chip and its position on the diagram, just the components and their connections (to save space).
170+
The chip is added automatically and positioned vertically in the center of the diagram (same as the default behavior of the `docs-embed init-diagram` command).
171+
172+
To run the documentation build command locally and in the CI system, you need to add those environment variables:
173+
174+
* ``DOCS_EMBED_ABOUT_WOKWI_URL``: URL to the info about Wokwi (default: ``https://docs.espressif.com/projects/arduino-esp32/en/latest/third_party/wokwi.html``)
175+
* ``DOCS_EMBED_BINARIES_DIR``: Path to the folder where the pre-compiled binaries are stored (default: ``_static/binaries``)
176+
* ``DOCS_EMBED_LAUNCHPAD_URL``: URL to the launchpad page (default: ``https://espressif.github.io/esp-launchpad/``)
177+
* ``DOCS_EMBED_WOKWI_VIEWER_URL``: URL to the Wokwi iframe viewer (default: ``https://wokwi.com/experimental/viewer``)
178+
179+
180+
CI/CD
181+
*****
182+
183+
This repository uses GitHub Actions for Continuous Integration and Continuous Deployment (CI/CD).
184+
If you forked the repository, you can enable them under the `Actions` tab in your forked repository.
185+
186+
To enable building the documentation, you need to set up additional secrets and environment variables in your forked repository.
187+
188+
Secrets
189+
^^^^^^^^^^^^
190+
* ``DOCS_SERVER``: The server where the documentation will be deployed
191+
* ``DOCS_PATH``: The path where the documentation will be deployed on the server
192+
193+
194+
Variables
195+
^^^^^^^^^
196+
197+
They are described above in the `Examples` section.
198+
112199
Testing
113200
*******
114201

0 commit comments

Comments
 (0)