Files
wehub-resource-sync e904b667c6
PaddleOCR PR Tests GPU / test-pr-gpu (push) Blocked by required conditions
PaddleOCR PR Tests / test-pr (push) Blocked by required conditions
PaddleOCR PR Tests / test-pr-python (3.8) (push) Waiting to run
Build/Publish Develop Docs / deploy (push) Failing after 1s
PaddleOCR Code Style Check / check-code-style (push) Failing after 1s
PaddleOCR PR Tests GPU / detect-changes (push) Failing after 1s
PaddleOCR PR Tests GPU / test-pr-gpu-impl (push) Waiting to run
PaddleOCR PR Tests / detect-changes (push) Failing after 1s
PaddleOCR PR Tests / test-pr-python (3.13) (push) Waiting to run
PaddleOCR PR Tests / test-pr-python (3.9) (push) Waiting to run
chore: import upstream snapshot with attribution
2026-07-13 11:59:26 +08:00

151 lines
4.8 KiB
Python

# Copyright (c) 2026 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import importlib.util
import os
import pickle
import sys
import types
from pathlib import Path
import pytest
REPO_ROOT = Path(__file__).resolve().parents[2]
def _stub_module(monkeypatch, name, **attrs):
module = types.ModuleType(name)
for key, value in attrs.items():
setattr(module, key, value)
monkeypatch.setitem(sys.modules, name, module)
return module
def _load_lmdb_dataset_module(monkeypatch, lmdb_open):
_stub_module(monkeypatch, "cv2")
_stub_module(
monkeypatch, "numpy", random=types.SimpleNamespace(randint=lambda upper: 0)
)
_stub_module(monkeypatch, "lmdb", open=lmdb_open)
_stub_module(monkeypatch, "PIL")
_stub_module(monkeypatch, "PIL.Image")
paddle_module = _stub_module(monkeypatch, "paddle")
paddle_io_module = _stub_module(
monkeypatch, "paddle.io", Dataset=type("Dataset", (), {})
)
paddle_module.io = paddle_io_module
ppocr_module = _stub_module(monkeypatch, "ppocr")
ppocr_data_module = _stub_module(monkeypatch, "ppocr.data")
ppocr_data_module.__path__ = []
ppocr_module.data = ppocr_data_module
_stub_module(
monkeypatch,
"ppocr.data.imaug",
transform=lambda data, ops: data,
create_operators=lambda *args, **kwargs: [],
)
spec = importlib.util.spec_from_file_location(
"ppocr.data.lmdb_dataset", REPO_ROOT / "ppocr" / "data" / "lmdb_dataset.py"
)
module = importlib.util.module_from_spec(spec)
monkeypatch.setitem(sys.modules, "ppocr.data.lmdb_dataset", module)
spec.loader.exec_module(module)
return module
class _Exploit:
def __reduce__(self):
return (os.system, ("echo SHOULD_NOT_RUN > /tmp/paddleocr_lmdb_pickle_test",))
class _Txn:
def __init__(self, values):
self._values = values
def get(self, key):
return self._values.get(key)
class _Env:
def __init__(self, txn):
self._txn = txn
def begin(self, write=False):
return self._txn
@pytest.fixture(autouse=True)
def _cleanup_marker():
marker = Path("/tmp/paddleocr_lmdb_pickle_test")
marker.unlink(missing_ok=True)
yield
marker.unlink(missing_ok=True)
def test_tablemaster_sample_info_rejects_pickle_rce_payload(monkeypatch):
module = _load_lmdb_dataset_module(
monkeypatch, lmdb_open=lambda *args, **kwargs: None
)
payload = pickle.dumps(_Exploit())
txn = _Txn({b"1": payload})
dataset = module.LMDBDataSetTableMaster.__new__(module.LMDBDataSetTableMaster)
assert dataset.get_lmdb_sample_info(txn, 1) is None
assert not Path("/tmp/paddleocr_lmdb_pickle_test").exists()
def test_tablemaster_sample_info_accepts_expected_basic_pickle_data(monkeypatch):
module = _load_lmdb_dataset_module(
monkeypatch, lmdb_open=lambda *args, **kwargs: None
)
safe_payload = pickle.dumps(("sample.png", b"img-bytes", "raw-name\ntext\n1,2,3,4"))
txn = _Txn({b"1": safe_payload})
dataset = module.LMDBDataSetTableMaster.__new__(module.LMDBDataSetTableMaster)
sample = dataset.get_lmdb_sample_info(txn, 1)
assert sample["file_name"] == "sample.png"
assert sample["image"] == b"img-bytes"
assert sample["structure"] == ["text"]
assert sample["cells"] == [{"bbox": [1, 2, 3, 4], "tokens": ["1", "2"]}]
def test_tablemaster_length_metadata_rejects_pickle_rce_payload(monkeypatch):
payload = pickle.dumps(_Exploit())
txn = _Txn({b"__len__": payload})
module = _load_lmdb_dataset_module(
monkeypatch, lmdb_open=lambda *args, **kwargs: _Env(txn)
)
dataset = module.LMDBDataSetTableMaster.__new__(module.LMDBDataSetTableMaster)
with pytest.raises(pickle.UnpicklingError):
dataset.load_hierarchical_lmdb_dataset("/tmp/ignored")
assert not Path("/tmp/paddleocr_lmdb_pickle_test").exists()
def test_tablemaster_length_metadata_accepts_expected_integer_pickle(monkeypatch):
txn = _Txn({b"__len__": pickle.dumps(7)})
module = _load_lmdb_dataset_module(
monkeypatch, lmdb_open=lambda *args, **kwargs: _Env(txn)
)
dataset = module.LMDBDataSetTableMaster.__new__(module.LMDBDataSetTableMaster)
lmdb_sets = dataset.load_hierarchical_lmdb_dataset("/tmp/ignored")
assert lmdb_sets[0]["num_samples"] == 7