James P. Carson

26 papers A* 2A 1B 1Journal 11Unranked 11
YearRankTypeTitle / Venue / Authors
2026 J jnl
J. Open Source Softw.
James A. Labyer, Erik S. Ferlanti, Martha Campbell-Thompson, Clayton E. Mathews, Wei-Jun Qian, James P. Carson
2025 conf
SC Workshops
William J. Allen, Kelsey M. Beavers, Erik S. Ferlanti, Lorenzo Concia, Joshua Urrutia, Ernesto A. B. F. Lima, John M. Fonner, Felix Zuo, H. E. Duplechin Seymour, Ari B. Kahn, Joe Stubbs, Anagha Jamthe, Stephanie N. Baker, Tabish Khan, James P. Carson
2023 J jnl
CoRR
Soichi Hayashi, Bradley Caron, Anibal Sólon Heinsfeld, Sophia Vinci-Booher, Brent C. McPherson, Daniel N. Bullock, Giulia Berto, J. Guiomar Niso, Sandra Hanekamp, Daniel Levitas, Lindsey Kitchell, Josiah Leong, Filipi N. Silva, Serge Koudoro, Hanna Willis, Jasleen Jolly, Derek Pisner, Taylor Zuidema, Jan Kurzwaski, Koulla Mikellidou, Aurore Bussalb, Christopher Rorden, Conner Victory, Dheeraj Bhatia, Dogu Baran Aydogan, Frank C. Yeh, Franco Delogu, Javier Guaje, Jelle Veraart, Jeremy Fischer, Joshua Faskowitz, Maximilien Chaumon, Ricardo Fabrega, David Hunt, Shawn McKee, Shaw T. Brown, Stephanie Heyman, Vittorio Iacovella, Amanda Mejia, Daniele Marinazzo, R. Cameron Craddock, Emanuele Olivetti, Jamie Hanson, Paolo Avesani, Eleftherios Garyfallidis, Daniel Stanzione, James P. Carson, Robert Henschel, David Y. Hancock, Craig A. Stewart, David M. Schnyer, Damian Eke, Russell A. Poldrack, Nathalie George, Holly Bridge, Ilaria Sani, Winrich Freiwald, Aina Puce, Nicholas Port, Franco Pestilli
2016 conf
EMBC
James P. Carson, Monique Y. Rennie, Michael Danilchik, Kent L. Thornburg, Sandra Rugonyi
2015 J jnl
Neuroinformatics
Volodymyr Shcherbatyy, James P. Carson, Murat Yaylaoglu, Katharina Jäckle, Frauke Grabbe, Maren Brockmeyer, Halenur Yavuz, Gregor Eichele
2014 conf
EMBC
Mathew Thomas, Matthew J. Marshall, Erin A. Miller, Andrew P. Kuprat, Kerstin Kleese van Dam, James P. Carson
2014 J jnl
BMC Medical Imaging
Richard E. Jacob, James P. Carson
2013 J jnl
J. Comput. Phys.
Andrew P. Kuprat, Senthil Kabilan, James P. Carson, Richard A. Corley, Daniel R. Einstein
2013 J jnl
J. Digit. Imaging
Lu Liu, Paul K. Commean, Charles Hildebolt, David R. Sinacore, Fred W. Prior, James P. Carson, Ioannis A. Kakadiaris, Tao Ju
2012 conf
EMBC
James P. Carson, Andrew P. Kuprat, Sean M. Colby, Cassi A. Davis, Christopher A. Basciano, Kevin Greene, John Feo, Andrew Kennedy
2012 conf
MICCAI (1)
Yen H. Le, Uday Kurkure, Nikos Paragios, Tao Ju, James P. Carson, Ioannis A. Kakadiaris
2012 conf
eScience
Kerstin Kleese van Dam, James P. Carson, Abigail L. Corrigan, Daniel R. Einstein, Zoe Guillen, Brandi Heath, Andrew P. Kuprat, Ingela Lanekoff, Carina Lansing, Julia Laskin, Dongsheng Li, Yan Liu, Matthew J. Marshall, Erin A. Miller, Galya Orr, Paulo Pinheiro da Silva, Seun Ryu, Craig Szymanski, Mathew Thomas
2012 conf
EMBC
Mathew Thomas, Brandi S. Heath, Julia Laskin, Dongsheng Li, Ellen Liu, Katrina Hui, Andrew P. Kuprat, Kerstin Kleese van Dam, James P. Carson
2011 A* conf
CVPR
Uday Kurkure, Yen H. Le, Nikos Paragios, James P. Carson, Tao Ju, Ioannis A. Kakadiaris
2011 conf
EMBC
Matthew A. Enlow, Tao Ju, Ioannis A. Kakadiaris, James P. Carson
2011 A* conf
ICCV
Uday Kurkure, Yen H. Le, Nikos Paragios, Tao Ju, James P. Carson, Ioannis A. Kakadiaris
2010 J jnl
Comput. Medical Imaging Graph.
James P. Carson, Daniel R. Einstein, Kevin R. Minard, Michelle V. Fanucchi, Christopher D. Wallis, Richard A. Corley
2009 J jnl
Medical Biol. Eng. Comput.
Xiangmin Jiao, Daniel R. Einstein, Vladimir Dyedov, James P. Carson
2007 J jnl
IEEE Trans. Medical Imaging
Musodiq Bello, Tao Ju, James P. Carson, Joe D. Warren, Wah Chiu, Ioannis A. Kakadiaris
2005 J jnl
PLoS Comput. Biol.
James P. Carson, Tao Ju, Hui-Chen Lu, Christina Thaller, Mei Xu, Sarah L. Pallas, Michael C. Crair, Joe D. Warren, Wah Chiu, Gregor Eichele
2005 J jnl
Vis. Comput.
Tao Ju, Joe D. Warren, James P. Carson, Gregor Eichele, Christina Thaller, Wah Chiu, Musodiq Bello, Ioannis A. Kakadiaris
2005 conf
CSB Workshops
James P. Carson, Tao Ju, Christina Thaller, Musodiq Bello, Joe D. Warren, Gregor Eichele, Wah Chiu
2005 conf
CSB Workshops
James P. Carson, Christina Thaller, Musodiq Bello, Wah Chiu, Tao Ju, Joe D. Warren, Ioannis A. Kakadiaris, Gregor Eichele
2005 A conf
MICCAI
Musodiq Bello, Tao Ju, Joe D. Warren, James P. Carson, Wah Chiu, Christina Thaller, Gregor Eichele, Ioannis A. Kakadiaris
2004 conf
MICCAI (1)
Ioannis A. Kakadiaris, Musodiq Bello, Shiva Arunachalam, Wei Kang, Tao Ju, Joe D. Warren, James P. Carson, Wah Chiu, Christina Thaller, Gregor Eichele
2003 B conf
Symposium on Geometry Processing
Joe D. Warren, Tao Ju, Gregor Eichele, Christina Thaller, Wah Chiu, James P. Carson
redb/extractors/js_extractors/js_patterns.py
← Index redb/extractors/js_extractors/js_patterns.py python
"""Canonical, compiled JavaScript regex patterns shared across JS extractors.

All suspicious-API patterns and the few feature-only patterns live here so each
expression is compiled exactly once per Python process and so any pattern that
was previously duplicated across `js_features.py` and `js_suspicious_apis.py`
now resolves to a single shared compiled object.

JavaScript is case-sensitive at runtime, but every suspicious-API pattern matches
either a literal-case identifier (`\\beval\\s*\\(`, `String\\.fromCharCode`, etc.)
or a string-quoted token (`"powershell"`). Compiling them with `re.IGNORECASE`
matches the historical behaviour of `JSSuspiciousAPIsExtractor` and is safe for
the patterns that historically came from `JSFeaturesExtractor` — those literals
are spelled in real-world JS exactly as written.

`scan_source()` is the entry point used by extractors: it walks the source once
per pattern using the pre-compiled regexes and returns a flat
`{name: {"count": N, "lines": [unique_line_numbers_sorted]}}` dict. Both
`JSFeaturesExtractor` and `JSSuspiciousAPIsExtractor` consume the same dict so
the per-pattern × per-line loops they used to run independently collapse to a
single shared scan.
"""

