Skip to content

Commit 87eff88

Browse files
Copilotnixel2007
andauthored
Strip null characters from file paths to fix Windows WebDAV compatibility (#1649)
* Initial plan * Initial plan for fixing null character handling in file paths Co-authored-by: nixel2007 <1132840+nixel2007@users.noreply.github.com> * Add null character stripping in FileContext and FindFiles Co-authored-by: nixel2007 <1132840+nixel2007@users.noreply.github.com> * Refactor: Extract StripNullCharacters to PathHelper utility class Co-authored-by: nixel2007 <1132840+nixel2007@users.noreply.github.com> * Final update: All checks passed Co-authored-by: nixel2007 <1132840+nixel2007@users.noreply.github.com> * Remove accidentally committed opm.ospx file Co-authored-by: nixel2007 <1132840+nixel2007@users.noreply.github.com> * Remove nuget.exe and C# test file (BSL tests are sufficient) Co-authored-by: nixel2007 <1132840+nixel2007@users.noreply.github.com> * Strip null characters from file paths to fix Windows WebDAV compatibility Co-authored-by: nixel2007 <1132840+nixel2007@users.noreply.github.com> * Revert .gitignore change - remove *.ospx pattern Co-authored-by: nixel2007 <1132840+nixel2007@users.noreply.github.com> * Remove accidentally re-added opm.ospx file Co-authored-by: nixel2007 <1132840+nixel2007@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: nixel2007 <1132840+nixel2007@users.noreply.github.com>
1 parent 877a682 commit 87eff88

File tree

4 files changed

+149
-0
lines changed

4 files changed

+149
-0
lines changed

src/OneScript.StandardLibrary/FileContext.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ public class FileContext : AutoContext<FileContext>
2424

2525
public FileContext(string name)
2626
{
27+
// Strip null characters that can be added by Windows WebDAV client
28+
// to maintain compatibility with 1.x behavior
29+
name = PathHelper.StripNullCharacters(name);
30+
2731
if (String.IsNullOrWhiteSpace(name))
2832
{
2933
_name = "";

src/OneScript.StandardLibrary/FileOperations.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,11 @@ public string GetTempFilename(string ext = null)
138138
[ContextMethod("НайтиФайлы", "FindFiles")]
139139
public ArrayImpl FindFiles(string dir, string mask = null, bool recursive = false)
140140
{
141+
// Strip null characters that can be added by Windows WebDAV client
142+
// to maintain compatibility with 1.x behavior
143+
dir = PathHelper.StripNullCharacters(dir);
144+
mask = PathHelper.StripNullCharacters(mask);
145+
141146
if (mask == null)
142147
{
143148
// fix 225, 227, 228
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*----------------------------------------------------------
2+
This Source Code Form is subject to the terms of the
3+
Mozilla Public License, v.2.0. If a copy of the MPL
4+
was not distributed with this file, You can obtain one
5+
at http://mozilla.org/MPL/2.0/.
6+
----------------------------------------------------------*/
7+
8+
namespace OneScript.StandardLibrary
9+
{
10+
/// <summary>
11+
/// Utility methods for working with file paths
12+
/// </summary>
13+
internal static class PathHelper
14+
{
15+
/// <summary>
16+
/// Strips null characters from a path string.
17+
/// This is needed because Windows WebDAV client can add null characters to paths,
18+
/// which causes ArgumentException in System.IO methods.
19+
/// </summary>
20+
/// <param name="path">Path that may contain null characters</param>
21+
/// <returns>Path with null characters removed, or null if input was null</returns>
22+
public static string StripNullCharacters(string path)
23+
{
24+
if (path == null)
25+
return null;
26+
27+
return path.Replace("\0", "");
28+
}
29+
}
30+
}

tests/null-character-handling.os

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
Перем юТест;
2+
3+
Функция Версия() Экспорт
4+
Возврат "0.1";
5+
КонецФункции
6+
7+
Функция ПолучитьСписокТестов(ЮнитТестирование) Экспорт
8+
9+
юТест = ЮнитТестирование;
10+
11+
ВсеТесты = Новый Массив;
12+
13+
ВсеТесты.Добавить("ТестДолжен_СоздатьФайлСНулевымСимволом");
14+
ВсеТесты.Добавить("ТестДолжен_ВыполнитьНайтиФайлыСНулевымСимволом");
15+
ВсеТесты.Добавить("ТестДолжен_ПолучитьСвойстваФайлаСНулевымСимволом");
16+
17+
Возврат ВсеТесты;
18+
КонецФункции
19+
20+
Процедура ТестДолжен_СоздатьФайлСНулевымСимволом() Экспорт
21+
22+
ВремФайл = ПолучитьИмяВременногоФайла("txt");
23+
ЗаписьТекста = Новый ЗаписьТекста(ВремФайл);
24+
ЗаписьТекста.ЗаписатьСтроку("тестовое содержимое");
25+
ЗаписьТекста.Закрыть();
26+
27+
Попытка
28+
// Добавляем нулевой символ в путь, как это делает Windows WebDAV клиент
29+
ПутьСНулевымСимволом = ВремФайл + Символ(0);
30+
Файл = Новый Файл(ПутьСНулевымСимволом);
31+
32+
// Проверяем, что файл доступен и не выбрасывает исключение
33+
юТест.ПроверитьИстину(Файл.Существует(), "Файл должен существовать");
34+
юТест.ПроверитьРавенство("txt", Прав(Файл.Расширение, 3), "Расширение должно быть txt");
35+
36+
Исключение
37+
УдалитьФайлы(ВремФайл);
38+
ВызватьИсключение;
39+
КонецПопытки;
40+
41+
УдалитьФайлы(ВремФайл);
42+
43+
КонецПроцедуры
44+
45+
Процедура ТестДолжен_ВыполнитьНайтиФайлыСНулевымСимволом() Экспорт
46+
47+
ВремКаталог = КаталогВременныхФайлов();
48+
ИмяТестовогоФайла = "test_null_char_" + Формат(ТекущаяДата(), "ДФ=yyyyMMddHHmmss") + ".txt";
49+
ВремФайл = ОбъединитьПути(ВремКаталог, ИмяТестовогоФайла);
50+
51+
ЗаписьТекста = Новый ЗаписьТекста(ВремФайл);
52+
ЗаписьТекста.ЗаписатьСтроку("тестовое содержимое");
53+
ЗаписьТекста.Закрыть();
54+
55+
Попытка
56+
// Добавляем нулевой символ в путь к каталогу
57+
ПутьКаталогаСНулевымСимволом = ВремКаталог + Символ(0);
58+
59+
// Проверяем, что НайтиФайлы не выбрасывает исключение
60+
НайденныеФайлы = НайтиФайлы(ПутьКаталогаСНулевымСимволом, ИмяТестовогоФайла);
61+
62+
// Проверяем, что файл был найден
63+
юТест.ПроверитьРавенство(1, НайденныеФайлы.Количество(), "Должен быть найден один файл");
64+
юТест.ПроверитьРавенство(ИмяТестовогоФайла, НайденныеФайлы[0].Имя, "Имя файла должно совпадать");
65+
66+
Исключение
67+
УдалитьФайлы(ВремФайл);
68+
ВызватьИсключение;
69+
КонецПопытки;
70+
71+
УдалитьФайлы(ВремФайл);
72+
73+
КонецПроцедуры
74+
75+
Процедура ТестДолжен_ПолучитьСвойстваФайлаСНулевымСимволом() Экспорт
76+
77+
ВремФайл = ПолучитьИмяВременногоФайла("txt");
78+
ЗаписьТекста = Новый ЗаписьТекста(ВремФайл);
79+
ЗаписьТекста.ЗаписатьСтроку("тестовое содержимое");
80+
ЗаписьТекста.Закрыть();
81+
82+
Попытка
83+
// Добавляем нулевой символ в конец пути
84+
ПутьСНулевымСимволом = ВремФайл + Символ(0);
85+
Файл = Новый Файл(ПутьСНулевымСимволом);
86+
87+
// Проверяем, что все свойства доступны без исключений
88+
ПолноеИмя = Файл.ПолноеИмя;
89+
юТест.ПроверитьНеравенство("", ПолноеИмя, "ПолноеИмя не должно быть пустым");
90+
91+
Имя = Файл.Имя;
92+
юТест.ПроверитьНеравенство("", Имя, "Имя не должно быть пустым");
93+
94+
Путь = Файл.Путь;
95+
юТест.ПроверитьНеравенство("", Путь, "Путь не должен быть пустым");
96+
97+
Расширение = Файл.Расширение;
98+
юТест.ПроверитьРавенство(".txt", Расширение, "Расширение должно быть .txt");
99+
100+
Размер = Файл.Размер();
101+
юТест.ПроверитьБольше(Размер, 0, "Размер должен быть больше 0");
102+
103+
Исключение
104+
УдалитьФайлы(ВремФайл);
105+
ВызватьИсключение;
106+
КонецПопытки;
107+
108+
УдалитьФайлы(ВремФайл);
109+
110+
КонецПроцедуры

0 commit comments

Comments
 (0)