aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--org/in_abstraction_artefacts.org44
-rw-r--r--src/sisudoc/ocda/abstraction/doc_from_artefact.d44
2 files changed, 78 insertions, 10 deletions
diff --git a/org/in_abstraction_artefacts.org b/org/in_abstraction_artefacts.org
index f688c33..bbbdbd9 100644
--- a/org/in_abstraction_artefacts.org
+++ b/org/in_abstraction_artefacts.org
@@ -1215,9 +1215,12 @@ template spineDocFromArtefact() {
import std.digest.sha : sha256Of;
import std.file : mkdirRecurse, write, tempDir;
import sisudoc.ocda.abstraction.db_in : spineAbstractionDbRead;
+ import sisudoc.ocda.abstraction.pod_from_db : spinePodFromDb;
mixin spineAbstractionDbRead _dbr;
+ mixin spinePodFromDb _pfd;
auto _files = _dbr.dbReadFiles(_artefact, "image");
- if (_files.length == 0) { return ""; }
+ auto _manifest = _dbr.dbReadFiles(_artefact, "manifest");
+ if (_files.length == 0 && _manifest.length == 0) { return ""; }
/+ ↓ every name checked before anything is created or written.
the name comes out of the database and a database can be
downloaded, so it is attacker-controlled: it can climb with "..",
@@ -1236,8 +1239,25 @@ template spineDocFromArtefact() {
return "";
}
}
- string _root = (tempDir.chainPath("spine-ocda-"
+ /+ ↓ the directory this makes is a pod, named for the document, and not
+ a bare place to put images.
+ .
+ Because a document's output files are named from its pod: no pod,
+ and doc_uid_out takes its other branch and prefixes an underscore,
+ so the same database rendered here wrote _live-manual.en.txt where
+ the pod it came from writes live-manual.en.txt. It mixed environment:
+ a database sitting beside a pod tree borrowed that pod's name and got
+ it right, and the same database moved elsewhere did not.
+ .
+ A database carries its own pod.manifest, so it can say what it is
+ called without being told. Written here beside the images, which
+ makes this a pod as far as PathMatters is concerned, and the naming
+ is then the document's own wherever the file happens to be.
+ +/
+ string _tmp = (tempDir.chainPath("spine-ocda-"
~ _artefact.baseName ~ "-" ~ thisProcessID.to!string).array).to!string;
+ string _root = (_tmp.chainPath(_pfd.podNameFromDbPath(_artefact))
+ .array).to!string;
string _img_dir = (_root.chainPath("media").chainPath("image").array).to!string;
try {
_img_dir.mkdirRecurse;
@@ -1246,6 +1266,16 @@ template spineDocFromArtefact() {
": ", ex.msg);
return "";
}
+ foreach (_m; _manifest) {
+ if (validateCarriedPath(_m.name).length > 0) { continue; }
+ string _m_path = (_root.chainPath(_m.name).array).to!string;
+ if (!(carriedPathIsWithin(_root, _m_path))) { continue; }
+ try {
+ _m_path.write(_m.data);
+ } catch (Exception ex) {
+ stderr.writeln("WARNING: could not write ", _m.name, ": ", ex.msg);
+ }
+ }
foreach (_f; _files) {
string _got = _f.data.sha256Of.toHexString.to!string;
if (_f.sha256.length > 0 && _got != _f.sha256) {
@@ -1348,9 +1378,13 @@ template spineDocFromArtefact() {
} else {
string _extracted = _imagesExtract(_artefact, _opt_action);
if (_extracted.length > 0) {
- /+ ↓ the source path has to move with it: image_dir_path is
- reached from the document's own file, not from the pod +/
- _images_tmp = _extracted;
+ /+ ↓ the source path has to move with it: image_dir_path is reached
+ from the document's own file, not from the pod. What is removed
+ afterwards is the pod's *parent*, the directory this run made:
+ the pod inside it is named for the document, and removing only
+ that would leave the parent.
+ +/
+ _images_tmp = _extracted.dirName;
_pths.pod_dir = _extracted;
_pths.src_file_with_path = (_extracted
.chainPath("media").chainPath("text")
diff --git a/src/sisudoc/ocda/abstraction/doc_from_artefact.d b/src/sisudoc/ocda/abstraction/doc_from_artefact.d
index fa620f8..b3d208c 100644
--- a/src/sisudoc/ocda/abstraction/doc_from_artefact.d
+++ b/src/sisudoc/ocda/abstraction/doc_from_artefact.d
@@ -247,9 +247,12 @@ template spineDocFromArtefact() {
import std.digest.sha : sha256Of;
import std.file : mkdirRecurse, write, tempDir;
import sisudoc.ocda.abstraction.db_in : spineAbstractionDbRead;
+ import sisudoc.ocda.abstraction.pod_from_db : spinePodFromDb;
mixin spineAbstractionDbRead _dbr;
+ mixin spinePodFromDb _pfd;
auto _files = _dbr.dbReadFiles(_artefact, "image");
- if (_files.length == 0) { return ""; }
+ auto _manifest = _dbr.dbReadFiles(_artefact, "manifest");
+ if (_files.length == 0 && _manifest.length == 0) { return ""; }
/+ ↓ every name checked before anything is created or written.
the name comes out of the database and a database can be
downloaded, so it is attacker-controlled: it can climb with "..",
@@ -268,8 +271,25 @@ template spineDocFromArtefact() {
return "";
}
}
- string _root = (tempDir.chainPath("spine-ocda-"
+ /+ ↓ the directory this makes is a pod, named for the document, and not
+ a bare place to put images.
+ .
+ Because a document's output files are named from its pod: no pod,
+ and doc_uid_out takes its other branch and prefixes an underscore,
+ so the same database rendered here wrote _live-manual.en.txt where
+ the pod it came from writes live-manual.en.txt. It mixed environment:
+ a database sitting beside a pod tree borrowed that pod's name and got
+ it right, and the same database moved elsewhere did not.
+ .
+ A database carries its own pod.manifest, so it can say what it is
+ called without being told. Written here beside the images, which
+ makes this a pod as far as PathMatters is concerned, and the naming
+ is then the document's own wherever the file happens to be.
+ +/
+ string _tmp = (tempDir.chainPath("spine-ocda-"
~ _artefact.baseName ~ "-" ~ thisProcessID.to!string).array).to!string;
+ string _root = (_tmp.chainPath(_pfd.podNameFromDbPath(_artefact))
+ .array).to!string;
string _img_dir = (_root.chainPath("media").chainPath("image").array).to!string;
try {
_img_dir.mkdirRecurse;
@@ -278,6 +298,16 @@ template spineDocFromArtefact() {
": ", ex.msg);
return "";
}
+ foreach (_m; _manifest) {
+ if (validateCarriedPath(_m.name).length > 0) { continue; }
+ string _m_path = (_root.chainPath(_m.name).array).to!string;
+ if (!(carriedPathIsWithin(_root, _m_path))) { continue; }
+ try {
+ _m_path.write(_m.data);
+ } catch (Exception ex) {
+ stderr.writeln("WARNING: could not write ", _m.name, ": ", ex.msg);
+ }
+ }
foreach (_f; _files) {
string _got = _f.data.sha256Of.toHexString.to!string;
if (_f.sha256.length > 0 && _got != _f.sha256) {
@@ -380,9 +410,13 @@ template spineDocFromArtefact() {
} else {
string _extracted = _imagesExtract(_artefact, _opt_action);
if (_extracted.length > 0) {
- /+ ↓ the source path has to move with it: image_dir_path is
- reached from the document's own file, not from the pod +/
- _images_tmp = _extracted;
+ /+ ↓ the source path has to move with it: image_dir_path is reached
+ from the document's own file, not from the pod. What is removed
+ afterwards is the pod's *parent*, the directory this run made:
+ the pod inside it is named for the document, and removing only
+ that would leave the parent.
+ +/
+ _images_tmp = _extracted.dirName;
_pths.pod_dir = _extracted;
_pths.src_file_with_path = (_extracted
.chainPath("media").chainPath("text")