Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions application/single_app/admin_settings_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -2557,10 +2557,10 @@
{
"key": "enable_office_embedded_image_analysis",
"type": "switch",
"label": "Analyze images embedded in DOCX and PPTX files",
"label": "Analyze images embedded in DOCX, PPTX, and Excel files",
"help": (
"Neither extraction engine describes figures inside Word and PowerPoint "
"files. With this on, embedded images are pulled out, analysed with "
"Native extraction does not describe image pixels inside Word, PowerPoint, "
"or Excel files. With this on, embedded images are pulled out, analysed with "
"whichever engine backs the selected extraction mode, and indexed as "
"their own citable chunks. Works with Standard extraction too."
),
Expand Down
2 changes: 1 addition & 1 deletion application/single_app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@
EXECUTOR_MAX_WORKERS = 30
CHAT_STREAM_EXECUTOR_MAX_WORKERS = max(8, int(os.getenv('SIMPLECHAT_CHAT_STREAM_WORKERS', '32') or '32'))
SESSION_TYPE = 'filesystem'
VERSION = "0.261.407"
VERSION = "0.261.409"
IS_DEVELOPMENT = is_development_env_enabled()

# Opt-out for deployments where App Service Easy Auth is active but the platform
Expand Down
22 changes: 20 additions & 2 deletions application/single_app/content_screening/access.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
"group_document_collaboration_operation", "document_share_details",
"public_document_projection_writer",
"public_document_collaboration_operation",
"excel_native_inventory",
# Recomputed per request from current authorization, so a stored copy is
# always stale. The group projection re-adds them after serialization.
"document_actions", "document_collaboration_actions",
Expand Down Expand Up @@ -1068,6 +1069,23 @@
return payload


def _with_current_excel_metadata(payload, document):
metadata = payload.get("accessibility_metadata")
marker = document.get(SCREENING_FIELD)
if (
not isinstance(metadata, Mapping) or metadata.get("format") not in {"xlsx", "xlsm", "xls"}
or not isinstance(marker, Mapping)
):
return payload
active = marker.get("active_blob")

Check warning on line 1080 in application/single_app/content_screening/access.py

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains secret or sensitive data source marker. Recommendation%3A Pair this source with any nearby network, logging, serialization, or process execution sink before approving.
inventory = metadata.get("inventory_storage")

Check warning on line 1081 in application/single_app/content_screening/access.py

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains secret or sensitive data source marker. Recommendation%3A Pair this source with any nearby network, logging, serialization, or process execution sink before approving.
digest = inventory.get("source_sha256") if isinstance(inventory, Mapping) else None
if not isinstance(active, Mapping) or not digest or active.get("content_hash") != digest:
payload.pop("accessibility_metadata", None)
payload["native_inspection_status"] = "requires_active_source_inspection"
return payload


def public_document_payload(document):
if not isinstance(document, Mapping):
return {}
Expand All @@ -1080,7 +1098,7 @@
payload["status"] = resolve_metadata_completion_status(
document.get("status"), document.get("metadata_extraction_status"),
)
return payload
return _with_current_excel_metadata(payload, document)
try:
_require_available_metadata(document)
config = import_module("config")
Expand Down Expand Up @@ -1116,7 +1134,7 @@
document.get("status"), document.get("metadata_extraction_status"),
)
payload["num_chunks"] = chunk_count_for_response(document)
return payload
return _with_current_excel_metadata(payload, document)


def public_documents_payload(documents, user_id=None, *, metadata_reader=None):
Expand Down
3 changes: 3 additions & 0 deletions application/single_app/content_screening/extraction.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from dataclasses import dataclass, field
from datetime import date, datetime, time
from pathlib import Path
from typing import Callable

from content_screening.contracts import (
CONTENT_METADATA_FIELDS,
Expand Down Expand Up @@ -43,6 +44,8 @@
completed: bool = False
preloaded_text: bool = False
failure_code: str | None = None
artifact_storage: object | None = field(default=None, repr=False, compare=False)

Check warning on line 47 in application/single_app/content_screening/extraction.py

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains secret or sensitive data source marker. Recommendation%3A Pair this source with any nearby network, logging, serialization, or process execution sink before approving.
heartbeat: Callable[[], None] | None = field(default=None, repr=False, compare=False)

def _append(self, target, unit):
self.characters += len(unit.text)
Expand Down
40 changes: 37 additions & 3 deletions application/single_app/content_screening/publication.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"""Application-side projection of inspected canonical content."""

import hashlib
import io
import json
import mimetypes
from urllib.parse import quote
Expand Down Expand Up @@ -171,6 +172,34 @@
)


