I think the relevant part of the C++17 Standard is here
27.2.1 In general [ iterator.requirements.general ]
...
8 An iterator j is called reachable from an iterator i if and only if there is a finite sequence of applications of the expression ++i that makes i == j. If j is reachable from i, they refer to elements of the same sequence.
9 Most of the library’s algorithmic templates that operate on data structures have interfaces that use ranges. A range is a pair of iterators that designate the beginning and end of the computation. A range [i, i) is an empty range; in general, a range [i, j) refers to the elements in the data structure starting with the element pointed to by i and up to but not including the element pointed to by j. Range [i, j) is valid if and only if j is reachable from i. The result of the application of functions in the library to invalid ranges is undefined.
So extracting the pertinent parts:
8 An iterator j is called reachable from an iterator i if and only if there is a finite sequence of applications of the expression ++i that makes i == j...
9 ... Range [i, j) is valid if and only if j is reachable from i....
So it seems that a "valid range" is a pair of iterators that belong to the same container (or array), with j being farther along than i.
But also not forgetting:
in general, a range [i, j) refers to the elements in the data structure starting with the element pointed to by i and up to but not including the element pointed to by j.
So all of the iterators between i and j (but not necessarily including j) must be "in the data structure" (ie. not out-of-bounds).