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];
if(fileInfo.isEditableFile) {
relativePath = path.relative($tw.boot.wikiTiddlersPath,fileInfo.filepath);
fileInfo.originalpath = relativePath;
output[title] =
path.sep === "/" ?
relativePath :

View File

@ -167,10 +167,10 @@ WikiFolderMaker.prototype.saveTiddler = function(directory,tiddler) {
}
var fileInfo = $tw.utils.generateTiddlerFileInfo(tiddler,{
directory: path.resolve(this.wikiFolderPath,directory),
wiki: this.wiki,
pathFilters: pathFilters,
extFilters: extFilters,
originalpath: this.wiki.extractTiddlerDataItem("$:/config/OriginalTiddlerPaths",title, "")
wiki: this.wiki,
fileInfo: {}
});
try {
$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
wiki: optional wiki for evaluating the pathFilters,
fileInfo: an existing fileInfo to check against
originalpath: a preferred filepath if no pathFilters match
*/
exports.generateTiddlerFileInfo = function(tiddler,options) {
var fileInfo = {}, metaExt;
// Propagate the isEditableFile flag
if(options.fileInfo) {
fileInfo.isEditableFile = options.fileInfo.isEditableFile || false;
if(options.fileInfo && !!options.fileInfo.isEditableFile) {
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
var hasUnsafeFields = false;
@ -247,7 +247,7 @@ exports.generateTiddlerFileInfo = function(tiddler,options) {
fileInfo.hasMetaFile = true;
}
if(options.extFilters) {
// Check for extension override
// Check for extension overrides
metaExt = $tw.utils.generateTiddlerExtension(tiddler.fields.title,{
extFilters: options.extFilters,
wiki: options.wiki
@ -279,8 +279,7 @@ exports.generateTiddlerFileInfo = function(tiddler,options) {
directory: options.directory,
pathFilters: options.pathFilters,
wiki: options.wiki,
fileInfo: options.fileInfo,
originalpath: options.originalpath
fileInfo: options.fileInfo
});
return fileInfo;
};
@ -292,8 +291,7 @@ Options include:
wiki: optional wiki for evaluating the extFilters
*/
exports.generateTiddlerExtension = function(title,options) {
var self = this,
extension;
var extension;
// Check if any of the extFilters applies
if(options.extFilters && options.wiki) {
$tw.utils.each(options.extFilters,function(filter) {
@ -319,11 +317,10 @@ Options include:
fileInfo: an existing fileInfo object to check against
*/
exports.generateTiddlerFilepath = function(title,options) {
var self = this,
directory = options.directory || "",
var directory = options.directory || "",
extension = options.extension || "",
originalpath = options.originalpath || "",
filepath;
originalpath = (options.fileInfo && options.fileInfo.originalpath) ? options.fileInfo.originalpath : "",
filepath;
// Check if any of the pathFilters applies
if(options.pathFilters && options.wiki) {
$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
var ext = path.extname(originalpath);
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
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)) {
// 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(filepath.substring(filepath.length - extension.length) === extension) {
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
if(filepath.length > 200) {
filepath = filepath.substr(0,200);
}
// Truncate the extension if it is too long
if(extension.length > 32) {
extension = extension.substr(0,32);
}
// If the resulting filename is blank (eg because the title is just punctuation characters)
if(!filepath) {
// If the resulting filename is blank (eg because the title is just punctuation)
if(!filepath || /^_+$/g.test(filepath)) {
// ...then just use the character codes of the title
filepath = "";
$tw.utils.each(title.split(""),function(char) {
@ -386,14 +391,15 @@ exports.generateTiddlerFilepath = function(title,options) {
count++;
} while(fs.existsSync(fullPath));
// 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,
// then encodeURIComponent() and resolve to tiddler directory
var writePath = $tw.hooks.invokeHook("th-make-tiddler-path",fullPath),
// the resolved options.directory, the resolved wikiPath directory, the wikiTiddlersPath directory,
// or the 'originalpath' directory, then encodeURIComponent() and resolve to tiddler directory.
var writePath = $tw.hooks.invokeHook("th-make-tiddler-path",fullPath,fullPath),
encode = (options.fileInfo || {writeError: false}).writeError == true;
if(!encode) {
encode = !(fullPath.indexOf(path.resolve(directory)) == 0 ||
fullPath.indexOf(path.resolve($tw.boot.wikiPath)) == 0 ||
fullPath.indexOf($tw.boot.wikiTiddlersPath) == 0);
encode = !(writePath.indexOf($tw.boot.wikiTiddlersPath) == 0 ||
writePath.indexOf(path.resolve(directory)) == 0 ||
writePath.indexOf(path.resolve($tw.boot.wikiPath)) == 0 ||
writePath.indexOf(path.resolve($tw.boot.wikiTiddlersPath,originalpath)) == 0 );
}
if(encode) {
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) {
// 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")) {
pathFilters = this.wiki.getTiddlerText("$:/config/FileSystemPaths","").split("\n");
}
@ -65,8 +66,7 @@ FileSystemAdaptor.prototype.getTiddlerFileInfo = function(tiddler,callback) {
pathFilters: pathFilters,
extFilters: extFilters,
wiki: this.wiki,
fileInfo: this.boot.files[title],
originalpath: this.wiki.extractTiddlerDataItem("$:/config/OriginalTiddlerPaths",title,"")
fileInfo: fileInfo
});
callback(null,newInfo);
};