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
2 changes: 2 additions & 0 deletions core/libs/nid/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ void _writeFile(const std::string& path, const std::vector<std::uint8_t>& data)
std::ofstream f(Nid::Internal::NativePath(path), std::ios::binary);
if (!f) throw std::runtime_error("cannot write: " + path);
f.write(reinterpret_cast<const char*>(data.data()), static_cast<std::streamsize>(data.size()));
f.close();
if (!f) throw std::runtime_error("cannot write: " + path);
}

}
Expand Down
27 changes: 27 additions & 0 deletions core/libs/nid/tests/test_native_paths.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import subprocess
import signal
import sys
import tempfile
import unittest
from pathlib import Path

from test_macho_nids import build_dylib, exports_of, nid

try:
import resource
except ImportError:
resource = None

PATCHER = Path(sys.argv.pop(1)).resolve()


Expand Down Expand Up @@ -51,6 +57,27 @@ def test_missing_unicode_input_does_not_modify_another_file(self):
self.assertFalse(missing.exists())
self.assertEqual(existing.read_bytes(), b"unchanged")

@unittest.skipUnless(resource is not None and hasattr(signal, "SIGXFSZ"), "requires POSIX file size limits")
def test_failed_file_write_is_reported_without_success(self):
for limit in (0, 1024):
with self.subTest(limit=limit), tempfile.TemporaryDirectory() as temporary:
file = Path(temporary) / "library.prx"
original = build_dylib([("_puts_nid_postfix", 0, 0x100)], [])
file.write_bytes(original)

def restrict_output():
signal.signal(signal.SIGXFSZ, signal.SIG_IGN)
resource.setrlimit(resource.RLIMIT_FSIZE, (limit, limit))

result = subprocess.run([str(PATCHER), "libtest", str(file)], capture_output=True,
encoding="utf-8", errors="replace", timeout=10,
preexec_fn=restrict_output)
self.assertEqual(file.stat().st_size, limit)
self.assertEqual(result.returncode, 2, result.stdout + result.stderr)
self.assertIn("cannot write", result.stderr)
self.assertIn(str(file), result.stderr)
self.assertNotIn("OK:", result.stdout)


if __name__ == "__main__":
unittest.main()
Loading