Mudlet: 文件路径中具有非ASCII的Windows用户无法加载LuaGlobal

创建于 2018-04-17  ·  38评论  ·  资料来源: Mudlet/Mudlet

问题摘要/请求的功能描述:

  1. 重新安装了Mudlet,并以新的配置文件开始。
  2. 出现错误信息,请参见下文。
  3. Mudlet缺少核心功能,例如间歇泉。

用户/目录名称中的特殊字符不应影响/阻碍Mudlet的功能。
这似乎是Mudlet的最新更新。
还打破了不仅仅是Geyser的功能。

重现问题的步骤/添加功能的原因:

  1. 可以在我的1号计算机上多次复制,但不能在2号计算机上复制
  2. 完整路径为C:\ Users \Eingeschränkt\ AppDataLocal \ Mudlet-也许是因为用户名中的特殊字符?
  3. @keneanung评论:实施自动更新程序时,我们将安装目录从C:\Program Files\更改为用户配置文件,我不记得最近在该位置进行了任何更改。 代码_looks_好像应该正确处理UTF-8路径名

错误输出/功能的预期结果

[错误] LuaGlobal.lua编译错误
来自Lua的错误:无法打开/LuaGlobal.lua:没有此类文件或目录
grafik

额外信息,例如Mudlet版本,操作系统以及有关如何解决/实施的想法:

Win7上的Mudlet 3.8.1

Windows bug i18n & l10n medium

所有38条评论

Windows的路径名很奇怪-Lua中的文件函数必须使用正确的斜杠路径名。 在C ++代码中,如果我们不使用C ++ 11原始字符串文字(并且我们可能被迫不使用QObject::tr( ... )来处理Qt错误)单个/如果要发送给lua函数,则将nix系统的硬编码路径名中的/加倍转义*为\\\\ -C ++编译剥离每个\\下降到\并且lua解释器中也会发生相同的情况。

碰巧的是, [ ERROR ]消息中的路径看起来像是在LuaGlobal.lua文件名之前的路径保留为./默认值,因此预期它位于与Mudlet可执行文件相同的目录-但是对于* Doze,至少应该在C ++源代码中将其更改为.\\.\\\\

这也意味着我认为,如果我们在将要使用的C ++代码中将路径/文件名写为原始字符串,则QDir::nativeSeparators( ... )静态方法不能做正确的事被作为字符串输入到Lua解释器中。

不知道我是否理解您的评论,或者它们是否实际上实际上是针对我的.. :)

除了从头开始配置一个新用户之外,您是否有机会解决这个问题?

对于任何看过它的人来说,它更像是一个普遍的观察。 应该有可能通过查看用于加载LuaGlobel.lua文件的路径来修复它,尤其是在Windows平台上。 我怀疑操作系统已使用某些默认值-可能是“与可执行文件相同的目录”,但由于非POSIX路径而不合适。

看一下我认为是这个问题的原因:

void TLuaInterpreter::loadGlobal()
{
#if defined(Q_OS_MACOS)
    // Load relatively to MacOS inside Resources when we're in a .app bundle,
    // as mudlet-lua always gets copied in by the build script into the bundle
    QString path = QCoreApplication::applicationDirPath() + "/../Resources/mudlet-lua/lua/LuaGlobal.lua";
#else
    // Additional "../src/" allows location of lua code when object code is in a
    // directory alongside src directory as occurs using Qt Creator "Shadow Builds"
    QString path = "../src/mudlet-lua/lua/LuaGlobal.lua"; // <== A
#endif

    int error = luaL_dofile(pGlobalLua, path.toUtf8().constData());
    if (error != 0) {
        // For the installer we do not go down a level to search for this. So
        // we check again for the user case of a windows install.

        // overload previous behaviour to check by absolute path as well
        // TODO this sould be cleaned up and refactored to just use an array and a for loop
        path = QCoreApplication::applicationDirPath() + "/mudlet-lua/lua/LuaGlobal.lua"; // <== B
        if (!QFileInfo::exists(path)) {
            path = "mudlet-lua/lua/LuaGlobal.lua"; // <== C
        }
        error = luaL_dofile(pGlobalLua, path.toUtf8().constData());
        if (error == 0) {
            mpHost->postMessage("[  OK  ]  - Mudlet-lua API & Geyser Layout manager loaded.");
            return;
        }
    } else {
        mpHost->postMessage("[  OK  ]  - Mudlet-lua API & Geyser Layout manager loaded.");
        return;
    }

    // Finally try loading from LUA_DEFAULT_PATH
    path = LUA_DEFAULT_PATH "/LuaGlobal.lua"; // <== D
    error = luaL_dofile(pGlobalLua, path.toUtf8().constData());
    if (error != 0) {
        string e = "no error message available from Lua";
        if (lua_isstring(pGlobalLua, -1)) {
            e = "[ ERROR ] - LuaGlobal.lua compile error - please report!\n"
                "Error from Lua: ";
            e += lua_tostring(pGlobalLua, -1);
        }
        mpHost->postMessage(e.c_str());
    } else {
        mpHost->postMessage("[  OK  ]  - Mudlet-lua API & Geyser Layout manager loaded.");
        return;
    }
}

