improve uri handling

This commit is contained in:
Fabian Freund
2026-03-10 04:35:27 +01:00
parent 36bdb5b966
commit f56fe86501
3 changed files with 29 additions and 7 deletions
+2 -1
View File
@@ -25,7 +25,8 @@ class UriConverter extends TypeConverter<Uri, String> {
@override @override
Uri fromSql(String fromDb) { Uri fromSql(String fromDb) {
return uri_parser.tryParseUrl(fromDb, eagerParsing: true)!; return uri_parser.tryParseUrl(fromDb, eagerParsing: true) ??
Uri.parse(fromDb);
} }
@override @override
@@ -18,6 +18,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:weblibre/utils/uri_parser.dart' as uri_parser;
Future<({String title, Uri url})?> showEditTopSiteDialog( Future<({String title, Uri url})?> showEditTopSiteDialog(
BuildContext context, { BuildContext context, {
@@ -94,8 +95,11 @@ class _EditTopSiteDialogState extends State<_EditTopSiteDialog> {
if (value == null || value.trim().isEmpty) { if (value == null || value.trim().isEmpty) {
return 'URL cannot be empty'; return 'URL cannot be empty';
} }
final uri = Uri.tryParse(value.trim()); final parsed = uri_parser.tryParseUrl(
if (uri == null || !uri.hasScheme || uri.host.isEmpty) { value.trim(),
eagerParsing: true,
);
if (parsed == null) {
return 'Enter a valid URL'; return 'Enter a valid URL';
} }
return null; return null;
@@ -112,7 +116,11 @@ class _EditTopSiteDialogState extends State<_EditTopSiteDialog> {
TextButton( TextButton(
onPressed: () { onPressed: () {
if (_formKey.currentState?.validate() == true) { if (_formKey.currentState?.validate() == true) {
final url = Uri.parse(_urlController.text.trim()); final url = uri_parser.tryParseUrl(
_urlController.text.trim(),
eagerParsing: true,
);
if (url == null) return;
Navigator.pop( Navigator.pop(
context, context,
(title: _titleController.text.trim(), url: url), (title: _titleController.text.trim(), url: url),
@@ -30,6 +30,7 @@ import 'package:weblibre/features/geckoview/features/top_sites/data/providers.da
import 'package:weblibre/features/geckoview/features/top_sites/domain/entities/top_site_item.dart'; import 'package:weblibre/features/geckoview/features/top_sites/domain/entities/top_site_item.dart';
import 'package:weblibre/features/geckoview/features/top_sites/domain/entities/top_site_source.dart'; import 'package:weblibre/features/geckoview/features/top_sites/domain/entities/top_site_source.dart';
import 'package:weblibre/features/geckoview/features/top_sites/domain/providers.dart'; import 'package:weblibre/features/geckoview/features/top_sites/domain/providers.dart';
import 'package:weblibre/utils/uri_parser.dart' as uri_parser;
part 'top_site_repository.g.dart'; part 'top_site_repository.g.dart';
@@ -81,9 +82,7 @@ class TopSiteRepository extends _$TopSiteRepository {
final remaining = targetCount - persisted.length; final remaining = targetCount - persisted.length;
final historyItems = await _getHistoryItems( final historyItems = await _getHistoryItems(
limit: remaining, limit: remaining,
excludeUrls: persisted excludeUrls: persisted.map((s) => s.url.normalized.toString()).toSet(),
.map((s) => s.url.normalized.toString())
.toSet(),
); );
return [...persisted, ...historyItems]; return [...persisted, ...historyItems];
@@ -126,10 +125,23 @@ class TopSiteRepository extends _$TopSiteRepository {
); );
} }
static Uri _validateUrl(Uri url) {
final normalized = url.normalized;
final parsed = uri_parser.tryParseUrl(
normalized.toString(),
eagerParsing: true,
);
if (parsed == null) {
throw ArgumentError.value(url.toString(), 'url', 'Invalid URL');
}
return normalized;
}
Future<String> addPinnedSite({ Future<String> addPinnedSite({
required String title, required String title,
required Uri url, required Uri url,
}) async { }) async {
_validateUrl(url);
final db = ref.read(topSiteDatabaseProvider); final db = ref.read(topSiteDatabaseProvider);
// Check if URL already exists as a persisted site // Check if URL already exists as a persisted site
@@ -163,6 +175,7 @@ class TopSiteRepository extends _$TopSiteRepository {
required String title, required String title,
required Uri url, required Uri url,
}) { }) {
_validateUrl(url);
return ref return ref
.read(topSiteDatabaseProvider) .read(topSiteDatabaseProvider)
.topSiteDao .topSiteDao