import bisect
import re
from typing import Dict, Iterable, List, Mapping

_FLAGS = re.IGNORECASE

# Canonical compiled patterns, keyed by their human-readable name. The name is
# also the value emitted into `redb_js_suspicious_apis.api_name`.
PATTERNS = {
    # ---- code execution ----
    "eval": re.compile(r"\beval\s*\(", _FLAGS),
    "Function constructor": re.compile(r"\bnew\s+Function\s*\(", _FLAGS),
    "execScript": re.compile(r"\bexecScript\s*\(", _FLAGS),
    "document.write": re.compile(r"\bdocument\.write(?:ln)?\s*\(", _FLAGS),
    "innerHTML assignment": re.compile(r"\.innerHTML\s*=", _FLAGS),
    "outerHTML assignment": re.compile(r"\.outerHTML\s*=", _FLAGS),
    "insertAdjacentHTML": re.compile(r"\.insertAdjacentHTML\s*\(", _FLAGS),
    # ---- network ----
    "XMLHttpRequest": re.compile(r"\bnew\s+XMLHttpRequest\b", _FLAGS),
    "fetch": re.compile(r"\bfetch\s*\(", _FLAGS),
    "WebSocket": re.compile(r"\bnew\s+WebSocket\s*\(", _FLAGS),
    "navigator.sendBeacon": re.compile(r"\bnavigator\.sendBeacon\s*\(", _FLAGS),
    "ActiveXObject XMLHTTP": re.compile(
        r"ActiveXObject\s*\(\s*[\"\'](?:MSXML2\.XMLHTTP|Microsoft\.XMLHTTP)", _FLAGS
    ),
    "require network module": re.compile(
        r"require\s*\(\s*[\"\'](?:http|https|net|dgram)[\"\']", _FLAGS
    ),
    "axios": re.compile(r"\baxios\b", _FLAGS),
    # ---- filesystem ----
    "require fs": re.compile(r"require\s*\(\s*[\"\']fs[\"\']", _FLAGS),
    "require path": re.compile(r"require\s*\(\s*[\"\']path[\"\']", _FLAGS),
    "FileSystemObject": re.compile(r"Scripting\.FileSystemObject", _FLAGS),
    "ADODB.Stream": re.compile(r"ADODB\.Stream", _FLAGS),
    "Shell.Application": re.compile(r"Shell\.Application", _FLAGS),
    "WScript.CreateObject": re.compile(r"WScript\.CreateObject", _FLAGS),
    # ---- process ----
    "require child_process": re.compile(r"require\s*\(\s*[\"\']child_process[\"\']", _FLAGS),
    "child_process exec": re.compile(r"child_process\.(?:exec|spawn|execFile|fork)\s*\(", _FLAGS),
    "WScript.Shell": re.compile(r"WScript\.Shell", _FLAGS),
    "WScript.Shell.Run": re.compile(r"\.Run\s*\(", _FLAGS),
    "WScript.Shell.Exec": re.compile(r"\.Exec\s*\(", _FLAGS),
    "ShellExecute": re.compile(r"\bShellExecute\b", _FLAGS),
    "PowerShell reference": re.compile(r"[\"\']powershell[\"\']", _FLAGS),
    "cmd.exe reference": re.compile(r"[\"\']cmd\.exe[\"\']", _FLAGS),
    "require os": re.compile(r"require\s*\(\s*[\"\']os[\"\']", _FLAGS),
    # ---- registry ----
    "RegRead": re.compile(r"\.RegRead\s*\(", _FLAGS),
    "RegWrite": re.compile(r"\.RegWrite\s*\(", _FLAGS),
    "RegDelete": re.compile(r"\.RegDelete\s*\(", _FLAGS),
    "StdRegProv": re.compile(r"StdRegProv", _FLAGS),
    # ---- crypto / encoding ----
    "atob": re.compile(r"\batob\s*\(", _FLAGS),
    "btoa": re.compile(r"\bbtoa\s*\(", _FLAGS),
    "String.fromCharCode": re.compile(r"String\.fromCharCode\s*\(", _FLAGS),
    "unescape": re.compile(r"\bunescape\s*\(", _FLAGS),
    "decodeURIComponent": re.compile(r"\bdecodeURIComponent\s*\(", _FLAGS),
    "Buffer.from": re.compile(r"Buffer\.from\s*\(", _FLAGS),
    "crypto module": re.compile(r"crypto\.create(?:Cipher|Decipher|Hash|Hmac)", _FLAGS),
    # ---- DOM manipulation ----
    "document.forms": re.compile(r"document\.forms", _FLAGS),
    "document.cookie": re.compile(r"document\.cookie", _FLAGS),
    "querySelector sensitive input": re.compile(
        r"document\.querySelector\s*\([^)]*(?:password|credit|card|cvv|ssn)", _FLAGS
    ),
    "submit event listener": re.compile(r"addEventListener\s*\(\s*[\"\']submit", _FLAGS),
    "createElement script/iframe": re.compile(
        r"\.createElement\s*\(\s*[\"\'](?:script|iframe)", _FLAGS
    ),
    "dynamic script src": re.compile(r"\.src\s*=\s*[\"\'](?:https?://|//)", _FLAGS),
}

