blob: 9623b7aab370716eff83ec7c8345b0cfce7b3831 [file] [log] [blame]
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:expect/expect.dart';
void testValidIPvFutureUri() {
void test(String address) {
var bracketedAddress = '[$address]';
var path = 'https://me:you@$bracketedAddress:1234/path?query=5#now';
var uri = Uri.parse(path);
var uriString = uri.toString();
Expect.equals(path, uriString);
Expect.isTrue(uri.hasAuthority);
Expect.equals('https', uri.scheme, ".scheme of $uriString");
Expect.equals('me:you', uri.userInfo, ".userInfo of $uriString");
Expect.equals(bracketedAddress, uri.host, ".host of $uriString");
Expect.equals(1234, uri.port, ".port of $uriString");
Expect.equals('/path', uri.path, ".path of $uriString");
Expect.equals('query=5', uri.query, ".query of $uriString");
Expect.equals('now', uri.fragment, ".fragment of $uriString");
uri = Uri(scheme: 'https', host: bracketedAddress, path: '/path');
Expect.isTrue(uri.hasAuthority);
Expect.equals('https://$bracketedAddress/path', uri.toString());
Expect.equals(bracketedAddress, uri.host);
uri = Uri.https(bracketedAddress, '/path');
Expect.isTrue(uri.hasAuthority);
Expect.equals('https://$bracketedAddress/path', uri.toString());
Expect.equals(bracketedAddress, uri.host);
uri = Uri.parse('https://example.com/path');
uri = uri.replace(host: bracketedAddress);
Expect.isTrue(uri.hasAuthority);
Expect.equals('https://$bracketedAddress/path', uri.toString());
Expect.equals(bracketedAddress, uri.host);
}
test('v0.0'); // Minimal valid
test('vDEADBEEF.CAKE:EAT'); // More characters.
// All allowed characters in each position
// (skipping the middle ones of 0-9, a-z and A-Z).
test(r"v0123456789abcdefABCDEF.!$&'()*+,-.09:;=AZ_az~");
}
void testInvalidIPvFutureUri() {
void fail(String host) {
Expect.throwsFormatException(() => Uri.parse('http://[$host]/'), '[$host]');
Expect.throwsFormatException(
() => Uri(scheme: 'http', host: '[$host]'),
'[$host]',
);
}
// No leading whitespace.
fail(' v0.0'); // Also not valid IPv6.
// Must start with lower-case 'v'.
fail('V0.0'); // Also not valid IPv6.
// Does not allow escapes, %56 is 'v'.
fail('%560.0'); // Also not valid IPv6.
// Hex digit must follow `v`.
fail('v');
fail('v:');
fail('v:0');
fail('v 0.0');
fail('v.:');
fail('vv0.:');
fail('v%41.:'); // No escape.
// Correct ranges for hex digits.
fail('v/.:'); // / is before 0
fail('v:.:'); // : is after 9
fail('v@.:'); // @ is before A
fail('vG.:'); // G is after F
fail('v`.:'); // ` is before a
fail('vg.:'); // g is after f
// Dot must follow hex-digits.
fail('v0');
fail('v0:');
fail('v0%2E:'); // No escape.
// Correct ranges for second hex digit.
fail('v0/.:'); // / is before 0
fail('v0:.:'); // : is after 9
fail('v0@.:'); // @ is before A
fail('v0G.:'); // G is after F
fail('v0`.:'); // ` is before a
fail('v0g.:'); // g is after f
// Valid character must follow dot.
// Unreserved, sub-delimiters and colon are valid.
fail('vA.');
fail('vA.%41'); // No escapes, no zones
// No trailing garbage.
fail('v0.0 ');
fail('v0.0/');
// No zones.
fail('v0.0%41');
fail('v0.0%25x');
}
void main() {
testValidIPvFutureUri();
testInvalidIPvFutureUri();
}