def _tabular_publication_chunks(units, file_name, max_characters, *, include_native, schema_text=None):
chunks = publication_chunks([
ContentUnit("table-schema", table_schema_text(units) if schema_text is None else schema_text, {"kind": "schema"}),
], max_characters)
if not include_native or not any(unit.locator.get("kind") == "excel_native" for unit in units):
return chunks
prefix = f"### Excel native inspection\nWorkbook: {file_name}\nSearch preview; complete records are in the native inventory.\n"

Check warning on line 181 in application/single_app/content_screening/publication.py

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains secret or sensitive data source marker. Recommendation%3A Pair this source with any nearby network, logging, serialization, or process execution sink before approving.
if len(prefix) >= max_characters:
prefix = "### Excel native inspection\n"
if len(prefix) >= max_characters:
raise ScreeningValidationError("The publication chunk size cannot fit the Excel native evidence marker.")
remaining = 1000000
for unit in units:
if unit.locator.get("kind") != "excel_native" or remaining <= len(prefix):
continue
preview = ContentUnit(unit.unit_id, unit.text[:remaining], unit.locator)
for chunk in publication_chunks([preview], max_characters - len(prefix)):
if remaining <= len(prefix):
break
text = prefix + chunk["chunk_text"][:remaining - len(prefix)]
chunks.append({
**chunk, "chunk_text": text, "chunk_sequence": len(chunks) + 1,
"end": chunk["start"] + len(text) - len(prefix),
})
remaining -= len(text)
return chunks


def publish_document(document, units, scan, actor_id, *, storage):
helpers = _document_helpers()
subject = subject_from_document(document)
Expand All @@ -195,9 +224,14 @@
max(1, helpers.get_embedding_usable_tokens(settings) // 4),
)
if structured_sheets(units):
chunks = publication_chunks([
ContentUnit("table-schema", table_schema_text(units), {"kind": "schema"}),
], max_characters)
extension = "." + file_name.rsplit(".", 1)[-1].lower()
schema_text = None
if extension in {".xlsx", ".xlsm", ".xls"}:
schema_text = helpers._build_tabular_schema_summary(io.BytesIO(content), file_name, extension)
chunks = _tabular_publication_chunks(
units, file_name, max_characters, include_native=not scan.get("sanitized"),
schema_text=schema_text,
)
else:
chunks = publication_chunks(units, max_characters)
if not chunks:
Expand Down
7 changes: 6 additions & 1 deletion application/single_app/content_screening/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@
def _extract_and_inspect(scan, actor_id, source_path, processor, *, repository, storage, extraction_mode_override=None):
subject = Subject.from_dict(scan["subject"])
scan, owner = _claim_scan(repository, _read_scan(repository, scan["id"]))
capture = ExtractionCapture(subject, scan["id"], scan["original_file_name"])
capture = ExtractionCapture(subject, scan["id"], scan["original_file_name"], artifact_storage=storage)

Check warning on line 475 in application/single_app/content_screening/service.py

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains secret or sensitive data source marker. Recommendation%3A Pair this source with any nearby network, logging, serialization, or process execution sink before approving.
last_heartbeat = _now()

def heartbeat():
Expand Down Expand Up @@ -1049,6 +1049,11 @@
def prepare_document_deletion(document, actor_id, *, repository=None, storage=None):
"""Revoke a screened document before removing private evidence and originals."""
if SCREENING_FIELD not in document:
if (
"excel_native_inventory" in document
or str(document.get("file_name") or "").lower().endswith((".xlsx", ".xlsm", ".xls"))
):
_storage(storage).delete_revision(subject_from_document(document))

Check warning on line 1056 in application/single_app/content_screening/service.py

View workflow job for this annotation

GitHub Actions / malicious-pr-security-review

Important - Changed line contains secret or sensitive data source marker. Recommendation%3A Pair this source with any nearby network, logging, serialization, or process execution sink before approving.
return
repository = _repository(repository)
subject = subject_from_document(document)
Expand Down
Loading
Loading