# Pattern name -> category (one of code_execution / network / filesystem /
# process / registry / crypto_encoding / dom_manipulation).
CATEGORIES = {
    "eval": "code_execution",
    "Function constructor": "code_execution",
    "execScript": "code_execution",
    "document.write": "code_execution",
    "innerHTML assignment": "code_execution",
    "outerHTML assignment": "code_execution",
    "insertAdjacentHTML": "code_execution",
    "XMLHttpRequest": "network",
    "fetch": "network",
    "WebSocket": "network",
    "navigator.sendBeacon": "network",
    "ActiveXObject XMLHTTP": "network",
    "require network module": "network",
    "axios": "network",
    "require fs": "filesystem",
    "require path": "filesystem",
    "FileSystemObject": "filesystem",
    "ADODB.Stream": "filesystem",
    "Shell.Application": "filesystem",
    "WScript.CreateObject": "filesystem",
    "require child_process": "process",
    "child_process exec": "process",
    "WScript.Shell": "process",
    "WScript.Shell.Run": "process",
    "WScript.Shell.Exec": "process",
    "ShellExecute": "process",
    "PowerShell reference": "process",
    "cmd.exe reference": "process",
    "require os": "process",
    "RegRead": "registry",
    "RegWrite": "registry",
    "RegDelete": "registry",
    "StdRegProv": "registry",
    "atob": "crypto_encoding",
    "btoa": "crypto_encoding",
    "String.fromCharCode": "crypto_encoding",
    "unescape": "crypto_encoding",
    "decodeURIComponent": "crypto_encoding",
    "Buffer.from": "crypto_encoding",
    "crypto module": "crypto_encoding",
    "document.forms": "dom_manipulation",
    "document.cookie": "dom_manipulation",
    "querySelector sensitive input": "dom_manipulation",
    "submit event listener": "dom_manipulation",
    "createElement script/iframe": "dom_manipulation",
    "dynamic script src": "dom_manipulation",
}

