@@ -1476,15 +1476,94 @@ drag_process_item_data(Window *w, size_t idx, int has_more, const uint8_t *paylo
14761476}
14771477
14781478static const char * *
1479- parse_uri_list (int fd ) {
1480- (void )fd ;
1481- // TODO: Implement this, it should read the uri list from fd, parse
1482- // it ignoring comments, see get_nth_file_url() for an example of
1483- // parsing a uri list. If an error occurs it should call abrt() with
1484- // appropriate error code and return NULL. The returned value should
1485- // be a list of strings alloced by malloc with each string also
1486- // alloced by malloc.
1487- return NULL ;
1479+ parse_uri_list (Window * w , int fd , size_t * num_uris_out ) {
1480+ * num_uris_out = 0 ;
1481+ // Determine file size and read all data
1482+ off_t file_size = lseek (fd , 0 , SEEK_END );
1483+ if (file_size < 0 ) { cancel_drag (w , EIO ); return NULL ; }
1484+ if (lseek (fd , 0 , SEEK_SET ) < 0 ) { cancel_drag (w , EIO ); return NULL ; }
1485+ char * buf = malloc ((size_t )file_size + 1 );
1486+ if (!buf ) { cancel_drag (w , ENOMEM ); return NULL ; }
1487+ size_t total = 0 ;
1488+ while (total < (size_t )file_size ) {
1489+ ssize_t n = read (fd , buf + total , (size_t )file_size - total );
1490+ if (n < 0 ) {
1491+ if (errno == EINTR ) continue ;
1492+ free (buf ); cancel_drag (w , EIO ); return NULL ;
1493+ }
1494+ if (n == 0 ) break ;
1495+ total += (size_t )n ;
1496+ }
1497+ buf [total ] = '\0' ;
1498+
1499+ // First pass: count non-comment, non-empty lines
1500+ size_t count = 0 ;
1501+ char * p = buf ;
1502+ while (* p ) {
1503+ char * eol = p + strcspn (p , "\r\n" );
1504+ char saved = * eol ; * eol = '\0' ;
1505+ char * end = eol ;
1506+ while (end > p && (end [-1 ] == ' ' || end [-1 ] == '\t' )) end -- ;
1507+ char saved_end = * end ; * end = '\0' ;
1508+ if (* p && * p != '#' ) count ++ ;
1509+ * end = saved_end ;
1510+ * eol = saved ;
1511+ if (saved == '\0' ) break ;
1512+ p = eol + 1 ;
1513+ while (* p == '\r' || * p == '\n' ) p ++ ;
1514+ }
1515+
1516+ const char * * result = malloc ((count + 1 ) * sizeof (const char * ));
1517+ if (!result ) { free (buf ); cancel_drag (w , ENOMEM ); return NULL ; }
1518+
1519+ // Second pass: fill in decoded URI strings
1520+ size_t idx = 0 ;
1521+ p = buf ;
1522+ while (* p && idx < count ) {
1523+ char * eol = p + strcspn (p , "\r\n" );
1524+ char saved = * eol ; * eol = '\0' ;
1525+ char * end = eol ;
1526+ while (end > p && (end [-1 ] == ' ' || end [-1 ] == '\t' )) end -- ;
1527+ * end = '\0' ;
1528+ if (* p && * p != '#' ) {
1529+ char * decoded = NULL ;
1530+ if (strncmp (p , "file://" , 7 ) == 0 ) {
1531+ const char * rest = p + 7 ;
1532+ const char * slash = strchr (rest , '/' );
1533+ if (slash ) {
1534+ size_t host_len = (size_t )(slash - rest );
1535+ if (host_len == 0 || (host_len == 9 && strncasecmp (rest , "localhost" , 9 ) == 0 )) {
1536+ decoded = strdup (slash );
1537+ if (decoded ) {
1538+ char * qf = decoded + strcspn (decoded , "?#" );
1539+ * qf = '\0' ;
1540+ url_decode_inplace (decoded );
1541+ }
1542+ } else {
1543+ decoded = strdup (p );
1544+ }
1545+ } else {
1546+ decoded = strdup (p );
1547+ }
1548+ } else {
1549+ decoded = strdup (p );
1550+ }
1551+ if (!decoded ) {
1552+ for (size_t k = 0 ; k < idx ; k ++ ) free ((char * )result [k ]);
1553+ free (result ); free (buf );
1554+ cancel_drag (w , ENOMEM ); return NULL ;
1555+ }
1556+ result [idx ++ ] = decoded ;
1557+ }
1558+ * eol = saved ;
1559+ if (saved == '\0' ) break ;
1560+ p = eol + 1 ;
1561+ while (* p == '\r' || * p == '\n' ) p ++ ;
1562+ }
1563+ result [idx ] = NULL ;
1564+ free (buf );
1565+ * num_uris_out = idx ;
1566+ return result ;
14881567}
14891568
14901569
@@ -1500,7 +1579,7 @@ drag_remote_file_data(
15001579 }
15011580 if (item_idx == ds .num_mimes || ds .items [item_idx ].fd_plus_one == 0 ) abrt (EINVAL );
15021581 if (ds .items [item_idx ].uri_list == NULL ) {
1503- ds .items [item_idx ].uri_list = parse_uri_list (ds .items [item_idx ].fd_plus_one - 1 );
1582+ ds .items [item_idx ].uri_list = parse_uri_list (w , ds .items [item_idx ].fd_plus_one - 1 , & ds . items [ item_idx ]. num_uris );
15041583 if (!ds .items [item_idx ].uri_list ) return ;
15051584 }
15061585 (void )x ; (void )y ; (void )X ; (void )Y ; (void )has_more ; (void )payload ; (void )payload_sz ;
0 commit comments