1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-11-26 19:47:20 +00:00

Fix 5483 & 3483 (#5504)

This commit is contained in:
Joshua Fontany 2021-03-26 01:39:32 -07:00 committed by GitHub
parent 226df2ad7d
commit a2e7cc51b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 34 deletions

View File

@ -2133,6 +2133,7 @@ $tw.loadWikiTiddlers = function(wikiPath,options) {
fileInfo = $tw.boot.files[title]; fileInfo = $tw.boot.files[title];
if(fileInfo.isEditableFile) { if(fileInfo.isEditableFile) {
relativePath = path.relative($tw.boot.wikiTiddlersPath,fileInfo.filepath); relativePath = path.relative($tw.boot.wikiTiddlersPath,fileInfo.filepath);
fileInfo.originalpath = relativePath;
output[title] = output[title] =
path.sep === "/" ? path.sep === "/" ?
relativePath : relativePath :

View File

@ -167,10 +167,10 @@ WikiFolderMaker.prototype.saveTiddler = function(directory,tiddler) {
} }
var fileInfo = $tw.utils.generateTiddlerFileInfo(tiddler,{ var fileInfo = $tw.utils.generateTiddlerFileInfo(tiddler,{
directory: path.resolve(this.wikiFolderPath,directory), directory: path.resolve(this.wikiFolderPath,directory),
wiki: this.wiki,
pathFilters: pathFilters, pathFilters: pathFilters,
extFilters: extFilters, extFilters: extFilters,
originalpath: this.wiki.extractTiddlerDataItem("$:/config/OriginalTiddlerPaths",title, "") wiki: this.wiki,
fileInfo: {}
}); });
try { try {
$tw.utils.saveTiddlerToFileSync(tiddler,fileInfo); $tw.utils.saveTiddlerToFileSync(tiddler,fileInfo);

View File

@ -213,13 +213,13 @@ Options include:
extFilters: optional array of filters to be used to generate the base path extFilters: optional array of filters to be used to generate the base path
wiki: optional wiki for evaluating the pathFilters, wiki: optional wiki for evaluating the pathFilters,
fileInfo: an existing fileInfo to check against fileInfo: an existing fileInfo to check against
originalpath: a preferred filepath if no pathFilters match
*/ */
exports.generateTiddlerFileInfo = function(tiddler,options) { exports.generateTiddlerFileInfo = function(tiddler,options) {
var fileInfo = {}, metaExt; var fileInfo = {}, metaExt;
// Propagate the isEditableFile flag // Propagate the isEditableFile flag
if(options.fileInfo) { if(options.fileInfo && !!options.fileInfo.isEditableFile) {
fileInfo.isEditableFile = options.fileInfo.isEditableFile || false; fileInfo.isEditableFile = true;
fileInfo.originalpath = options.fileInfo.originalpath;
} }
// Check if the tiddler has any unsafe fields that can't be expressed in a .tid or .meta file: containing control characters, or leading/trailing whitespace // Check if the tiddler has any unsafe fields that can't be expressed in a .tid or .meta file: containing control characters, or leading/trailing whitespace
var hasUnsafeFields = false; var hasUnsafeFields = false;
@ -247,7 +247,7 @@ exports.generateTiddlerFileInfo = function(tiddler,options) {
fileInfo.hasMetaFile = true; fileInfo.hasMetaFile = true;
} }
if(options.extFilters) { if(options.extFilters) {
// Check for extension override // Check for extension overrides
metaExt = $tw.utils.generateTiddlerExtension(tiddler.fields.title,{ metaExt = $tw.utils.generateTiddlerExtension(tiddler.fields.title,{
extFilters: options.extFilters, extFilters: options.extFilters,
wiki: options.wiki wiki: options.wiki
@ -279,8 +279,7 @@ exports.generateTiddlerFileInfo = function(tiddler,options) {
directory: options.directory, directory: options.directory,
pathFilters: options.pathFilters, pathFilters: options.pathFilters,
wiki: options.wiki, wiki: options.wiki,
fileInfo: options.fileInfo, fileInfo: options.fileInfo
originalpath: options.originalpath
}); });
return fileInfo; return fileInfo;
}; };
@ -292,8 +291,7 @@ Options include:
wiki: optional wiki for evaluating the extFilters wiki: optional wiki for evaluating the extFilters
*/ */
exports.generateTiddlerExtension = function(title,options) { exports.generateTiddlerExtension = function(title,options) {
var self = this, var extension;
extension;
// Check if any of the extFilters applies // Check if any of the extFilters applies
if(options.extFilters && options.wiki) { if(options.extFilters && options.wiki) {
$tw.utils.each(options.extFilters,function(filter) { $tw.utils.each(options.extFilters,function(filter) {
@ -319,11 +317,10 @@ Options include:
fileInfo: an existing fileInfo object to check against fileInfo: an existing fileInfo object to check against
*/ */
exports.generateTiddlerFilepath = function(title,options) { exports.generateTiddlerFilepath = function(title,options) {
var self = this, var directory = options.directory || "",
directory = options.directory || "",
extension = options.extension || "", extension = options.extension || "",
originalpath = options.originalpath || "", originalpath = (options.fileInfo && options.fileInfo.originalpath) ? options.fileInfo.originalpath : "",
filepath; filepath;
// Check if any of the pathFilters applies // Check if any of the pathFilters applies
if(options.pathFilters && options.wiki) { if(options.pathFilters && options.wiki) {
$tw.utils.each(options.pathFilters,function(filter) { $tw.utils.each(options.pathFilters,function(filter) {
@ -336,7 +333,7 @@ exports.generateTiddlerFilepath = function(title,options) {
} }
}); });
} }
if(!filepath && originalpath !== "") { if(!filepath && !!originalpath) {
//Use the originalpath without the extension //Use the originalpath without the extension
var ext = path.extname(originalpath); var ext = path.extname(originalpath);
filepath = originalpath.substring(0,originalpath.length - ext.length); filepath = originalpath.substring(0,originalpath.length - ext.length);
@ -345,27 +342,35 @@ exports.generateTiddlerFilepath = function(title,options) {
// Remove any forward or backward slashes so we don't create directories // Remove any forward or backward slashes so we don't create directories
filepath = filepath.replace(/\/|\\/g,"_"); filepath = filepath.replace(/\/|\\/g,"_");
} }
//If the path does not start with "." or ".." and a path seperator, then // Replace any Windows control codes
filepath = filepath.replace(/^(con|prn|aux|nul|com[0-9]|lpt[0-9])$/i,"_$1_");
// Replace any leading spaces with the same number of underscores
filepath = filepath.replace(/^ +/,function (u) { return u.replace(/ /g, "_")});
//If the path does not start with "." or ".." && a path seperator, then
if(!/^\.{1,2}[/\\]/g.test(filepath)) { if(!/^\.{1,2}[/\\]/g.test(filepath)) {
// Don't let the filename start with any dots because such files are invisible on *nix // Don't let the filename start with any dots because such files are invisible on *nix
filepath = filepath.replace(/^\.+/g,"_"); filepath = filepath.replace(/^\.+/g,function (u) { return u.replace(/\./g, "_")});
}
// Replace any Unicode control codes
filepath = filepath.replace(/[\x00-\x1f\x80-\x9f]/g,"_");
// Replace any characters that can't be used in cross-platform filenames
filepath = $tw.utils.transliterate(filepath.replace(/<|>|~|\:|\"|\||\?|\*|\^/g,"_"));
// Replace any dots or spaces at the end of the extension with the same number of underscores
extension = extension.replace(/[\. ]+$/, function (u) { return u.replace(/[\. ]/g, "_")});
// Truncate the extension if it is too long
if(extension.length > 32) {
extension = extension.substr(0,32);
} }
// If the filepath already ends in the extension then remove it // If the filepath already ends in the extension then remove it
if(filepath.substring(filepath.length - extension.length) === extension) { if(filepath.substring(filepath.length - extension.length) === extension) {
filepath = filepath.substring(0,filepath.length - extension.length); filepath = filepath.substring(0,filepath.length - extension.length);
} }
// Remove any characters that can't be used in cross-platform filenames
filepath = $tw.utils.transliterate(filepath.replace(/<|>|~|\:|\"|\||\?|\*|\^/g,"_"));
// Truncate the filename if it is too long // Truncate the filename if it is too long
if(filepath.length > 200) { if(filepath.length > 200) {
filepath = filepath.substr(0,200); filepath = filepath.substr(0,200);
} }
// Truncate the extension if it is too long // If the resulting filename is blank (eg because the title is just punctuation)
if(extension.length > 32) { if(!filepath || /^_+$/g.test(filepath)) {
extension = extension.substr(0,32);
}
// If the resulting filename is blank (eg because the title is just punctuation characters)
if(!filepath) {
// ...then just use the character codes of the title // ...then just use the character codes of the title
filepath = ""; filepath = "";
$tw.utils.each(title.split(""),function(char) { $tw.utils.each(title.split(""),function(char) {
@ -386,14 +391,15 @@ exports.generateTiddlerFilepath = function(title,options) {
count++; count++;
} while(fs.existsSync(fullPath)); } while(fs.existsSync(fullPath));
// If the last write failed with an error, or if path does not start with: // If the last write failed with an error, or if path does not start with:
// the resolved options.directory, the resolved wikiPath directory, or the wikiTiddlersPath directory, // the resolved options.directory, the resolved wikiPath directory, the wikiTiddlersPath directory,
// then encodeURIComponent() and resolve to tiddler directory // or the 'originalpath' directory, then encodeURIComponent() and resolve to tiddler directory.
var writePath = $tw.hooks.invokeHook("th-make-tiddler-path",fullPath), var writePath = $tw.hooks.invokeHook("th-make-tiddler-path",fullPath,fullPath),
encode = (options.fileInfo || {writeError: false}).writeError == true; encode = (options.fileInfo || {writeError: false}).writeError == true;
if(!encode) { if(!encode) {
encode = !(fullPath.indexOf(path.resolve(directory)) == 0 || encode = !(writePath.indexOf($tw.boot.wikiTiddlersPath) == 0 ||
fullPath.indexOf(path.resolve($tw.boot.wikiPath)) == 0 || writePath.indexOf(path.resolve(directory)) == 0 ||
fullPath.indexOf($tw.boot.wikiTiddlersPath) == 0); writePath.indexOf(path.resolve($tw.boot.wikiPath)) == 0 ||
writePath.indexOf(path.resolve($tw.boot.wikiTiddlersPath,originalpath)) == 0 );
} }
if(encode) { if(encode) {
writePath = path.resolve(directory,encodeURIComponent(fullPath)); writePath = path.resolve(directory,encodeURIComponent(fullPath));

View File

@ -53,7 +53,8 @@ It is the responsibility of the filesystem adaptor to update this.boot.files for
*/ */
FileSystemAdaptor.prototype.getTiddlerFileInfo = function(tiddler,callback) { FileSystemAdaptor.prototype.getTiddlerFileInfo = function(tiddler,callback) {
// Always generate a fileInfo object when this fuction is called // Always generate a fileInfo object when this fuction is called
var title = tiddler.fields.title, newInfo, pathFilters, extFilters; var title = tiddler.fields.title, newInfo, pathFilters, extFilters,
fileInfo = this.boot.files[title];
if(this.wiki.tiddlerExists("$:/config/FileSystemPaths")) { if(this.wiki.tiddlerExists("$:/config/FileSystemPaths")) {
pathFilters = this.wiki.getTiddlerText("$:/config/FileSystemPaths","").split("\n"); pathFilters = this.wiki.getTiddlerText("$:/config/FileSystemPaths","").split("\n");
} }
@ -65,8 +66,7 @@ FileSystemAdaptor.prototype.getTiddlerFileInfo = function(tiddler,callback) {
pathFilters: pathFilters, pathFilters: pathFilters,
extFilters: extFilters, extFilters: extFilters,
wiki: this.wiki, wiki: this.wiki,
fileInfo: this.boot.files[title], fileInfo: fileInfo
originalpath: this.wiki.extractTiddlerDataItem("$:/config/OriginalTiddlerPaths",title,"")
}); });
callback(null,newInfo); callback(null,newInfo);
}; };