Vijay P. Singh

56 papers Journal 51Unranked 4
YearRankTypeTitle / Venue / Authors
2025 J jnl
Environ. Model. Softw.
Zengchao Hao, Xuan Zhang, Yuting Pang, Boying Lv, Vijay P. Singh
2025 J jnl
Mach. Learn. Sci. Technol.
Taesam Lee, Yejin Kong, Vijay P. Singh
2024 J jnl
Remote. Sens.
Wenhui Chen, Rui Yao, Peng Sun, Qiang Zhang, Vijay P. Singh, Shao Sun, Amir Aghakouchak, Chenhao Ge, Huilin Yang
2024 J jnl
Remote. Sens.
Anlan Feng, Zhenya Zhu, Xiudi Zhu, Qiang Zhang, Fengling Yan, Zhijun Li, Yiwei Guo, Vijay P. Singh, Kaiwen Zhang, Gang Wang
2024 J jnl
Remote. Sens.
Taesam Lee, Seonghyeon Hwang, Vijay P. Singh
2024 J jnl
Mach. Learn. Sci. Technol.
Taesam Lee, Chang-Hee Won, Vijay P. Singh
2024 J jnl
Remote. Sens.
Kaiwen Zhang, Qiang Zhang, Vijay P. Singh
2023 J jnl
J. Intell. Fuzzy Syst.
Shilpi Yadav, Raj K. Patel, Vijay P. Singh
2023 J jnl
Comput. Electron. Agric.
Xin Zhao, Lei Zhang, Ge Zhu, Chenguang Cheng, Jun He, Seydou Traore, Vijay P. Singh
2023 J jnl
CoRR
Manotosh Kumbhakar, Vijay P. Singh
2023 J jnl
Eng. Appl. Artif. Intell.
Meysam Alizamir, Jalal Shiri, Ahmad Fakheri Fard, Sungwon Kim, Alireza Docheshmeh Gorgij, Salim Heddam, Vijay P. Singh
2023 J jnl
Remote. Sens.
Yiran Zhang, Xin Tong, Tingxi Liu, Limin Duan, Lina Hao, Vijay P. Singh, Tianyu Jia, Shuo Lun
2022 J jnl
Remote. Sens.
Wenhuan Wu, Qiang Zhang, Vijay P. Singh, Gang Wang, Jiaqi Zhao, Zexi Shen, Shuai Sun
2022 J jnl
Remote. Sens.
Yuliang Zhang, Zhiyong Wu, Vijay P. Singh, Juliang Jin, Yuliang Zhou, Shiqin Xu, Lei Li
2022 J jnl
Remote. Sens.
Irfan Ullah, Xieyao Ma, Guoyu Ren, Jun Yin, Vedaste Iyakaremye, Sidra Syed, Kaidong Lu, Yun Xing, Vijay P. Singh
2021 J jnl
Remote. Sens.
Qiang Zhang, Zixuan Wu, Vijay P. Singh, Chunling Liu
2021 J jnl
Commun. Nonlinear Sci. Numer. Simul.
Manotosh Kumbhakar, Rajendra K. Ray, Suvra Kanti Chakraborty, Koeli Ghoshal, Vijay P. Singh
2021 J jnl
Earth Sci. Informatics
Maliheh Abbaszadeh, Mohammad Ehteram, Ali Najah Ahmed, Vijay P. Singh, Ahmed El-Shafie
2020 J jnl
IEEE Access
Liu Penghui, Ahmed A. Ewees, Beste Hamiye Beyaztas, Chongchong Qi, Sinan Q. Salih, Nadhir Al-Ansari, Suraj Kumar Bhagat, Zaher Mundher Yaseen, Vijay P. Singh
2020 J jnl
CoRR
Akram Seifi, Mohammad Ehteram, Vijay P. Singh, Amir Mosavi
2019 J jnl
Entropy
Mo Li, Hao Sun, Vijay P. Singh, Yan Zhou, Mingwei Ma
2019 J jnl
Soft Comput.
Sarita Gajbhiye Meshram, Ehsan Alvandi, Vijay P. Singh, Chandrashekhar Meshram
2019 J jnl
Entropy
Hadi Jahanshahi, Maryam Shahriari-Kahkeshi, Raúl Alcaraz, Xiong Wang, Vijay P. Singh, Viet-Thanh Pham
2019 J jnl
Entropy
Dragutin T. Mihailovic, Emilija Nikolic-Doric, Slavica Malinovic-Milicevic, Vijay P. Singh, Anja Mihailovic, Tatijana Stosic, Borko D. Stosic, Nusret Dreskovic
2018 J jnl
Environ. Model. Softw.
Rene A. Camacho, James L. Martin, Tim Wool, Vijay P. Singh
2018 J jnl
Entropy
Lu Chen, Vijay P. Singh, Kangdi Huang
2018 J jnl
Remote. Sens.
Yanling Hao, Tingwei Cui, Vijay P. Singh, Jie Zhang, Ruihong Yu, Wenjing Zhao
2018 J jnl
Entropy
Huijuan Cui, Bellie Sivakumar, Vijay P. Singh
2017 J jnl
IEEE Access
Lawrence E. Holloway, Zhihua Qu, Margaret J. Mohr-Schroeder, Juan Carlos Balda, Andrea Benigni, Donald G. Colliver, Paul A. Dolloff, Roger A. Dougal, M. Omar Faruque, Zongming Fei, Yuan Liao, Roy A. McCann, R. Mark Nelms, Vijay P. Singh, Azadeh Vosoughi, Qun Zhou
2017 J jnl
Environ. Model. Softw.
Kamran Chapi, Vijay P. Singh, Ataollah Shirzadi, Himan Shahabi, Dieu Tien Bui, Binh Thai Pham, Khabat Khosravi
2017 J jnl
Entropy
Lu Chen, Vijay P. Singh, Feng Xiong
2017 J jnl
Environ. Model. Softw.
Zengchao Hao, Fanghua Hao, Vijay P. Singh, Wei Ouyang, Hongguang Cheng
2017 J jnl
Entropy
Zhenghong Zhou, Juanli Ju, Xiaoling Su, Vijay P. Singh, Gengxi Zhang
2017 J jnl
Entropy
Yu Zhang, Vijay P. Singh, Aaron R. Byrd
2017 J jnl
Entropy
Lu Chen, Vijay P. Singh
2017 J jnl
Entropy
Gengxi Zhang, Xiaoling Su, Vijay P. Singh, Olusola O. Ayantobo
2017 J jnl
Entropy
Lina Hao, Xiaoling Su, Vijay P. Singh, Olusola O. Ayantobo
2017 J jnl
Entropy
Sufen Wang, Vijay P. Singh
2017 J jnl
Entropy
Vijay P. Singh, Bellie Sivakumar, Huijuan Cui
2017 J jnl
IEEE J. Sel. Top. Appl. Earth Obs. Remote. Sens.
Yanling Hao, Tingwei Cui, Vijay P. Singh, Jie Zhang, Ruihong Yu, Zhilei Zhang
2016 J jnl
IEEE Geosci. Remote. Sens. Lett.
Xin Tong, Tingxi Liu, Vijay P. Singh, Limin Duan, Di Long
2016 J jnl
Entropy
Manotosh Kumbhakar, Snehasis Kundu, Koeli Ghoshal, Vijay P. Singh
2015 J jnl
J. Comput. Civ. Eng.
Sungwon Kim, Youngmin Seo, Vijay P. Singh
2015 conf
ICHSA
Sungwon Kim, Youngmin Seo, Vijay P. Singh
2015 J jnl
Entropy
Zengchao Hao, Vijay P. Singh
2015 conf
ICHSA
Youngmin Seo, Sungwon Kim, Vijay P. Singh
2015 J jnl
Entropy
Emöke Imre, László Nagy, Jànos Lörincz, Negar Rahemi, Tom Schanz, Vijay P. Singh, Stephen Fityus
2015 J jnl
Entropy
Jànos Lörincz, Emöke Imre, Stephen Fityus, Phong Q. Trang, Tibor Tarnai, István Talata, Vijay P. Singh
2013 J jnl
IEEE Trans. Geosci. Remote. Sens.
Di Long, Vijay P. Singh
2013 J jnl
Entropy
Vijay P. Singh, Gustavo Marini, Nicola Fontana
2012 J jnl
Entropy
Lan Zhang, Vijay P. Singh
2012 J jnl
Entropy
Emöke Imre, Jànos Lörincz, Janos Szendefy, Phong Q. Trang, László Nagy, Vijay P. Singh, Stephen Fityus
2011 ch.
Modeling Risk Management for Resources and Environment in China
Jiguo Zhang, Huimin Wang, Vijay P. Singh
2010 J jnl
Adv. Eng. Softw.
Gürol Yildirim, Vijay P. Singh
2007 conf
PRIS
Ganesh R. Naik, Dinesh Kant Kumar, Hans Weghorn, Vijay P. Singh, Marimuthu Palaniswami
2006 conf
EMBC
Vijay P. Singh, Dinesh K. Kumar, Barbara Polus, Sonia Lo Guidice, Steve Fraser
redb/extractors/js_extractors/js_context.py
← Index redb/extractors/js_extractors/js_context.py python
"""Per-sample shared state for the JavaScript extractor pipeline.

A `JSContext` is built exactly once per JS sample (in `workers.py`) and threaded
into every extractor that runs against that sample. It owns the disk read, the
decoded source text, the line-split cache, the Shannon text-entropy figure, the
shared `scan_source()` results, and the pyjsparser AST. Each of those is
computed lazily through `cached_property` so an extractor that doesn't need a
particular artefact does not pay for it.

Without this object, every JS extractor instance redoes the same disk read,
decode, scan, and (for any consumer) AST parse. With it, every extractor
shares one set of results.

`JSExtractor.__init__` accepts the context via a `context=` kwarg; if absent
(e.g. unit tests instantiating an extractor directly with `source=...`) it
builds a fresh context from the constructor arguments. Either path produces a
fully-populated context, so extractor code can always rely on
`self._context.scan` / `self._context.ast` / etc.
"""

