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

Creation of arrays with negative lengths? #110949

Open
jerviscui opened this issue Dec 26, 2024 · 9 comments
Open

Creation of arrays with negative lengths? #110949

jerviscui opened this issue Dec 26, 2024 · 9 comments
Labels
area-System.Threading untriaged New issue has not been triaged by the area owner

Comments

@jerviscui
Copy link

jerviscui commented Dec 26, 2024

var newArray = new object?[m_array.Length << 1];

I have a problem where a continuous left shift goes negative, and the code throws an exception.
Am I missing something?

Thank you everyone.

Successive left shifts in this code will cause the length to become negative, throwing an exception. But there is no defensive code here.

My question is, will this never happen? Hidden logic in the CLR or otherwise?

@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 Dec 26, 2024
@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label Dec 26, 2024
@En3Tho
Copy link
Contributor

En3Tho commented Dec 26, 2024

How do you even end up having 2 billion work items in the first place?

Are you just pushing more and more items in an endless loop or something?

Expanding an array more and more won't help you as it is a clear indication of a bug in your code

@huoyaoyuan
Copy link
Member

Trying to create array of negative length will throw an exception. It's a safe behavior for handling exceptional cases.

@vcsjones vcsjones added area-System.Threading and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Dec 26, 2024
@huoyaoyuan
Copy link
Member

How do you even end up having 2 billion work items in the first place?

Security-wise, it's still important to get exceptionally large content correctly rejected, instead of causing security issues like buffer overrun.

@EgorBo
Copy link
Member

EgorBo commented Dec 26, 2024

@jerviscui is the question basically "how can m_array.Length << 1 produce a negative value"? if so, just run this:

byte[] arr = new byte[1_100_000_000];
Console.WriteLine(arr.Length << 1);

@EgorBo EgorBo added the needs-author-action An issue or pull request that requires more info or actions from the author. label Dec 26, 2024
@sfiruch
Copy link
Contributor

sfiruch commented Dec 27, 2024

var newArray = new object?[m_array.Length << 1];
I have a problem where a continuous left shift goes negative, and the code throws an exception. Am I missing something?

m_array.Length is a signed integer. The most-significant bit of a signed integer specifies whether the integer represents a positive or negative number.

If you start with a very large signed integer, which has the second-most-significant-bit set, the left-shift will shift that bit into the most-significant position. This then represents a negative number, because the most-significant bit is set.

This is expected behavior. I don't think it's an issue/bug in .NET.

@jerviscui
Copy link
Author

How do you even end up having 2 billion work items in the first place?

Security-wise, it's still important to get exceptionally large content correctly rejected, instead of causing security issues like buffer overrun.

Yes, I agree.
I was wondering if there is hidden logic in the CLR to prevent this.

@dotnet-policy-service dotnet-policy-service bot removed the needs-author-action An issue or pull request that requires more info or actions from the author. label Dec 31, 2024
@jerviscui
Copy link
Author

@EgorBo I have re-described problem. Thanks.

@EgorBo
Copy link
Member

EgorBo commented Dec 31, 2024

@EgorBo I have re-described problem. Thanks.

My question is, will this never happen? Hidden logic in the CLR or otherwise?

Well it may happen if you push some unrealistic amount of work item to the pool I guess. We may change the logic to be aligned what List's Grow does, namely

if ((uint)newCapacity > Array.MaxLength) newCapacity = Array.MaxLength;

but it won't protect you from an exception anyway if you're just stress-testing it

@sfiruch
Copy link
Contributor

sfiruch commented Dec 31, 2024

Security-wise, it's still important to get exceptionally large content correctly rejected, instead of causing security issues like buffer overrun.

Yes, I agree. I was wondering if there is hidden logic in the CLR to prevent this.

What would you expect to happen when there's no more space in the queue?

You probably shouldn't have billions of entries in a ThreadPoolWorkQueue anyway. I think raising an exception is reasonable for such an exceptional case. You pobably try to divide the work too fine-grained. Parallel and .AsParallel() are easy-to-use altternatives that do not suffer from this problem.

If the implementation of ThreadPoolWorkQueue used extreme measures to support an arbitrary number of entries, i.e. more than int.MaxValue, you'll eventually run out of memory, which will rrsult in an exception.

Either way, you get an exception when you try to put billions of elements into queues. You shouldn't do this. The only quesition is perhaps, which Exception you should get. I think the ThreadPoolWorlQueue could produce a more descriptive exception.

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

No branches or pull requests

6 participants