IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

La version stable de Rust 1.27.1 est désormais disponible !
Bogue d'emprunts et faille de sécurité du côté de rustdoc corrigés

Le , par Songbird

1KPARTAGES

11  0 
Rust est un langage de programmation système axé sur la sécurité, la rapidité et la concurrence.

Pour mettre à jour votre version stable, il suffit d’exécuter la commande habituelle.

Code bash : Sélectionner tout
$ rustup update stable

Si vous ne disposez pas de rustup, vous pouvez en obtenir une copie sur la page de téléchargement du site officiel. N’hésitez pas également à consulter la release note de la 1.27.1 sur GitHub !

Patch : Faux positif sur les ressources empruntées

En Rust, les notions d’emprunt (borrowing) et de transfert (ownership) sont fondamentales et régissent la gestion des ressources. Ici, foo a l’ownership sur un objet Foo.

Code Rust : Sélectionner tout
1
2
3
fn main() { 
    let foo: Foo = Foo; 
}

Nous pourrions nous en servir par le biais d’une référence bar, à quelques exceptions près.

Code Rust : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#[derive(Debug)] 
struct Foo; 
  
fn main() { 
    let foo: Foo = Foo; 
  
    // On emprunte l'objet `foo` en lecture seule. 
    let bar: &Foo = &foo; 
  
    super_foo_factory(foo); 
  
    println!("{:?}", bar); 
} 
  
// Ici, la fonction prend un paramètre dont la ressource 
// doit forcément être transférée. 
fn super_foo_factory(f: Foo) -> Foo { 
    /* ... On traite l'objet ... */ 
    f 
}
Code Rust : Sélectionner tout
1
2
3
4
5
6
7
8
error[E0505]: cannot move out of `foo` because it is borrowed 
  --> src/main.rs:10:23 
   | 
8  |     let bar: &Foo = &foo; 
   |                      --- borrow of `foo` occurs here 
9  |      
10 |     super_foo_factory(foo); 
   |                       ^^^ move out of `foo` occurs here

Je pense qu’on ne peut pas faire plus explicite. Le compilateur est capable de différencier un emprunt (en l’occurrence bar) d’un transfert (que je n’ai pas illustré ici avec une autre variable, mais qui peut aisément l’être grâce au paramètre f de la fonction super_foo_factory).

Seulement, comme pour le dernier bug en date causé par une révision de l’expression match, le compilateur ne semblait plus différencier les deux notions.

Code Rust : Sélectionner tout
1
2
3
4
5
6
fn main() { 
    let a = vec!["".to_string()]; 
    a.iter().enumerate() 
            .take_while(|(_, &t)| false) 
            .collect::<Vec<_>>(); 
}
Code Rust : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
error[E0507]: cannot move out of borrowed content 
    --> src/main.rs:4:30 
    | 
  4 |             .take_while(|(_, &t)| false) 
    |                              ^- 
    |                              || 
    |                              |hint: to prevent move, use `ref t` or `ref mut t` 
    |                              cannot move out of borrowed content 
  
error: aborting due to previous error

Ici, le compilateur nous renvoie une erreur affirmant que nous tentons de transférer une ressource empruntée et nous suggère d’effectuer un emprunt, ce qui est déjà le cas.

En réponse à cela, le problème a été corrigé dans la 1.27.1.

Pour ceux qui se poseraient la question :

  • enumerate() crée un itérateur contenant un tuple de deux valeurs (index, valeur) par élément;
  • take_while() crée un nouvel itérateur en accumulant les éléments matchant le prédicat (i.e. tant que le prédicat renvoie true, les éléments sont accumulés);
  • collect() crée une nouvelle collection avec les éléments triés par la dernière méthode.


Patch: Exploitation possible du système de plugin de rustdoc

Ce 3 juillet, Red Hat a rapporté une vulnérabilité affectant le comportement de rustdoc. En effet, le système de plugin de rustdoc dispose d’un répertoire par défaut (i.e. /tmp/rustdoc/plugins) dans lequel les plugins seront chargés. Ce dernier pouvant être accédé en écriture, sans restrictions spécifiques sur la plupart des plateformes, il est possible d’y ajouter une bibliothèque dynamique pour ainsi exécuter du code arbitraire au lancement de l’outil.

Pour tenter de corriger progressivement la faille, il a été décidé que ce chemin par défaut serait supprimé et que l’utilisateur serait dans l’obligation de fournir explicitement un chemin dans lequel charger les plugins. L’équipe Rust prévoit de supprimer intégralement la fonctionnalité pour la version 1.28.0.

Source

Le blog de l'équipe Rust

Une erreur dans cette actualité ? Signalez-nous-la !

Avatar de Pyramidev
Expert éminent https://www.developpez.com
Le 06/08/2018 à 11:30
Salut,

Concernant les tailles de Option<u16> et Option<NonZeroU16>, l'explication est la suivante :
  • Option<u16> contient 65537 valeurs possibles (None et les valeurs de Some(0) à Some(65535)), donc ne peut pas tenir sur seulement 2 octets, quelle que soit l'implémentation.
  • Option<NonZeroU16> contient 65536 valeurs possibles (None et les valeurs de Some(1) à Some(65535)), donc peut tenir sur seulement 2 octets, si on choisit la bonne implémentation.


À mon avis, sous le capot, Option<NonZeroU16> contient un entier n entre 0 et 65535. Si n == 0, alors cela correspond à None. Sinon, cela correspond à Some(n). Je n'ai pas vérifié, mais ce serait l'implémentation la plus logique.
1  0 
Avatar de Songbird
Membre expert https://www.developpez.com
Le 11/08/2018 à 21:58
Hello,

Effectivement, je n'y avais pas pensé. Merci pour l'élément de réponse !
0  0