# Patterns consumed only by JSFeaturesExtractor (no category, never surfaced as
# a suspicious-API row). Kept here so every JS regex is compiled in one place.
FEATURE_PATTERNS = {
    "hex_escape": re.compile(r"\\x[0-9a-fA-F]{2}"),
    "unicode_escape": re.compile(r"\\u[0-9a-fA-F]{4}"),
    "base64_string": re.compile(r"[A-Za-z0-9+/]{40,}={0,2}"),
    # decodeURI matches BOTH decodeURI and decodeURIComponent. The latter is also
    # a suspicious-API pattern in PATTERNS; this broader form is what the
    # `decodeuri_count` feature column has historically counted.
    "decodeURI": re.compile(r"\b(?:decodeURI|decodeURIComponent)\s*\(", _FLAGS),
    "settimeout_setinterval": re.compile(r"\b(?:setTimeout|setInterval)\s*\(", _FLAGS),
    "function_decl": re.compile(r"\bfunction\s+\w+\s*\(|\bfunction\s*\("),
    "var_decl": re.compile(r"\b(?:var|let|const)\s+"),
    "string_concat": re.compile(r"[\"\'][\s]*\+[\s]*[\"\']"),
    "comment": re.compile(r"//.*?$|/\*[\s\S]*?\*/", re.MULTILINE),
    "long_string": re.compile(r"[\"\']([^\"\']{256,})[\"\']"),
    "array_function_call": re.compile(r"\[(?:0x[0-9a-f]+|[\d]+)\]\s*\(", _FLAGS),
}