这立即看起来有点狡猾,因为Windows的A到D都是错误的,例如A应该是"..\\\\src\\\\mudlet-lua\\\\lua\\\\LuaGlobal.lua"但是其他人需要在运行时将/替换为\\\\文字字符串和包含的变量。 该主题顶部的原始错误是因为LUA_DEFAULT_PATH在Windows上使用时为空!

记住,如果调试此命令,屏幕上的[ ERROR ]消息将重现一条路径,我认为\\\没有转义,所以应该看起来像是正确的,真实的屏幕上的Windows路径-在给定的情况下为\LuaGobal.lua -可能也是错误的,应该是.\LuaGobal.lua -所以LUA_DEFAULT_PATH应该是.\\\\改为

Windows上的Lua可以将/作为目录分隔符来处理。

这并不是我的有限经验-IIRC在lua内容中的某个地方有一个配置设置,其中包含4个字符的数组,其中包含编译后的设置,其中包括程序包名称和目录分隔符中的通配符。 我回想起这是因为,当我过去固定Windows和* nix文件路径的LuaGlobal.lua(内部)处理时,我确实使用过检查功能,我认为一个C数组索引会进入config char '\\''/' char数组-尽管我认为随后找到了更好的解决方案。

啊,哈-是的-看到package.config变量-就是这样,来自Lua非官方常见问题解答

1.40 Windows和Unix之间的兼容性问题?

在这里,“ Unix”代表任何类似POSIX的操作系统,例如Linux,Mac OS X,Solaris等。

package.config是一个字符串,其中第一个“字符”是目录分隔符; 因此package.config:sub(1,1)是斜杠或反斜杠。 通常,在构建路径时请尝试使用它。

Windows和Unix版本之间的最大区别是默认package.path基于Windows可执行文件的位置,而在Unix上则基于/usr/local/share/lua/5.1 。 因此,在Windows上进行Lua的本地用户安装比较容易,但是Lua尊重环境变量LUA_PATHLUA_CPATH

与大多数脚本语言相比,Lua更直接地依赖于系统的C运行时库,因此您必须了解平台的差异。 如果需要与Windows二进制I / O兼容,请将"rb"说明符与io.open一起使用。 请小心os.tmpname因为它在Windows上不会返回完整路径(带有TMP环境变量的值的前缀以及反斜杠的前缀)。 os.clock的实现非常简单。在Windows上有所不同。

同样,如果传递了不兼容的格式说明符,则os.time实际上会使Lua崩溃。 (这不再是Lua 5.2的问题,它先进行完整性检查。)

对于Windows GUI子系统, os.execute可能很烦人,而io.popen根本不起作用-在这种情况下,可以使用跨平台扩展库。

“作为一般规则”-不能反驳/作为目录分隔符在Lua的Windows上可以正常工作的事实。

这就是它-对有些人,包括我自己,工作-这很可能是我没有按照正常的引用的食谱(或者说我有一个Cygwin的安装周围也一样)准备了LUA安装。

