Hallo,
nur einmal so an all die Programmierer die das mit den Datentypen nicht so ernst nehmen.
|
Anzeige
|
Ursache ist ein ungeprüfter Typecast.Hallo, nur einmal so an all die Programmierer die das mit den Datentypen nicht so ernst nehmen. Danke für den Hinweis! Hab' direkt erst einmal WAP-Push abgeschaltet. Für C-Programmierer müsste man mal ein Programm schreiben, das sowas überprüft. Ich würde es "lint" nennen.
Man wird davon ausgehen können, daß der Kram nicht in C geschrieben ist. Die im Artikel erwähnte Neuzeitlichere Compiler wie z.B. Clang/llvm haben eine deutlich bessere Quelltextprüfung, die lint nicht mehr unbedingt erforderlich machen.
und die engine für Java ist in C geschrieben.
Sowas lässt sich leicht schreiben, wenn man noch nie lint verwendet hat (Unterstellung). Lint kann so richtig nerven, bis jetzt ist mir das noch nicht bei C-Compilern untergekommen.
Hab's in den c't Kommentaren gefunden. Nachrichten(Messenger) · Einstellungen · weitere Einstellungen · WAP-Push Aus
Danke, ich habe es auch schon gefunden.
Hier ist eher das Problem, dass Java keine unsigned integer Typen kennt. Der Array-Konstruktor kriegt deshalb seine Längenangabe "signed" und muss sich zur Laufzeit mit einer Exception gegen negative Array-Längen wehren. in C erwartet malloc ein (unsigned) size_t, negative Angaben sind also nicht möglich. Macht es aber nicht besser, das ungeprüft übernommene Lägenfeld aus der WAP-Message wäre dann ein Out-of-Memory Fehler zur Laufzeit, wenn nicht behandelt mit demselben Resultat wie in Java.
Angeblich ist Java typsicher. C ist es nicht, das ist aber auch nix neues. Sowohl Java als auch C sind stark typisierte Sprachen. Die Typen werden natürlich auch geprüft. Nur hat man hier halt einen expliziten Typcast gemacht. In Rust wäre etwas vergleichbares vermutlich, das "unsafe" Keyword zu nutzen. Irgend ein zusätzlicher Linter wäre hier auch nutzlos. Ein Linter ist eher was für dynamisch typisierte Sprachen. https://en.wikipedia.org/wiki/Type_safety Ich hab schon ewig keine Java mehr verwendet. Dass man damit casten kann habe ich wohl vergessen. Aber es kann (vermutlich) nur casten auf kleinere Typen (64 -> 32 Bit).
Weder C noch Java sind dynamische Sprachen. lint wurde ursprünglich für C entwickelt und das aus gutem Grund. Java ist u.a. angetreten um die Probleme von C zu verhindern. Naja eigentlich kann keine Sprache vor so einem Problem schützen. Java schützt ja schon indem es eben eine Exception wirft. Selbst mit unsigned Typen wäre eine zu große Array-Größe ebenso problematisch und würde in einer Exception resultieren. Genau das macht übrigens Kotlin, welches (u.a.) auf der JVM läuft aber unsigned Typen bietet. Natürlich muss man alle extern rein kommenden Daten immer prüfen, ganz besonders wenn man sie als Allokationsgröße oder Index verwendet. Weiterhin muss man beim Interpretieren von solchen Nachrichten sowieso die Exceptions abfangen, und dann im Fehlerfall die Nachricht ignorieren und mit der nächsten Nachricht weiter machen, statt den ganzen Service abstürzen zu lassen. Irgendwas kann halt immer schief gehen, Exceptions lassen sich nicht wirklich 100% verhindern - der Sinn von Exceptions ist ja sowieso, dass man sauber drauf reagieren kann, in dem Fall halt indem man die Nachricht ignoriert (und eine Log-Meldung ausgibt). Es sind also eigentlich zwei Fehler, wäre es nur an einer dieser Stellen gut umgesetzt gäbe es hier kein Problem. Man fragt sich ein bisschen warum es so lange dauert, ein "if(x > 0)" sowie ein "try-catch" einzubauen und warum das in alten Android-Versionen gar nicht möglich sein soll.
Also die Zahl-Typen kann man in Java in alle Richtungen hin und her casten, natürlich ggf. mit Datenverlust. Klassen kann man downcasten, also wenn man eine Referenz vom Typ einer Basisklasse hat, die auf eine Instanz einer abgeleiteten Klasse referenziert, kann man sie auf den Typ der abgeleiteten Klasse umwandeln. Konzeptuell recht ähnlich zu C++. :
Bearbeitet durch User
Ich kenne lint; ich habe lint schon verwendet, als C89 noch ganz, ganz frisch war (da in der Variante "flexe-lint" von Gimpel). Ich kenne aber auch clang/llvm; genauer: ich arbeite damit.
Spielt hier aber überhaupt keine Rolle, selbst wenn's in Python geschrieben wäre, wäre das Problem das gleiche - ein Logikfehler in der Applikation.
C nervt immer... ;-)
Ich geb dirr mal ein Beispiel von einem Cast, der in Java erlaubt ist:
Macht man den instanceof Check nicht, und Castet falsch, endet man halt mit einer Exception.
Naja, bei <= c89 gab folgendes bei Compilern höchstens eine Warnung, wurde dann halt implizit Konvertiert. Aber bei allen mir bekannten heutigen Compilern, ab c99, produziert es einen harten Fehler:
Bei c89 hatte man also wirklich nicht viel von der statischen Typisierung, da konnte ein linter noch Sinn machen. Aber bei allem danach ist ein Linter nur noch dafür gut, komplett valide Programme anzumotzen und zu nerven, falls er den modernen C code überhaupt zu Parsen vermag. Wo auch immer man sie nutzt, Linter nerven hauptsächlich nur, das ist Fakt.
Zur Typsicherheit gibt es unterschiedliche Definitionen und Ansichten. Im allgemeinen wird C eher als schwach typsicher und nicht als stark typsicher beschrieben. In C wird z.B. float implizit nach double und char implizit nach int konvertiert.
Das ist (zumindest für mich) kein cast. Da wird der Typ abgefragt und dann auch der richtige Typ verwendet.
Das schon. Aber es gibt zwei Arten von casts: Implizip und explizip. Implizip ist z.B. wenn man einen int32 auf einen int64 zuweist, denn das ist zulässig und führt nicht zu Fehlern.
Unter Android 16 finde ich WAP-Push und kann es auf AUS stellen. Unter Android 15 finde ich WAP-Push nicht mehr. Mein S21 kam wohl damals mit Android 11 neu heraus und sollte laut Wicki bis Android 15 noch Updates erhalten. mfg Klaus
Das ist ... eine "interessante" Sichtweise. Schaltest Du auch immer alle Compilerwarnungen aus? Nein, ich habe normalerweise "-std=c17 -Wall -Wextra -pedantic -Werror" als Compiler Optionen. Wobei, manchmal deaktiviere ich manche Warnungen schon, wenn ich z.B. absichtlich nicht alle struct Felder initialisiere oder so. PS: :
Bearbeitet durch User
Die Java Language Specification kennt kein implizites Casten. Casten ist immer explizit, man muß es hinschreiben.
Das ist kein Casten sondern eine implizite Konvertierung, genauer eine Widening Primitive Conversion. Siehe 5.1.2 in https://docs.oracle.com/javase/specs/jls/se27/jls27.pdf. Antwort schreiben |
Anzeige
|