Bug: jieba_dict_dir parameter value is lowercased, breaking case-sensitive filesystem paths
LadybugDB version
v0.19.0 (also present in the extensions repo HEAD)
What happened?
When using the FTS extension with tokenizer:='jieba', the jieba_dict_dir parameter is silently lowercased before being used to open the dictionary files. On case-sensitive filesystems (Linux), this makes the parameter unusable for any path containing ASCII uppercase letters, and crashes the process with a hard FATAL abort (not a recoverable exception).
Repro (Node.js binding, but the root cause is in the shared extension code):
INSTALL fts;
LOAD fts;
CREATE NODE TABLE Chunk (id INT64 PRIMARY KEY, content STRING);
CALL CREATE_FTS_INDEX('Chunk', 'c1', ['content'],
tokenizer:='jieba',
jieba_dict_dir:='/some/path/With-Uppercase'); -- valid, exists, contains jieba dicts
Process aborts with:
.../third_party/cppjieba/include/cppjieba/DictTrie.hpp:206 FATAL exp: [ifs.is_open()] false.
open /some/path/with-uppercase/jieba.dict.utf8 failed.
Note the path With-Uppercase was opened as with-uppercase.
I also verified that paths containing Chinese characters, digits, -, and _ work fine — only ASCII uppercase letters are affected (they get mapped to lowercase).
Root cause
In fts/src/function/fts_config.cpp (CreateFTSConfig constructor):
} else if (lowerCaseName == "jieba_dict_dir") {
value.validateType(common::LogicalTypeID::STRING);
tokenizerInfo.jiebaDictDir =
common::StringUtils::getLower(value.getValue<std::string>());
}
The value of jieba_dict_dir is passed through common::StringUtils::getLower(). That helper is a Unicode-aware lowercase conversion (changeCase → BaseLowerUpperFunction with utf8proc), so it maps every ASCII A-Z to a-z.
Other parameters in this same block legitimately lowercase their values because they are case-insensitive enums/patterns (stemmer, ignore_pattern, tokenizer). But jieba_dict_dir is a filesystem path, and on case-sensitive filesystems (Linux, and anywhere a mount is case-sensitive) lowercasing a path changes which directory/file is opened. The default value in fts_config.h happens to be lowercase so the shipped default works, but any user-supplied path with uppercase letters breaks.
Expected behavior
jieba_dict_dir should be used verbatim (no case transformation), like any other path parameter.
Suggested fix
Remove the getLower call for the jieba_dict_dir case:
} else if (lowerCaseName == "jieba_dict_dir") {
value.validateType(common::LogicalTypeID::STRING);
tokenizerInfo.jiebaDictDir = value.getValue<std::string>();
}
Additional observations
- The failure is a
FATAL process abort in cppjieba (DictTrie.hpp:206, exp: [ifs.is_open()] false), not a catchable exception. Even with the lowercasing fixed, a genuinely missing dictionary directory will still hard-crash the host process. Consider validating the directory up front and raising a proper BinderException/RuntimeException instead.
- Same family of issues as #588 (create-time vs runtime tokenization contract), but distinct: this one is a pure path mangling bug.
- Verification performed against the prebuilt
@ladybugdb/core-linux-x64 v0.19.0 Node.js binding and the extensions repo source (fts_config.cpp).
Bug:
jieba_dict_dirparameter value is lowercased, breaking case-sensitive filesystem pathsLadybugDB version
v0.19.0 (also present in the extensions repo HEAD)
What happened?
When using the FTS extension with
tokenizer:='jieba', thejieba_dict_dirparameter is silently lowercased before being used to open the dictionary files. On case-sensitive filesystems (Linux), this makes the parameter unusable for any path containing ASCII uppercase letters, and crashes the process with a hardFATALabort (not a recoverable exception).Repro (Node.js binding, but the root cause is in the shared extension code):
Process aborts with:
Note the path
With-Uppercasewas opened aswith-uppercase.I also verified that paths containing Chinese characters, digits,
-, and_work fine — only ASCII uppercase letters are affected (they get mapped to lowercase).Root cause
In
fts/src/function/fts_config.cpp(CreateFTSConfig constructor):The value of
jieba_dict_diris passed throughcommon::StringUtils::getLower(). That helper is a Unicode-aware lowercase conversion (changeCase→BaseLowerUpperFunctionwith utf8proc), so it maps every ASCIIA-Ztoa-z.Other parameters in this same block legitimately lowercase their values because they are case-insensitive enums/patterns (
stemmer,ignore_pattern,tokenizer). Butjieba_dict_diris a filesystem path, and on case-sensitive filesystems (Linux, and anywhere a mount is case-sensitive) lowercasing a path changes which directory/file is opened. The default value infts_config.hhappens to be lowercase so the shipped default works, but any user-supplied path with uppercase letters breaks.Expected behavior
jieba_dict_dirshould be used verbatim (no case transformation), like any other path parameter.Suggested fix
Remove the
getLowercall for thejieba_dict_dircase:Additional observations
FATALprocess abort incppjieba(DictTrie.hpp:206,exp: [ifs.is_open()] false), not a catchable exception. Even with the lowercasing fixed, a genuinely missing dictionary directory will still hard-crash the host process. Consider validating the directory up front and raising a properBinderException/RuntimeExceptioninstead.@ladybugdb/core-linux-x64v0.19.0 Node.js binding and the extensions repo source (fts_config.cpp).