Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 35 additions & 2 deletions src/OneScript.StandardLibrary/Json/JSONReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ This Source Code Form is subject to the terms of the
at http://mozilla.org/MPL/2.0/.
----------------------------------------------------------*/

using System;
using System.IO;
using Newtonsoft.Json;
using OneScript.Commons;
using OneScript.Contexts;
using OneScript.Exceptions;
using OneScript.StandardLibrary.Binary;
using OneScript.StandardLibrary.Text;
using ScriptEngine.Machine;
using ScriptEngine.Machine.Contexts;
using System;
using System.IO;

namespace OneScript.StandardLibrary.Json
{
Expand Down Expand Up @@ -266,6 +267,38 @@ public void OpenFile(string JSONFileName, IValue encoding = null)
};
}

/// <summary>
/// Устанавливает поток для чтения JSON данным объектом.
/// Если перед вызовом данного метода уже производилось чтение JSON из другого файла, строки или потока,
/// то чтение прекращается и объект инициализируется для чтения из указанного потока.
/// </summary>
/// <param name="stream">
/// Поток для чтения текста JSON.</param>
/// <param name="encoding">
/// Позволяет задать кодировку входного потока.</param>
[ContextMethod("ОткрытьПоток", "OpenStream")]
public void OpenStream(IValue streamContext, IValue encoding = null)
{
if (IsOpen())
Close();

var stream = streamContext switch
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

а просто IStreamWrapper не пойдет? Они все его реализуют

{
GenericStream s => s.GetUnderlyingStream(),
FileStreamContext s => s.GetUnderlyingStream(),
MemoryStreamContext s => s.GetUnderlyingStream(),

_ => throw RuntimeException.InvalidNthArgumentType(1)
};

var enc = encoding != null ? TextEncodingEnum.GetEncoding(encoding) : System.Text.Encoding.UTF8;

_reader = new JsonReaderInternal(new StreamReader(stream, enc))
{
SupportMultipleContent = true
};
Comment on lines +253 to +258
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Align OpenStream open/init exception behavior with OpenFile.

OpenFile wraps initialization failures into RuntimeException, while OpenStream currently leaks raw .NET exceptions from encoding resolution/reader creation. Keeping this consistent improves script-facing behavior.

Proposed fix
-            var enc = encoding != null ? TextEncodingEnum.GetEncoding(encoding) : System.Text.Encoding.UTF8;
-
-            _reader = new JsonReaderInternal(new StreamReader(stream, enc, leaveOpen:true))
-            {
-                SupportMultipleContent = true
-            };
+            try
+            {
+                var enc = encoding != null ? TextEncodingEnum.GetEncoding(encoding) : System.Text.Encoding.UTF8;
+
+                _reader = new JsonReaderInternal(new StreamReader(stream, enc, leaveOpen: true))
+                {
+                    SupportMultipleContent = true
+                };
+            }
+            catch (Exception e)
+            {
+                throw new RuntimeException(e.Message, e);
+            }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
var enc = encoding != null ? TextEncodingEnum.GetEncoding(encoding) : System.Text.Encoding.UTF8;
_reader = new JsonReaderInternal(new StreamReader(stream, enc, leaveOpen:true))
{
SupportMultipleContent = true
};
try
{
var enc = encoding != null ? TextEncodingEnum.GetEncoding(encoding) : System.Text.Encoding.UTF8;
_reader = new JsonReaderInternal(new StreamReader(stream, enc, leaveOpen: true))
{
SupportMultipleContent = true
};
}
catch (Exception e)
{
throw new RuntimeException(e.Message, e);
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/OneScript.StandardLibrary/Json/JSONReader.cs` around lines 253 - 258,
OpenStream currently allows .NET exceptions from TextEncodingEnum.GetEncoding
and new JsonReaderInternal to leak; mirror OpenFile by wrapping the encoding
resolution and _reader initialization in a try/catch and throw a
RuntimeException instead. Specifically, surround the calls to
TextEncodingEnum.GetEncoding(encoding) and the JsonReaderInternal/StreamReader
creation that assigns _reader with a try block, catch Exception ex, and rethrow
a new RuntimeException (include a clear message and set ex as the inner
exception) so OpenStream behavior matches OpenFile.

}

/// <summary>
/// Если текущее значение – начало массива или объекта, то пропускает его содержимое и конец.
/// Для остальных типов значений работает аналогично методу Прочитать().
Expand Down
12 changes: 12 additions & 0 deletions tests/json/test-json_reader.os
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
СписокТестов.Добавить("Тест_Должен_ПроверитьПропускНезавершенногоМассива");
СписокТестов.Добавить("Тест_Должен_ПроверитьПропускМассиваСВложенными");
СписокТестов.Добавить("Тест_Должен_ПроверитьПропускОбъектаСВложениями");

СписокТестов.Добавить("Тест_Должен_ПроверитьОткрытиеПотока");
Возврат СписокТестов;

КонецФункции
Expand Down Expand Up @@ -219,3 +221,13 @@
юТест.ПроверитьРавенство(ТипЗначенияJSON.Число, Чтение.ТипТекущегоЗначения);
юТест.ПроверитьРавенство(5, Чтение.ТекущееЗначение);
КонецПроцедуры

Процедура Тест_Должен_ПроверитьОткрытиеПотока() Экспорт
БДД = ПолучитьБуферДвоичныхДанныхИзСтроки("{""ответ"":42}");
Поток = Новый ПотокВПамяти(БДД);
Чтение = Новый ЧтениеJSON;
Чтение.ОткрытьПоток(Поток);
Json = ПрочитатьJSON(Чтение);

юТест.ПроверитьРавенство(42, Json.Ответ);
КонецПроцедуры