Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:26
erlang
0188-stdlib-Fix-io_lib-get_until-to-return-bina...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0188-stdlib-Fix-io_lib-get_until-to-return-binaries-at-eo.patch of Package erlang
From 038a7bf1320c095540c28cdd81c1fc56ab69127f Mon Sep 17 00:00:00 2001 From: Lukas Larsson <lukas@erlang.org> Date: Tue, 2 Jan 2024 16:43:48 +0100 Subject: [PATCH 1/2] stdlib: Fix io_lib:get_until to return binaries at eof Before this fix if a get_until function would return data when eof is seen, the result would not be correctly converted to a binary when returned. closes #4992 --- lib/stdlib/src/io_lib.erl | 16 ++++--- lib/stdlib/test/io_proto_SUITE.erl | 77 +++++++++++++++++++++++++++++- 2 files changed, 85 insertions(+), 8 deletions(-) diff --git a/lib/stdlib/src/io_lib.erl b/lib/stdlib/src/io_lib.erl index 87010361c0..4f42950069 100644 --- a/lib/stdlib/src/io_lib.erl +++ b/lib/stdlib/src/io_lib.erl @@ -960,8 +960,12 @@ get_until(Any,Data,Arg) -> %% Now we are aware of encoding... get_until(start, Data, Encoding, XtraArg) -> - get_until([], Data, Encoding, XtraArg); -get_until(Cont, Data, Encoding, {Mod, Func, XtraArgs}) -> + %% We use the type of the initial data as an indicator of what + %% the final result should be cast to. We cannot use the final + %% data as that might be eof and then we have no idea what to + %% convert to. + get_until({is_binary(Data), []}, Data, Encoding, XtraArg); +get_until({IsDataBinary, Cont}, Data, Encoding, {Mod, Func, XtraArgs}) -> Chars = if is_binary(Data), Encoding =:= unicode -> unicode:characters_to_list(Data,utf8); is_binary(Data) -> @@ -971,14 +975,14 @@ get_until(Cont, Data, Encoding, {Mod, Func, XtraArgs}) -> end, case apply(Mod, Func, [Cont,Chars|XtraArgs]) of {done,Result,Buf} -> - {stop,if is_binary(Data), + {stop,if IsDataBinary, is_list(Result), Encoding =:= unicode -> unicode:characters_to_binary(Result,unicode,unicode); - is_binary(Data), + IsDataBinary, is_list(Result) -> erlang:iolist_to_binary(Result); -%% is_list(Data), +%% IsDataBinary, %% is_list(Result), %% Encoding =:= latin1 -> %% % Should check for only latin1, but skip that for @@ -990,7 +994,7 @@ get_until(Cont, Data, Encoding, {Mod, Func, XtraArgs}) -> end, Buf}; {more,NewCont} -> - NewCont + {IsDataBinary, NewCont} end. binrev(L) -> diff --git a/lib/stdlib/test/io_proto_SUITE.erl b/lib/stdlib/test/io_proto_SUITE.erl index 1519ff89c6..9c27244801 100644 --- a/lib/stdlib/test/io_proto_SUITE.erl +++ b/lib/stdlib/test/io_proto_SUITE.erl @@ -32,6 +32,7 @@ file_read_line_stdin_unicode_translation_error_binary_mode/1, file_read_line_stdin_unicode_translation_error_list_mode/1, io_get_chars_stdin_binary_mode/1, io_get_chars_stdin_list_mode/1, + io_get_until_stdin_binary_mode/1, io_get_until_stdin_list_mode/1, io_get_chars_file_read_stdin_binary_mode/1, file_read_stdin_latin1_binary_mode/1, file_read_stdin_latin1_list_mode/1, @@ -48,6 +49,8 @@ -export([write_raw_to_stdout/0, read_raw_from_stdin/1]). +-export([get_until_eof/2]). + %%-define(debug, true). -ifdef(debug). @@ -73,6 +76,8 @@ all() -> file_read_line_stdin_unicode_translation_error_list_mode, io_get_chars_stdin_binary_mode, io_get_chars_stdin_list_mode, + io_get_until_stdin_binary_mode, + io_get_until_stdin_list_mode, io_get_chars_file_read_stdin_binary_mode, file_read_stdin_latin1_binary_mode, file_read_stdin_latin1_list_mode, @@ -367,7 +372,7 @@ file_read_line_stdin_unicode_translation_error_list_mode(_Config) -> ok. -%% Test that reading from stdin using file:read works when io is in binary mode +%% Test that reading from stdin using io:get_chars works when io is in binary mode io_get_chars_stdin_binary_mode(_Config) -> {ok, P, ErlPort} = start_stdin_node( fun() -> @@ -385,7 +390,75 @@ io_get_chars_stdin_binary_mode(_Config) -> ok. -%% Test that reading from stdin using file:read works when io is in binary mode +%% Test that reading from stdin using custom io_request works when io is in binary mode +io_get_until_stdin_binary_mode(_Config) -> + + GetUntilEof = + fun() -> + IoServer = group_leader(), + IoServer ! + {io_request, + self(), + IoServer, + {get_until, unicode, '', ?MODULE, get_until_eof, []}}, + receive + {io_reply, IoServer, Data} -> + {ok, Data} + end + end, + + {ok, P, ErlPort} = start_stdin_node(GetUntilEof, [binary]), + + erlang:port_command(ErlPort, "x\n"), + {error, timeout} = gen_tcp:recv(P, 0, 250), + ErlPort ! {self(), close}, + {ok, "got: <<\"x\\n\">>\n"} = gen_tcp:recv(P, 0), + + {ok, P2, ErlPort2} = start_stdin_node(GetUntilEof, [binary]), + + {error, timeout} = gen_tcp:recv(P2, 0, 250), + ErlPort2 ! {self(), close}, + {ok, "got: eof\n"} = gen_tcp:recv(P2, 0), + + ok. + +%% Test that reading from stdin using custom io_request works when io is in list mode +io_get_until_stdin_list_mode(_Config) -> + + GetUntilEof = + fun() -> + IoServer = group_leader(), + IoServer ! + {io_request, + self(), + IoServer, + {get_until, unicode, '', ?MODULE, get_until_eof, []}}, + receive + {io_reply, IoServer, Data} -> + {ok, Data} + end + end, + + {ok, P, ErlPort} = start_stdin_node(GetUntilEof, [list]), + + erlang:port_command(ErlPort, "x\n"), + {error, timeout} = gen_tcp:recv(P, 0, 250), + ErlPort ! {self(), close}, + {ok, "got: \"x\\n\"\n"} = gen_tcp:recv(P, 0), + + {ok, P2, ErlPort2} = start_stdin_node(GetUntilEof, [list]), + + {error, timeout} = gen_tcp:recv(P2, 0, 250), + ErlPort2 ! {self(), close}, + {ok, "got: eof\n"} = gen_tcp:recv(P2, 0), + + ok. + +get_until_eof([],eof) -> {done,eof,[]}; +get_until_eof(ThisFar,eof) -> {done,ThisFar,eof}; +get_until_eof(ThisFar,CharList) -> {more,ThisFar++CharList}. + +%% Test that reading from stdin using io:get_chars works when io is in list mode io_get_chars_stdin_list_mode(_Config) -> {ok, P, ErlPort} = start_stdin_node( fun() -> case io:get_chars(standard_io, "", 1) of -- 2.35.3
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor