diff options
| -rw-r--r-- | org/in_abstraction_artefacts.org | 44 | ||||
| -rw-r--r-- | src/sisudoc/ocda/abstraction/doc_from_artefact.d | 44 |
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") |