# Patterns consumed only by JSStringsExtractor for encoded-string discovery.
# Scoped to *hidden* strings only — patterns whose decoded form is not visible
# to a substring search over the raw text. Plain long literals are not
# extracted here because they're already preserved in code_text_content and
# scraped by the IOC pipeline over text_raw / text_normalized.
#
# Distinct from FEATURE_PATTERNS even where the names rhyme:
#   FEATURE_PATTERNS["hex_escape"] / ["unicode_escape"]   -> single escape
#   STRING_PATTERNS["hex_escape_seq"] / ["unicode_escape_seq"] -> 4+ / 3+ in a row
#   FEATURE_PATTERNS["base64_string"]                     -> bare base64 token
#   STRING_PATTERNS["base64_quoted"]                      -> base64 inside JS quotes
# These do not share match objects with the suspicious-API or feature scans, so
# they are not folded into JSContext.scan; the strings extractor walks them
# itself (one finditer per pattern, with shared line-offset bisect in #4b).
STRING_PATTERNS = {
    "hex_escape_seq": re.compile(r"(?:\\x[0-9a-fA-F]{2}){4,}"),
    "unicode_escape_seq": re.compile(r"(?:\\u[0-9a-fA-F]{4}){3,}"),
    "charcode_call": re.compile(r"String\.fromCharCode\s*\(\s*([\d,\s]+)\s*\)"),
    "base64_quoted": re.compile(r"[\"\']([A-Za-z0-9+/]{40,}={0,2})[\"\']"),
    "concat_chain": re.compile(r"(?:[\"\'][^\"\']+[\"\']\s*\+\s*){3,}[\"\'][^\"\']+[\"\']"),
}


def line_offsets(source: str) -> List[int]:
    """Sorted list of byte offsets for every newline in `source`, plus a final
    sentinel of len(source). Used to translate match offsets into 1-indexed
    line numbers via bisect.
    """
    offsets = [-1]  # so that bisect_right of offset 0 returns line 1
    push = offsets.append
    idx = source.find("\n")
    while idx != -1:
        push(idx)
        idx = source.find("\n", idx + 1)
    return offsets


def _scan_one(
    pattern: "re.Pattern[str]", source: str, offsets: List[int]
) -> Dict[str, object]:
    """Run a single compiled pattern over `source` and return count + unique lines."""
    count = 0
    seen_lines: "set[int]" = set()
    for m in pattern.finditer(source):
        count += 1
        seen_lines.add(bisect.bisect_right(offsets, m.start()))
    if not count:
        return None  # type: ignore[return-value]
    return {"count": count, "lines": sorted(seen_lines)}


def scan_source(
    source: str,
    patterns: Iterable[Mapping[str, "re.Pattern[str]"]] = (PATTERNS, FEATURE_PATTERNS),
) -> Dict[str, Dict[str, object]]:
    """Scan `source` against every compiled pattern in `patterns`.

    Returns a dict keyed by pattern name. Each entry has:
        "count": total number of matches in the source
        "lines": sorted list of unique 1-indexed line numbers where the pattern
                 matched (deduplicated — multiple matches on the same line
                 collapse to one entry, preserving the historical
                 line-set semantics of JSSuspiciousAPIsExtractor)
    Patterns with zero matches are absent from the dict; callers should default
    to {"count": 0, "lines": []}.
    """
    if not source:
        return {}
    offsets = line_offsets(source)
    results: Dict[str, Dict[str, object]] = {}
    for table in patterns:
        for name, pat in table.items():
            entry = _scan_one(pat, source, offsets)
            if entry is not None:
                results[name] = entry
    return results