我想知道-您是否有可能混淆lua子系统(或更确切地说是其包的一部分)对目录分隔符的处理-可以以任何一种方式(或可能完全以其他方式配置'来配置) RISCOS显然!

对于在Windows平台上编译的lua安装应该使用什么功能,这确实使我感到困惑-啊,可能是msys是POSIX式的,但mingw是Windowish的吗?

不,我不是,这也是为什么在LuaGlobal.lua中使用/可以在当前状态下在Windows上为许多人工作的原因...

selection_112

路径分隔符在这里不是问题。

因此,可以假定Qt的mingw中的lua解释器已为Windows正确配置,并且它使用的是Mudlet应用程序链接到的相同liblua {我想,不是每个人都可以}。 例如, luarocks提供了lua 5.1解释器,如果找不到其他解释器,则可以使用它,但由于相同的原因,它的库可能会被使用。

💡啊,我想知道, @ Kebap ,如果尝试在导致错误的设置上获取package.config的值,会得到什么? 对于我来说,例如在当前运行的系统上的命令行中:

[stephen<strong i="11">@ripley</strong> ~]$ lua51
Lua 5.1.5  Copyright (C) 1994-2012 Lua.org, PUC-Rio
> print(package.config)
/
;
?
!
-
> ^D
[stephen<strong i="12">@ripley</strong> ~]$

注意第一个值/是加载包时将使用的当前目录分隔符-例如LuaGlobal.lua文件! 当然,如果没有外部lua脚本运行/可用,我将无法回忆起是否可以从Mudlet中的“命令行”运行内容。 稍后,我将尝试启动我的“打ze笔记本电脑”,然后看看我在那台笔记本电脑上得到了什么...

当然可以尝试:
grafik
好像有一个反斜杠,而您有一个正斜杠

不知道我是否应该在Mudlet中尝试此操作,因为您似乎使用了不同的方式和位置。

我可以创建一个或两个带有或不带有特殊字符的新用户,只是要确保用户名确实是这里的问题。 您认为这有帮助吗?

是的,请尝试

2018年4月25日,星期三,基巴布,下午6:48, notifications @ github.com写道:

我可以创建一个或两个带有或不带有特殊字符的新用户,
只是要确保用户名确实是这里的问题。 你认为
有帮助吗?

-
您收到此邮件是因为您发表了评论。

直接回复此电子邮件,在GitHub上查看
https://github.com/Mudlet/Mudlet/issues/1616#issuecomment-384355980或静音
线程
https://github.com/notifications/unsubscribe-auth/AAGxjN9JHbiPCOgUf3u1u8jVg0KjDiSbks5tsKj3gaJpZM4TZAbQ

据我所知,代码正在尝试LuaGlobal.lua文件的所有建议位置,最后到达尝试的位置:

LUA_DEFAULT_PATH "/LuaGlobal.lua"

但是,从产生的错误消息看来,LUA_DEFAULT_PATH是一个空字符串,因此使用的路径是:

/LuaGlobal.lua

假设(并且我仍然不相信,但是希望这只是我的问题)'/'是在其中使用的可行目录分隔符,这意味着在文件系统的根目录中查找文件-在POSIX上实际上是根目录,在Windows上,它是当前活动驱动器上的根目录,可能是C:\ (或C:/ :wink :)-如果我们真的希望它成为当前工作目录,LUA_DEFAULT_PATH应该是单个.字符,并且不能完全为空-在这种情况下,错误消息将返回:

... cannot open ./LuaGlobal.lua ...

或者它返回完整路径,可能类似于:

... cannot open C:/Users/Eingeschränkt/AppData/Local/Mudlet/LuaGlobal.lua ...

也许? 😮

我看到来自lua解释器的错误消息在std::string捕获,并通过std::string::c_str()转换为cTelnet::postMessage( ... ) const char *但是由于postMessage期望的是QString因此应该使用QString :: QString(const char str)构造函数,该QString::fromUtf8()转换器,因此非ASCII字符*应使其完整无损...😌

\

lua print(package.config)

从Mudlet配置文件命令行,即使出现错误。

这有点投机性,但作为运行时修复程序,我想知道是否可以做类似的事情:

lua package.config = "/;?!_"

将分隔符更改为/ -尽管您可能希望在首选项中更改“命令分隔符”设置,以使它不会在;拆分以上内容-然后查看是否可以手动“运行” LuaGlobal.lua文件? 哦,即使无法正常运行,它也不会提供[ ERROR ]类型的错误消息。 \

在Win 8.1上使用用户名带有特殊字符ä的Mudlet 3.8.1的已确认错误:ä。
没有特殊字符的用户名没有错误。

lua print(package.config)无可见结果
lua print('test')也没有可见结果
lua别名可用,但print似乎不可用
lua echo('test')可以正常工作

lua package.config = "/;?!_"
错误日志显示: ERROR:[string "Alias: run lua code"]:4: [string "package.config = "/"]:1: unfinished string near '<eof>'

将命令分隔符从;更改为去别的东西

lua package.config = "/;?!_"
我觉得可以吧? 结果不可见

lua run("./LuaGlobal.lua")
错误日志显示: ERROR:[string "return run("./LuaGlobal.lua")"]:1: attempt to call global 'run' (a nil value)

include -同样的错误。

lua require("./LuaGlobal.lua") -有趣的错误:
ERROR:[string "return require("./LuaGlobal.lua")"]:1: module './LuaGlobal.lua' not found: no field package.preload['./LuaGlobal.lua'] no file 'C:\Users\Eingeschränkt\.config\mudlet\profiles\new profile name\\/LuaGlobal\lua.lua' no file 'C:\Users\Eingeschränkt\.config\mudlet\profiles\new profile name\\/LuaGlobal\lua\init.lua' no file '.\\/LuaGlobal\lua.lua' no file 'C:\Users\Eingeschr�nkt\AppData\Local\Mudlet\app-3.8.1\lua\\/LuaGlobal\lua.lua' no file 'C:\Users\Eingeschr�nkt\AppData\Local\Mudlet\app-3.8.1\lua\\/LuaGlobal\lua\init.lua' no file 'C:\Users\Eingeschr�nkt\AppData\Local\Mudlet\app-3.8.1\\/LuaGlobal\lua.lua' no file 'C:\Users\Eingeschr�nkt\AppData\Local\Mudlet\app-3.8.1\\/LuaGlobal\lua\init.lua' no file 'C:\Users\Eingeschränkt\.config\mudlet\profiles\new profile name\\/LuaGlobal\lua' no file '.\\/LuaGlobal\lua.dll' no file 'C:\Users\Eingeschr�nkt\AppData\Local\Mudlet\app-3.8.1\\/LuaGlobal\lua.dll' no file 'C:\Users\Eingeschr�nkt\AppData\Local\Mudlet\app-3.8.1\loadall.dll' no file 'C:\Users\Eingeschränkt\.config\mudlet\profiles\new profile name\' no file '.\.dll' no file 'C:\Users\Eingeschr�nkt\AppData\Local\Mudlet\app-3.8.1\.dll' no file 'C:\Users\Eingeschr�nkt\AppData\Local\Mudlet\app-3.8.1\loadall.dll'

只是要确保lua require("/LuaGlobal.lua")
错误日志显示:
ERROR:[string "return require("/LuaGlobal.lua")"]:1: module '/LuaGlobal.lua' not found: no field package.preload['/LuaGlobal.lua'] no file 'C:\Users\Eingeschränkt\.config\mudlet\profiles\new profile name\/LuaGlobal\lua.lua' no file 'C:\Users\Eingeschränkt\.config\mudlet\profiles\new profile name\/LuaGlobal\lua\init.lua' no file '.\/LuaGlobal\lua.lua' no file 'C:\Users\Eingeschr�nkt\AppData\Local\Mudlet\app-3.8.1\lua\/LuaGlobal\lua.lua' no file 'C:\Users\Eingeschr�nkt\AppData\Local\Mudlet\app-3.8.1\lua\/LuaGlobal\lua\init.lua' no file 'C:\Users\Eingeschr�nkt\AppData\Local\Mudlet\app-3.8.1\/LuaGlobal\lua.lua' no file 'C:\Users\Eingeschr�nkt\AppData\Local\Mudlet\app-3.8.1\/LuaGlobal\lua\init.lua' no file 'C:\Users\Eingeschränkt\.config\mudlet\profiles\new profile name\/LuaGlobal\lua' no file '.\/LuaGlobal\lua.dll' no file 'C:\Users\Eingeschr�nkt\AppData\Local\Mudlet\app-3.8.1\/LuaGlobal\lua.dll' no file 'C:\Users\Eingeschr�nkt\AppData\Local\Mudlet\app-3.8.1\loadall.dll' no file 'C:\Users\Eingeschränkt\.config\mudlet\profiles\new profile name\/LuaGlobal' no file '.\/LuaGlobal.dll' no file 'C:\Users\Eingeschr�nkt\AppData\Local\Mudlet\app-3.8.1\/LuaGlobal.dll' no file 'C:\Users\Eingeschr�nkt\AppData\Local\Mudlet\app-3.8.1\loadall.dll'

奇怪的是print无法正常工作-我虽然是内置的lua-但:

lua echo(package.config)

应该也可以。

查看第一种工作示例的输出,错误输出正在尝试加载LuaGlobal.lua文件-让我们看看正在尝试的文件名和路径:

  1. C:\Users\Eingeschränkt\.config\mudlet\profiles\new profile name\\/LuaGlobal\lua.lua
  2. C:\Users\Eingeschränkt\.config\mudlet\profiles\new profile name\\/LuaGlobal\lua\init.lua
  3. .\\/LuaGlobal\lua.lua
  4. C:\Users\Eingeschr�nkt\AppData\Local\Mudlet\app-3.8.1\lua\\/LuaGlobal\lua.lua
  5. C:\Users\Eingeschr�nkt\AppData\Local\Mudlet\app-3.8.1\lua\\/LuaGlobal\lua\init.lua
  6. C:\Users\Eingeschr�nkt\AppData\Local\Mudlet\app-3.8.1\\/LuaGlobal\lua.lua
  7. C:\Users\Eingeschr�nkt\AppData\Local\Mudlet\app-3.8.1\\/LuaGlobal\lua\init.lua
  8. C:\Users\Eingeschränkt\.config\mudlet\profiles\new profile name\\/LuaGlobal\lua
  9. .\\/LuaGlobal\lua.dll
  10. C:\Users\Eingeschr�nkt\AppData\Local\Mudlet\app-3.8.1\\/LuaGlobal\lua.dll
  11. C:\Users\Eingeschr�nkt\AppData\Local\Mudlet\app-3.8.1\loadall.dll
  12. C:\Users\Eingeschränkt\.config\mudlet\profiles\new profile name\
  13. .\.dll
  14. C:\Users\Eingeschr�nkt\AppData\Local\Mudlet\app-3.8.1\.dll
  15. C:\Users\Eingeschr�nkt\AppData\Local\Mudlet\app-3.8.1\loadall.dll

这些天我不确定文件应该放在哪里,所以我下载并安装了3.8.1二进制文件,发现使用的路径是:

C:\ Users \ Stephen \ AppDataLocal \ Mudlet \ app-3.8.1 \ mudlet-lualua

同样在该Windows Installer版本中,对于package.config,我具有以下内容:

lua print(package.config)
\
;
?
!
-

因此,它的路径必须使用\才能使程序包处理程序正常运行IMO。 仍然不清楚为什么不同的人得到不同的东西。

编辑:用`而不是'引用路径列表

为什么某些路径是mojibake,而其他路径正确显示用户名,则必须是因为它们来自不同的来源,而其中一些还不能正常使用I18n-如果我们可以通过Mudlet 4.0跟踪并修复它们,这将很有帮助-但是他们可能不是我们可以控制的。 请注意,它不能是显示代码或字体,因为各个错误消息都经过与创建它们相同的过程。

为了确保我使用的是预期的实例(作为开发人员,我在该PC上拥有多个副本),我重命名了文件并得到了相同的结果:
luagloballua_fail

另外,我还创建了一个具有非ASCII(甚至可能不是Latin1 / ISO 885901)字符的新用户,并且可以确认该用户是否以相同的方式搞乱了-Mudlet无法在以下位置看到文件:

C:\Users\şțȅƥĥēƞ\AppData\Local\Mudlet\app-3.8.1\mudlet-lua\lua\LuaGlobal.lua

但这可以

C:\Users\stephen\AppData\Local\Mudlet\app-3.8.1\mudlet-lua\lua\LuaGlobal.lua

:哭泣:

这个Q&A在栈交易所听起来并不看好。

但是,MIT许可的luawinfile Windows(仅在mingw必须与Windows文件处理API一起使用的UTF-16转换)看起来更好一些-它提供了替代项用于可以采用UTF-8文件名和路径名的LFS模块。

好发现。 只是把它扔出去,我们在Mudlet中已经有https://github.com/starwing/luautf8了,其中有什么可以帮助我们的吗?

SlySven,您的15个目录名称列表似乎不正确。 例如,13应该读.\.dll而不是..dll

嗯,这是标记系统的干扰-在某些情况下,这里的反斜杠会转义所需的以下字符,例如,如果您想在普通文本中显示小于符号,例如“ \ <”,则不会看到那里是反斜杠...,而我使用的是单引号而不是代码引号-已编辑以修复引号。

luautf8都是关于UTF-8字符串处理的-我不认为这会有所帮助,因为luainfile专门用于与Windows文件处理接口(仅适用于UTF-16字符串) C或更可能的C ++库-似乎只需要在Windows上换行或替换lfs (尽管我想打赌不是Cygwin)...

嗯,但我们不使用lfs来加载LuaGlobal.lua ,那么luainfile将如何解决该问题?

它不仅是lfs的替代品。 它还可以替换dofileloadfile 。 我们可能会需要更换,我们呼吁luaL_dofile用LUA调用dofile

编辑添加: luainfile lua 5.3的

好像我们可以编写自己的luaL_dofile函数,然后将其与Windows的特殊编码一起使用?

我们如何才能推动这一进程?

我在luawinfile存储库上提出了一个问题,询问5.1兼容性,但是我看了一下,它确实使用了lua 5.1未提供的5.3语言功能-有一个单独的官方5.3兼容性模块试图提供5.2和5.1缺少的一些功能,但并非没有其他复杂性,因此解决方案也不算少。

似乎与#229相关

我们如何才能推动这一进程?

我们将需要将MIT许可的https://github.com/cloudwu/luawinfile (大约884行{808 soc}代码的单个C文件)从5.3反向移植到5.3,以适应早期版本中不存在的某些功能Mudlet使用的lua版本。 我认为,这将需要比我目前感觉更好的lua-C编码知识。 但是,这似乎可以独立完成和测试,而不必担心其余的代码库-尽管它只能在Windows开发平台上进行真正的测试。

另一个问题是,人们无法使用非英语用户名将其个人资料保存在Windows上-不会写入任何历史记录。 不要以为我们有票。

@SlySven
您最近在将国际信件带给Mudlet的修复过程中是否学到了一些东西,以解决这个问题?

并非如此,我确实认为将luawinfile移植到Lua 5.1可以提供我们最大的希望,但我只是对C/C++ + lua不够了解(还可以?) 我们需要仔细研究Lua官方io库的代码,看看luawinfile如何用Windows特定的替代品替代某些功能(全部,我不知道?)。

正如人们可能已经注意到的那样,我的主要Windows开发平台不是最符合标准(带有64位处理器但运行32位版本的Windows 7笔记本电脑)-我的主PC也具有64位Windows 7,但是启动机器无法运行OS几个月,所以我有几个小时在盯着“更新Windows ...不要关掉”屏幕期待,我没有那么积极,ATM!

尽管现在Qt在线安装程序似乎终于切换到仅提供64位Mingw64 Windows安装-与以前的32位仅Mingw安装程序相比,如果我有几个小时要扔掉,我可能会考虑这样做。 ..

看起来不错...

Selection_127

这要感谢于年初创建的https://gist.github.com/Egor-Skriptunoff/2458547aa3b9210a8b5f686ac08ecbf0

将在Mudlet 3.22中提供

此页面是否有帮助?
0 / 5 - 0 等级