Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ReadOnlySequence<byte>.PositionOf Error #102457

Open
beetlex-io opened this issue May 20, 2024 · 4 comments
Open

ReadOnlySequence<byte>.PositionOf Error #102457

beetlex-io opened this issue May 20, 2024 · 4 comments
Labels
area-System.Buffers untriaged New issue has not been triaged by the area owner

Comments

@beetlex-io
Copy link

beetlex-io commented May 20, 2024

ReadOnlySequence.PositionOf fun return index larger than array length?
Test code:

using System;
using System.Buffers;

using System.Net.Http.Json;
using System.Net.Sockets;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Text.Json.Serialization;



MemoryStream stream = new MemoryStream();
string name = "name:henryfan\r\n";
string email = "email:henryfan@msn.com\r\n";
string result;
stream.Write(name, Encoding.UTF8);
stream.Write(email, Encoding.UTF8);
ReadOnlySequence<byte> sequence = new ReadOnlySequence<byte>(stream.ToArray());
var point = sequence.IndexOf("\r\n");
result = point.Value.ReadString(Encoding.UTF8);
sequence = sequence.Slice(point.Value.Length);
point = sequence.IndexOf("\r\n");
result = point.Value.ReadString(Encoding.UTF8);

public struct TemporaryBuffer<T> : IDisposable
{

    public T[] Data { get; set; }

    public void Dispose()
    {
        ArrayPool<T>.Shared.Return(Data);
    }

    public static implicit operator TemporaryBuffer<T>(int length)
    {
        TemporaryBuffer<T> result = new TemporaryBuffer<T>();
        result.Data = ArrayPool<T>.Shared.Rent(length);
        return result;
    }
}
static class extend
{
    public static ReadOnlySequence<byte>? IndexOf(this ReadOnlySequence<byte> _buffer, string eof, Encoding coding = null)
    {
        coding = coding ?? Encoding.UTF8;
        var bytes = coding.GetBytes(eof);
        return IndexOf(_buffer, bytes);
    }
    public static string ReadString(this ReadOnlySequence<byte> _buffer, Encoding coding)
    {
        return coding.GetString(_buffer);
    }
    public static int Write(this Stream _buffer, string value, Encoding encoding)
    {
        if (string.IsNullOrEmpty(value))
            return 0;
        int result = 0;
        using (TemporaryBuffer<byte> bytes = value.Length * 6)
        {
            result = encoding.GetBytes(value, 0, value.Length, bytes.Data, 0);
            _buffer.Write(bytes.Data, 0, result);
            return result;
        }
    }
    public static ReadOnlySequence<byte>? IndexOf(this ReadOnlySequence<byte> _buffer, byte[] eof)
    {
        var point = _buffer.PositionOf(eof[^1]);
        if (point != null)
        {
            Console.WriteLine($"_buffersize:{_buffer.Length}\t {eof[^1]} index:{point.Value.GetInteger()} offsetInex:{_buffer.GetOffset(point.Value)}");
            if (eof.Length == 1)
                return _buffer.Slice(0, point.Value);
            else
            {
                var index = _buffer.GetOffset(point.Value);
                if (index >= eof.Length)
                {
                    var eofbuffer = _buffer.Slice(index - eof.Length + 1, eof.Length);
                    var data = eofbuffer.ToArray();
                    for (int i = 0; i < eof.Length; i++)
                    {
                        if (data[i] != eof[i])
                            return null;
                    }
                    return _buffer.Slice(0, index + 1);
                }
            }
        }
        return null;
    }
}

Debug info:
image

Copy link

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

@dotnet-issue-labeler dotnet-issue-labeler bot added the untriaged New issue has not been triaged by the area owner label May 20, 2024
@baronfel baronfel transferred this issue from dotnet/sdk May 20, 2024
@dotnet-issue-labeler dotnet-issue-labeler bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label May 20, 2024
@vcsjones vcsjones added area-System.Buffers and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels May 20, 2024
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-buffers
See info in area-owners.md if you want to be subscribed.

@lilinus
Copy link
Contributor

lilinus commented May 21, 2024

Could this be a duplicate of #75866?

@beetlex-io
Copy link
Author

beetlex-io commented May 21, 2024

Maybe, use ReadOnlySequence.GetOffset(point) value does not change after the ReadOnlySequence.Slice method is called.

string name = "name:henryfan\r";
ReadOnlySequence<byte> sequence = new ReadOnlySequence<byte>(Encoding.UTF8.GetBytes(name));
var point = sequence.PositionOf((byte)'\r');
var index = sequence.GetOffset(point.Value);//return 13 right
sequence = sequence.Slice(2);
point = sequence.PositionOf((byte)'\r');
index = sequence.GetOffset(point.Value);//return 13 wrong

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-System.Buffers untriaged New issue has not been triaged by the area owner
Projects
None yet
Development

No branches or pull requests

3 participants