diff --git a/TIASshot/Cameras/CameraBase.cs b/TIASshot/Cameras/CameraBase.cs index d90bce6..1b1d3d2 100644 --- a/TIASshot/Cameras/CameraBase.cs +++ b/TIASshot/Cameras/CameraBase.cs @@ -141,7 +141,7 @@ var filename = Config.GetString("File/RgbImage"); filename = filename.Replace("{NO}", $"{idx + 1:0000}"); - Cv2.ImWrite(Path.Combine(_saveFolder, filename), img); + Cv2.ImWrite(IoUtil.CombineSaveFilePath(_saveFolder, filename), img); foreach (var channel in _colorCorrector.Channels) { // ConvertImage は src を in-place で CV_64FC3 に変換するため、 @@ -152,7 +152,7 @@ using (var converted = _colorCorrector.ConvertImage(imgClone, channel)) { filename = GetFilenameWithChannel("File/SrgbImage", channel); filename = filename.Replace("{NO}", $"{idx + 1:0000}"); - Cv2.ImWrite(Path.Combine(_saveFolder, filename), converted); + Cv2.ImWrite(IoUtil.CombineSaveFilePath(_saveFolder, filename), converted); } } } @@ -223,7 +223,7 @@ PreviewProfiler.MarkEvent("SHOT_START"); #endif var filename = Config.GetString("File/Info"); - using (var csv = new StreamWriter(Path.Combine(_saveFolder, filename))) { + using (var csv = new StreamWriter(IoUtil.CombineSaveFilePath(_saveFolder, filename))) { WriteInfo(csv); csv.WriteLine("Shot,Time(ms)"); @@ -288,8 +288,8 @@ // データ保存 SetSaveFolder("校正"); SetInfo("校正データ", _saveFolder); - Cv2.ImWrite(Path.Combine(_saveFolder, Config.GetString("File/TccImage")), img); - Cv2.ImWrite(Path.Combine(_saveFolder, Config.GetString("File/TccRoisImage")), imgRois); + Cv2.ImWrite(IoUtil.CombineSaveFilePath(_saveFolder, Config.GetString("File/TccImage")), img); + Cv2.ImWrite(IoUtil.CombineSaveFilePath(_saveFolder, Config.GetString("File/TccRoisImage")), imgRois); // 変換行列の計算・保存は ColorCorrector に委譲する(tccRgb の所有権は渡さない) _colorCorrector.CalcTcc(tccRgb, _saveFolder, IoUtil.SaveMatToCsv); diff --git a/TIASshot/ColorCorrection/ColorCorrector.cs b/TIASshot/ColorCorrection/ColorCorrector.cs index eadebea..5ee6184 100644 --- a/TIASshot/ColorCorrection/ColorCorrector.cs +++ b/TIASshot/ColorCorrection/ColorCorrector.cs @@ -89,7 +89,7 @@ /// Mat を CSV へ保存する処理(呼び出し側が提供) public void CalcTcc(Mat tccRgb, string saveFolder, Action saveMatToCsv) { - saveMatToCsv(Path.Combine(saveFolder, Config.GetString("File/TccRgbValues")), tccRgb); + saveMatToCsv(IoUtil.CombineSaveFilePath(saveFolder, Config.GetString("File/TccRgbValues")), tccRgb); // 再校正時,古い変換行列のネイティブ資源を解放してから作り直す(Mat リーク防止) foreach (var mat in _convRGB2SRGB.Values) { @@ -99,11 +99,11 @@ foreach (var channel in ChannelList) { var convRGB2SRGB = CalcConvertMatrix(tccRgb, TCC_SRGB, channel); - saveMatToCsv(Path.Combine(saveFolder, GetFilenameWithChannel("File/ConvRgb2Srgb", channel)), convRGB2SRGB); + saveMatToCsv(IoUtil.CombineSaveFilePath(saveFolder, GetFilenameWithChannel("File/ConvRgb2Srgb", channel)), convRGB2SRGB); // 以降の中間 Mat は辞書に保持しないため,使用後に確実に解放する using (var convRGB2XYZ = CalcConvertMatrix(tccRgb, TCC_XYZ, channel)) { - saveMatToCsv(Path.Combine(saveFolder, GetFilenameWithChannel("File/ConvRgb2Xyz", channel)), convRGB2XYZ); + saveMatToCsv(IoUtil.CombineSaveFilePath(saveFolder, GetFilenameWithChannel("File/ConvRgb2Xyz", channel)), convRGB2XYZ); if (channel == 17) { using (var convOld = new Mat(convRGB2XYZ.Size(), MatType.CV_64FC1)) { for (var row = 0; row < convRGB2XYZ.Rows; row++) { @@ -112,16 +112,16 @@ convOld.At(row, col) = convRGB2XYZ.At(rowFrom, col); } } - saveMatToCsv(Path.Combine(saveFolder, GetFilenameWithChannel("File/ConvRgb2XyzOld", channel)), convOld); + saveMatToCsv(IoUtil.CombineSaveFilePath(saveFolder, GetFilenameWithChannel("File/ConvRgb2XyzOld", channel)), convOld); } } } using (var tccSrgb = ConvertColor(tccRgb, convRGB2SRGB)) { - saveMatToCsv(Path.Combine(saveFolder, GetFilenameWithChannel("File/TccSrgbValues", channel)), tccSrgb); + saveMatToCsv(IoUtil.CombineSaveFilePath(saveFolder, GetFilenameWithChannel("File/TccSrgbValues", channel)), tccSrgb); using (var convSrgb2Xyz = CalcConvertMatrix(tccSrgb, TCC_XYZ, channel)) { - saveMatToCsv(Path.Combine(saveFolder, GetFilenameWithChannel("File/ConvSrgb2Xyz", channel)), convSrgb2Xyz); + saveMatToCsv(IoUtil.CombineSaveFilePath(saveFolder, GetFilenameWithChannel("File/ConvSrgb2Xyz", channel)), convSrgb2Xyz); } // 変換精度検証 diff --git a/TIASshot/Utils/IoUtil.cs b/TIASshot/Utils/IoUtil.cs index bf45a8b..925d032 100644 --- a/TIASshot/Utils/IoUtil.cs +++ b/TIASshot/Utils/IoUtil.cs @@ -99,12 +99,16 @@ /// /// 設定ファイル由来のファイル名を保存フォルダと結合し,保存先ファイルパスを返す. + /// ファイル名に含まれる不正なファイル名文字(パス区切り \ /・ドライブ区切り : 等)を + /// _ に置換してから結合するため,設定の破損・誤設定(絶対パス指定・..\ トラバーサル)でも + /// 保存先が保存フォルダの外へ出ない.同梱 config.xml の既存値では従来の + /// Path.Combine と完全に同一の結果を返す(挙動不変). /// /// 保存フォルダのパス /// 設定ファイル由来のファイル名({CN}/{NO} 置換後) - /// 保存先ファイルパス + /// 保存先ファイルパス(必ず saveFolder 配下) public static string CombineSaveFilePath(string saveFolder, string filename) { - return Path.Combine(saveFolder, filename); + return Path.Combine(saveFolder, SanitizeFolderNameElement(filename)); } ///