Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[C++] isspace(char): onveilig?

Pagina: 1
Acties:

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Wie weet waarom isspace(char) onveilig is en waarom deze functie toch zo ontworpen is?
C++:
1
2
3
4
std::string v = "user input";
if (v.empty())
    return;
isspace(v[0]);

[ Voor 36% gewijzigd door Olaf van der Spek op 09-11-2007 16:05 ]


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Waarom zou isspace onveilig zijn? Kun je in ieder geval iets meer uitweiden dan een topicstart van 1 zin?
edit:

Ah, er staat nu iig al code bij

[ Voor 17% gewijzigd door RobIII op 09-11-2007 16:07 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

wie zegt dan dat isspace() onveilig is?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Comp_Lex
  • Registratie: Juni 2005
  • Laatst online: 03:35
Ik zou niet weten waarom isspace onveilig zou zijn. Laat ik een gok doen: het gedrag is ongedefinieerd wanneer je geen int voert aan de functie die een unsigned char representeert? :?

  • leuk_he
  • Registratie: Augustus 2000
  • Laatst online: 28-11 09:35

leuk_he

1. Controleer de kabel!

Thread safe?
Unicode safe
Locale safe?

chasht het soms?

Need more data. We want your specs. Ik ben ook maar dom. anders: forum, ff reggen, ff topic maken
En als je een oplossing hebt gevonden laat het ook ujb ff in dit topic horen.


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Genoeg gegokt; laten we even afwachten waar TS mee komt.

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Comp_Lex schreef op vrijdag 09 november 2007 @ 16:24:
Ik zou niet weten waarom isspace onveilig zou zijn. Laat ik een gok doen: het gedrag is ongedefinieerd wanneer je geen int voert aan de functie die een unsigned char representeert? :?
Inderdaad.
Het argument is een int, en de functie verwacht een waarde tussen -1 en 255. Maar char en dus ook std::string zijn vrijwel altijd signed, dus is het eigenlijk vragen om problemen. Nu zit ik me dus af te vragen, waarom werkt die functie niet gewoon ook voor 'negatieve waarden' die niet ongebruikelijk zijn in een char/string?
En, hoe voorkom je dat je in deze 'val' trapt als je er even niet aan denkt?

[ Voor 5% gewijzigd door Olaf van der Spek op 09-11-2007 17:06 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Hmm signedness, daar had ik niet aan gedacht. Best stom. Dat ie niet kan werken voor negatieve waarden is logisch - EOF is gelijk aan -1, maar niet aan de char 0xff.

Nou gebruik ik sowieso nooit die is* functies. We hebben ze hier op 't werk ook vakkundig weggesloopt bij het parsen van xml data omdat ze ranzig traag zijn (in de VC++ CRT iig, geen idee hoe dat met andere implementaties zit) omdat ze elke keer zo'n locale ophalen e.d.. En dat terwijl onze invoer toch altijd gewoon in de ASCII range valt, dus een whitespace is 9..13 of 32, een digit is '0'..'9', en een letter is 'A'..'Z' of 'a'..'z'.

Hoe je het voorkomt?
C++:
1
2
3
4
5
6
7
8
9
#include <cctype>

namespace std
{
    bool isspace(char c)
    {
        return isspace(c & 0xff);
    }
}


.edit: blaat. Onzin natuurlijk. Als je een char erin stopt ben je gewoon dom bezig. Uiteraard verwacht isdigit() een verbreedde char - wat je verkrijgt door ctype<char>::widen() aan te roepen op een locale. Hij verwacht geen chars, dus waarom er eentje geven? Da's vragen om problemen :). Voor C ben je gewoon screwed, maar C is dan ook een kuttaal :P

[ Voor 28% gewijzigd door .oisyn op 09-11-2007 18:00 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Comp_Lex
  • Registratie: Juni 2005
  • Laatst online: 03:35
Het is erg lastig om dat te voorkomen, want de compiler geeft namelijk geen waarschuwingen over het type char dat wordt gebruikt (signed of unsigned). Het is volledig afhankelijk van de processor. Het enige snelle manier om er achter te komen dat je niet in de 'val' bent getrapt is om gewoon het programma te runnen en kijken hoe het zich gedraagt.

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
.oisyn schreef op vrijdag 09 november 2007 @ 17:46:
.edit: blaat. Onzin natuurlijk. Als je een char erin stopt ben je gewoon dom bezig. Uiteraard verwacht isdigit() een verbreedde char - wat je verkrijgt door ctype<char>::widen() aan te roepen op een locale. Hij verwacht geen chars, dus waarom er eentje geven? Da's vragen om problemen :). Voor C ben je gewoon screwed, maar C is dan ook een kuttaal :P
Wat bedoel je met een verbrede char? Een wchar?
Maar in een deel van de taal/library chars tussen -128 en 127 gebruiken en in een ander deel ints tussen -1 en 255 is toch gewoon niet handig?
Signed chars vind ik uberhaupt geen handige keus.

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Comp_Lex schreef op vrijdag 09 november 2007 @ 17:49:
Het is erg lastig om dat te voorkomen, want de compiler geeft namelijk geen waarschuwingen over het type char dat wordt gebruikt (signed of unsigned). Het is volledig afhankelijk van de processor.
Niet volledig, bij sommige compilers kun je gewoon kiezen.
Het enige snelle manier om er achter te komen dat je niet in de 'val' bent getrapt is om gewoon het programma te runnen en kijken hoe het zich gedraagt.
Dat deed ik net dus, ik was wat met UTF-8 aan het testen en voila: assertion failure.

  • Comp_Lex
  • Registratie: Juni 2005
  • Laatst online: 03:35
Olaf van der Spek schreef op vrijdag 09 november 2007 @ 18:25:
Niet volledig, bij sommige compilers kun je gewoon kiezen.
Okee, dat wist ik niet :)

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
Olaf van der Spek schreef op vrijdag 09 november 2007 @ 18:25:
Dat deed ik net dus, ik was wat met UTF-8 aan het testen en voila: assertion failure.
Dat is niet zo'n verbazing, als je geen UTF-8 locale hebt. En als je dat wel hebt, dan moet je char unsigned zijn. Verder is UTF-8 een probleem; omdat er genoeg digits zijn die niet in een enkele char passen. Alleen de arabische cijfers passen, maar Unicode heeft meer digits.

[ Voor 20% gewijzigd door MSalters op 10-11-2007 09:52 ]

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
MSalters schreef op zaterdag 10 november 2007 @ 09:50:
Dat is niet zo'n verbazing, als je geen UTF-8 locale hebt.
Waarom?
Ik verwacht geen assertion failure, zelfs als ik er binary troep in stop.
En als je dat wel hebt, dan moet je char unsigned zijn. Verder is UTF-8 een probleem; omdat er genoeg digits zijn die niet in een enkele char passen. Alleen de arabische cijfers passen, maar Unicode heeft meer digits.
Het gaat hier over isspace, niet isdigit.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Olaf van der Spek schreef op vrijdag 09 november 2007 @ 18:24:
[...]

Wat bedoel je met een verbrede char? Een wchar?
Nee, een type dat naast alle geldige tekens ook EOF kan bevatten (in de regel gewoon een int). Op je basic_ios<> (base class van basic_istream<> en -ostream<>) zit ook een widen() functie die in principe gewoon use_facet<ctype<char> >(m_locale).widen() doet om een char te converteren naar dat andere type.
Maar in een deel van de taal/library chars tussen -128 en 127 gebruiken en in een ander deel ints tussen -1 en 255 is toch gewoon niet handig?
De std::is* functies verwachten geen char maar een int. Voor de C variant van de is* functies verwachten ze alle waarden die gerepresenteerd kunnen worden door een unsigned char, -1, of het resultaat van functies als tolower en toupper
Signed chars vind ik uberhaupt geen handige keus.
chars zijn niet per definitie signed ;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
.oisyn schreef op zaterdag 10 november 2007 @ 12:48:
De std::is* functies verwachten geen char maar een int. Voor de C variant van de is* functies verwachten ze alle waarden die gerepresenteerd kunnen worden door een unsigned char, -1, of het resultaat van functies als tolower en toupper
Handig is anders.
chars zijn niet per definitie signed ;)
Dat weet ik. Eigenlijk had ik chars graag unsigned gezien per definitie. Zou een hoop geklooi met byte / unsigned char vs (signed) char voorkomen hebben.
Pagina: 1