Readable source
#!/usr/bin/env python3
"""Report SVG dimensions and active/external content. Does not sanitise or modify SVGs."""
import argparse,json,xml.etree.ElementTree as ET
from pathlib import Path
def audit(path):
result={'file':str(path),'issues':[]}
try:
if path.stat().st_size>5*1024*1024:raise ValueError('File exceeds 5 MB audit limit.')
raw=path.read_text(encoding='utf-8')
if '<!doctype' in raw.lower() or '<!entity' in raw.lower():raise ValueError('DOCTYPE / ENTITY declarations are not accepted.')
root=ET.fromstring(raw)
if root.tag.split('}')[-1]!='svg':raise ValueError('Root element is not SVG.')
result.update(width=root.get('width'),height=root.get('height'),viewBox=root.get('viewBox'),elements=sum(1 for _ in root.iter()))
if not root.get('viewBox'):result['issues'].append('Missing viewBox.')
for el in root.iter():
name=el.tag.split('}')[-1]
if name in ('script','foreignObject'):result['issues'].append('Active content: '+name)
for k,v in el.attrib.items():
attr=k.split('}')[-1].lower()
if attr.startswith('on'):result['issues'].append('Event attribute: '+attr)
if attr=='href' and not v.startswith('#'):result['issues'].append('Non-local reference: '+v[:100])
if any(s in v.lower() for s in ('javascript:','url(http','url(//','@import')):result['issues'].append('Active or external attribute content.')
if name=='style' and el.text and any(s in el.text.lower() for s in ('@import','http:','https:','javascript:')):result['issues'].append('External / active style content.')
except (ValueError,OSError,UnicodeError,ET.ParseError) as e:result['issues'].append(str(e))
return result
def main():
p=argparse.ArgumentParser(description=__doc__);p.add_argument('path',type=Path);a=p.parse_args();files=sorted(a.path.rglob('*.svg')) if a.path.is_dir() else [a.path]
results=[audit(f) for f in files];print(json.dumps(results,indent=2));return 1 if any(r['issues'] for r in results) else 0
if __name__=='__main__':raise SystemExit(main())