from __future__ import annotations

import math
from collections import Counter
from dataclasses import dataclass
from functools import cached_property
from typing import Any, Dict, List, Optional

import chardet

from redb.extractors.js_extractors.js_patterns import scan_source


def decode_source(raw_bytes: bytes) -> str:
    """Decode raw JS bytes to text, honouring BOMs and falling back to chardet.

    Mirrors the historical `JSExtractor._decode_source` logic so existing tests
    continue to round-trip identically.
    """
    if not raw_bytes:
        return ""

    if raw_bytes[:3] == b"\xef\xbb\xbf":
        return raw_bytes[3:].decode("utf-8", errors="replace")
    if raw_bytes[:2] in (b"\xff\xfe", b"\xfe\xff"):
        return raw_bytes.decode("utf-16", errors="replace")

    try:
        return raw_bytes.decode("utf-8")
    except UnicodeDecodeError:
        pass

    try:
        detected = chardet.detect(raw_bytes)
        if detected and detected.get("encoding"):
            return raw_bytes.decode(detected["encoding"], errors="replace")
    except Exception:
        pass

    return raw_bytes.decode("latin-1", errors="replace")


def _text_entropy(text: str) -> float:
    """Shannon entropy of the character distribution of `text`, rounded to 4dp."""
    if not text:
        return 0.0
    counter = Counter(text)
    length = len(text)
    entropy = 0.0
    for count in counter.values():
        p = count / length
        if p > 0:
            entropy -= p * math.log2(p)
    return round(entropy, 4)


