Add robust CSS injection and size limit validation

- Ensure CSS is injected correctly even if <head> is missing
- Escape special characters in CSS to prevent sed errors
- Validate --size argument is an integer
- Support both .md and .markdown extensions for Markdown conversion
- Improve temporary file handling
This commit is contained in:
cedric 2026-01-05 09:17:10 +00:00
parent 79cb9e3c31
commit e66a39d24b

View file

@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
# Usage: ./md2data_safe.sh FILE [--css CSS_FILE] [--size LIMIT] # Usage: ./md2data_safe.sh FILE [--css CSS_FILE] [--size LIMIT]
# Converts HTML or Markdown to Base64 Data URL # Converts HTML or Markdown to Base64 Data URL safely
# Default size limit is 30000 characters # Default size limit is 30000 characters
# ----------------- Functions ----------------- # ----------------- Functions -----------------
@ -24,6 +24,14 @@ check_file_exists() {
fi fi
} }
validate_limit() {
local limit="$1"
if ! [[ "$limit" =~ ^[0-9]+$ ]]; then
echo "Error: size limit must be an integer." >&2
exit 1
fi
}
convert_md_to_html() { convert_md_to_html() {
local file="$1" local file="$1"
if ! command -v pandoc >/dev/null 2>&1; then if ! command -v pandoc >/dev/null 2>&1; then
@ -41,8 +49,8 @@ minify_css() {
escape_css_for_sed() { escape_css_for_sed() {
local css="$1" local css="$1"
css=${css//\\/\\\\} # Escape backslash css=${css//\\/\\\\} # Escape backslash
css=${css//\//\\/} # Escape slashes
css=${css//&/\\&} # Escape & css=${css//&/\\&} # Escape &
css=${css//\"/\\\"} # Escape double quotes
echo "$css" echo "$css"
} }
@ -52,11 +60,12 @@ inject_css() {
local escaped_css local escaped_css
escaped_css=$(escape_css_for_sed "$css") escaped_css=$(escape_css_for_sed "$css")
if grep -q "</head>" "$html_file"; then if grep -qi "</head>" "$html_file"; then
sed "/<\/head>/i <style>$escaped_css</style>" "$html_file" sed "/<\/head>/i <style>$escaped_css</style>" "$html_file"
else else
echo "<style>$escaped_css</style>" echo "<html><head><style>$escaped_css</style></head><body>"
cat "$html_file" cat "$html_file"
echo "</body></html>"
fi fi
} }
@ -96,6 +105,7 @@ while [[ $# -gt 0 ]]; do
;; ;;
--size) --size)
LIMIT="$2" LIMIT="$2"
validate_limit "$LIMIT"
shift 2 shift 2
;; ;;
-*) -*)
@ -118,12 +128,11 @@ EXT="${FILE##*.}"
# ----------------- Main Processing ----------------- # ----------------- Main Processing -----------------
# Temporary HTML file for streaming
TMP_HTML=$(mktemp) TMP_HTML=$(mktemp)
trap 'rm -f "$TMP_HTML"' EXIT trap 'rm -f "$TMP_HTML"' EXIT
# Convert Markdown or copy HTML # Convert Markdown or copy HTML
if [[ "$EXT" == "md" ]]; then if [[ "$EXT" =~ ^(md|markdown)$ ]]; then
convert_md_to_html "$FILE" > "$TMP_HTML" convert_md_to_html "$FILE" > "$TMP_HTML"
else else
cp "$FILE" "$TMP_HTML" cp "$FILE" "$TMP_HTML"
@ -134,6 +143,7 @@ if [[ -n "$CSS_FILE" ]]; then
check_file_exists "$CSS_FILE" check_file_exists "$CSS_FILE"
MIN_CSS=$(minify_css "$CSS_FILE") MIN_CSS=$(minify_css "$CSS_FILE")
TMP_HTML_INJECTED=$(mktemp) TMP_HTML_INJECTED=$(mktemp)
trap 'rm -f "$TMP_HTML" "$TMP_HTML_INJECTED"' EXIT
inject_css "$TMP_HTML" "$MIN_CSS" > "$TMP_HTML_INJECTED" inject_css "$TMP_HTML" "$MIN_CSS" > "$TMP_HTML_INJECTED"
mv "$TMP_HTML_INJECTED" "$TMP_HTML" mv "$TMP_HTML_INJECTED" "$TMP_HTML"
echo "Injected CSS size: ${#MIN_CSS} characters" echo "Injected CSS size: ${#MIN_CSS} characters"