The answer to this question is actually much more interesting than it seems :-).
If you're doing this call on-chain then you're limited by the block gas limit minus the amount of gas that you need to use to be able to trigger the call in the first place.
However... if you're doing this off-chain (e.g., a front-end is using the
eth_call RPC method) then your actual limit will fully depend on the specific node you're querying! Check out the following line of code from go-ethereum:
result, err := DoCall(ctx, s.b, args, blockNrOrHash, overrides, 5*time.Second, s.b.RPCGasCap())
Nodes are allowed to set a gas limit higher than the block gas limit specifically for RPC calls like
eth_call in the form of the
s.b.RPCGasCap() variable being passed into the
DoCall function. However, Geth also has a built-in timeout of
5*time.Second = 5 seconds so calls will automatically fail if they haven't completed after that amount of time. Nodes can choose to modify this timeout if they'd like, but I assume most nodes leave this untouched.
So the real (and unsatisfying) answer is "it depends". I believe node providers like Infura do set this RPC gas cap to be much higher than the block gas limit by about 2x (~60m gas?). I'm not 100% sure though, I would have to do some experimentation to figure that out.