@dataclass
class JSContext:
    """Shared raw materials for one JS sample, consumed by every JS extractor.

    Cheap attributes (raw_bytes, source) are populated eagerly by the factory.
    Expensive ones (scan, ast) are cached_property — computed on first access
    and reused across every extractor that holds the same context.

    `content_type` is the magika label (e.g. `"javascript"`) carried alongside
    the source so the new code_text_content writer (and any future generic
    text-content writer) can record it without re-running magika. Defaults to
    `"javascript"` because by construction this context type is JS-specific;
    workers.py supplies the actual magika value when it builds the context.
    """

    filepath: str
    raw_bytes: bytes
    source: str
    log: Any = None
    content_type: str = "javascript"
    # Populated by JSStringsExtractor.extract() (the decoded/reconstructed
    # strings — hex/unicode/charcode/base64/concat unpacked into plaintext).
    # Read post-loop by the IOC plumbing in workers.py so any IOCs hidden
    # behind those encodings get scraped from the decoded form. Stays None
    # if JSStringsExtractor didn't run for this sample.
    decoded_strings: Optional[list] = None

    @cached_property
    def lines(self) -> List[str]:
        return self.source.splitlines() if self.source else []

    @cached_property
    def text_entropy(self) -> float:
        return _text_entropy(self.source)

    @cached_property
    def scan(self) -> Dict[str, Dict[str, object]]:
        """Result of running scan_source() exactly once over self.source."""
        return scan_source(self.source) if self.source else {}

    @cached_property
    def ast(self) -> Optional[Any]:
        """Lazy pyjsparser AST. Returns None if the parser is missing or fails.

        Extractors should treat None AST as "fall back to regex" — every
        AST-consuming extractor already handles that path.
        """
        if not self.source:
            return None
        try:
            import pyjsparser
            return pyjsparser.parse(self.source)
        except ImportError:
            if self.log is not None:
                self.log.debug("pyjsparser not installed, AST analysis skipped")
        except Exception as e:
            if self.log is not None:
                self.log.warning(f"AST parsing failed for {self.filepath}: {e}")
        return None

    @cached_property
    def deobfuscated(self) -> "tuple[Optional[str], Optional[str]]":
        """Run the configured JS deobfuscator (with jsbeautifier fallback) once
        per sample and cache the result. Returns `(text, normalizer_used)` or
        `(None, None)` if neither path produced output.

        Computed lazily on first access — samples whose pipeline never reads
        this don't pay the subprocess cost.
        """
        from redb.extractors.js_extractors.js_deobfuscator import deobfuscate
        return deobfuscate(self.source, self.log)

    @cached_property
    def scan_deobfuscated(self) -> Dict[str, Dict[str, object]]:
        """Result of running scan_source() exactly once over the deobfuscated
        text, keyed by PATTERNS only (FEATURE_PATTERNS are not consulted by
        the dual-pass consumers). Empty dict when there is no deobfuscated
        text or it equals the raw source.

        Two extractors consume the post-deobf API surface:
        `JSSuspiciousAPIsExtractor` (for revealed_by_deobf rows) and
        `JSDeobfuscationExtractor` (for the new_apis_found diff). Caching here
        means we scan the deobfuscated text once instead of twice per sample.
        """
        from redb.extractors.js_extractors.js_patterns import PATTERNS
        deobf_text, _ = self.deobfuscated
        if not deobf_text or deobf_text == self.source:
            return {}
        return scan_source(deobf_text, patterns=(PATTERNS,))

    @cached_property
    def xray(self):
        """Run @nodesecure/js-x-ray once per sample and cache the result.

        Returns an `XRayResult` (always — the function collapses every failure
        path to an empty result so callers don't have to special-case missing
        Node, missing package, timeouts, or parse errors). The
        `JSFeaturesExtractor` reads it for the obfuscator family name and for
        corroborating warning kinds; the heuristic falls back cleanly when
        `xray.obfuscator is None`.
        """
        from redb.extractors.js_extractors.js_xray import run
        return run(self.source, self.log)

    @classmethod
    def from_path(
        cls,
        filepath: str,
        log: Any = None,
        source: Optional[str] = None,
        raw_bytes: Optional[bytes] = None,
        content_type: str = "javascript",
    ) -> "JSContext":
        """Build a context from disk. `raw_bytes` and `source` are optional
        overrides — useful when the caller has already read or decoded the file.
        `content_type` is the magika label workers.py dispatched on; it lands
        on the context for the code_text_content writer to record.
        """
        if raw_bytes is None:
            with open(filepath, "rb") as f:
                raw_bytes = f.read()
        if source is None:
            source = decode_source(raw_bytes)
        return cls(
            filepath=filepath,
            raw_bytes=raw_bytes,
            source=source,
            log=log,
            content_type=content_type,
        )