Thread View: be.comp.programming
24 messages
24 total messages
Started by Aquila
Tue, 01 Mar 2005 08:58
Printf: vaste lengte strings en ints?
Author: Aquila
Date: Tue, 01 Mar 2005 08:58
Date: Tue, 01 Mar 2005 08:58
11 lines
1812 bytes
1812 bytes
In een stukje logging code gebruik ik volgend commando: sprintf(buffer, "%s %.9f _%i_ --- %i %i ------- [%i:%i] (%s) %s", event, timeval2double(now), id, pid, length, nid, dst_i, message, additional) Nu is dit niet bepaald veilig omdat buffer een array met vaste lengte is. Hoe kan ik dat veiliger maken? In concreto: kan %s een maximum lengte opleggen? Kan %i een maximum lengte opleggen zonder daarvoor extra nullen te printen? In beide gevallen mag er afgekapt worden, ik wil gewoon beveiligingsfouten vermijden. -- "May the source be with you"
Re: Printf: vaste lengte strings en ints?
Author: Ingeborg
Date: Tue, 01 Mar 2005 09:09
Date: Tue, 01 Mar 2005 09:09
16 lines
1389 bytes
1389 bytes
Aquila <braempje@netscape.net> wrote in news:M5qdnYvpZutbs7nfRVnyjA@scarlet.biz: > In een stukje logging code gebruik ik volgend commando: > sprintf(buffer, "%s %.9f _%i_ --- %i %i ------- [%i:%i] (%s) %s", > event, timeval2double(now), id, pid, length, nid, dst_i, message, > additional) Nu is dit niet bepaald veilig omdat buffer een array met > vaste lengte is. Hoe kan ik dat veiliger maken? > In concreto: kan %s een maximum lengte opleggen? > Kan %i een maximum lengte opleggen zonder daarvoor extra nullen te > printen? In beide gevallen mag er afgekapt worden, ik wil gewoon > beveiligingsfouten vermijden. Bij strings %.ns, waarbij n de lengte is, en bij integers dacht ik ook. Kijk eens of de functie snprintf ook ondersteund is, dat is m.i. veiliger en netter.
Re: Printf: vaste lengte strings en ints?
Author: Marco van de Voort
Date: Tue, 01 Mar 2005 09:10
Date: Tue, 01 Mar 2005 09:10
13 lines
1551 bytes
1551 bytes
On 2005-03-01, Aquila <braempje@netscape.net> wrote: > In een stukje logging code gebruik ik volgend commando: > sprintf(buffer, "%s %.9f _%i_ --- %i %i ------- [%i:%i] (%s) %s", event, > timeval2double(now), id, pid, length, nid, dst_i, message, additional) > Nu is dit niet bepaald veilig omdat buffer een array met vaste lengte is. > Hoe kan ik dat veiliger maken? > In concreto: kan %s een maximum lengte opleggen? > Kan %i een maximum lengte opleggen zonder daarvoor extra nullen te printen? > In beide gevallen mag er afgekapt worden, ik wil gewoon beveiligingsfouten > vermijden. snprintf gebruiken? Het hele idee was juist om sprintf niet meer te gebruiken vziw
Re: Printf: vaste lengte strings en ints?
Author: Philip Paeps
Date: Tue, 01 Mar 2005 09:38
Date: Tue, 01 Mar 2005 09:38
18 lines
1784 bytes
1784 bytes
In be.comp.programming Aquila <braempje@netscape.net> wrote: > In een stukje logging code gebruik ik volgend commando: > sprintf(buffer, "%s %.9f _%i_ --- %i %i ------- [%i:%i] (%s) %s", event, > timeval2double(now), id, pid, length, nid, dst_i, message, additional) Is het niet handiger om gewoon syslog(3) te gebruiken? Dan zorgt syslogd(8) voor het formatten van messages op een fairly standaard manier, en moet je je enkel nog zorgen maken over je message zelf, niet over hoe laat het is, of waar het vandaan komt. - Philip -- Philip Paeps Please don't email any replies philip@paeps.cx I follow the newsgroup. The secret of success is sincerity. Once you can fake that you've got it made.
Re: Printf: vaste lengte strings en ints?
Author: Dr.Ruud
Date: Tue, 01 Mar 2005 09:58
Date: Tue, 01 Mar 2005 09:58
26 lines
1847 bytes
1847 bytes
Wat Aquila schreef, bleek het
begin van iets moois; kijk zelf maar:
> In een stukje logging code gebruik ik volgend commando:
> sprintf(buffer, "%s %.9f _%i_ --- %i %i ------- [%i:%i] (%s) %s",
> event, timeval2double(now), id, pid, length, nid, dst_i, message,
> additional)
Je programmeertaal zal dus wel C zijn?
> [...]
> Kan %i een maximum lengte opleggen zonder daarvoor extra nullen te
> printen? In beide gevallen mag er afgekapt worden, ik wil gewoon
> beveiligingsfouten vermijden.
Nee, maar je zou wel kunnen casten, bijvoorbeeld
(int32) id
want op die manier weet je dat %i maximaal 10 tekens kan opleveren,
zelfs als later 'id' een 64-bits integer zou worden.
--
Affijn, Ruud ` - �
+ ` � *
� ` Jvr qvg yrrfg,
� = ` fgresg wbatre.
Re: Printf: vaste lengte strings en ints?
Author: Aquila
Date: Tue, 01 Mar 2005 14:29
Date: Tue, 01 Mar 2005 14:29
8 lines
1413 bytes
1413 bytes
Marco van de Voort wrote: > snprintf gebruiken? Het hele idee was juist om sprintf niet meer te > gebruiken vziw Net wat ik nodig had, bedankt! -- "May the source be with you"
Re: Printf: vaste lengte strings en ints?
Author: Aquila
Date: Tue, 01 Mar 2005 14:30
Date: Tue, 01 Mar 2005 14:30
11 lines
1648 bytes
1648 bytes
Philip Paeps wrote: > Is het niet handiger om gewoon syslog(3) te gebruiken? Dan zorgt > syslogd(8) voor het formatten van messages op een fairly standaard manier, > en moet je je enkel nog zorgen maken over je message zelf, niet over hoe > laat het is, of waar het vandaan komt. Dit is low level experimentele code die niet aan syslog kan. Was logisch maar niet hier... -- "May the source be with you"
Re: Printf: vaste lengte strings en ints?
Author: Philip Paeps
Date: Tue, 01 Mar 2005 17:33
Date: Tue, 01 Mar 2005 17:33
25 lines
2033 bytes
2033 bytes
Aquila <braempje@netscape.net> wrote:
> Philip Paeps wrote:
> > Is het niet handiger om gewoon syslog(3) te gebruiken? Dan zorgt
> > syslogd(8) voor het formatten van messages op een fairly standaard manier,
> > en moet je je enkel nog zorgen maken over je message zelf, niet over hoe
> > laat het is, of waar het vandaan komt.
>
> Dit is low level experimentele code die niet aan syslog kan. Was logisch
> maar niet hier...
Zelfs de kernel kan aan syslog hoor (nuja, syslogd kan aan /dev/kmem *g*).
Maar als je er echt niet aan kan om welke reden dan ook, is het misschien aan
te raden om je eigen functie ervoor te schrijven en met een growing buffer
mechanisme te werken. Static buffers are bound to fail...
- Philip
--
Philip Paeps Please don't email any replies
philip@paeps.cx I follow the newsgroup.
BOFH Excuse #225:
It's those computer people in X {city of world}. They keep stuffing
things up.
Re: Printf: vaste lengte strings en ints?
Author: moi
Date: Wed, 02 Mar 2005 10:24
Date: Wed, 02 Mar 2005 10:24
53 lines
3290 bytes
3290 bytes
Dr.Ruud wrote:
> Wat Aquila schreef, bleek het
> begin van iets moois; kijk zelf maar:
>
>
>>In een stukje logging code gebruik ik volgend commando:
>>sprintf(buffer, "%s %.9f _%i_ --- %i %i ------- [%i:%i] (%s) %s",
>>event, timeval2double(now), id, pid, length, nid, dst_i, message,
>>additional)
>
>
>>[...]
>>Kan %i een maximum lengte opleggen zonder daarvoor extra nullen te
>>printen? In beide gevallen mag er afgekapt worden, ik wil gewoon
>>beveiligingsfouten vermijden.
>
>
> Nee, maar je zou wel kunnen casten, bijvoorbeeld
> (int32) id
> want op die manier weet je dat %i maximaal 10 tekens kan opleveren,
> zelfs als later 'id' een 64-bits integer zou worden.
>
Is wel erg paranoide, IMO, om rekening te houden met andere sizes.
En onsmakelijk om daar een cast voor te gebruiken.
Een int is een int. een "%d" of "%i" verwijst naar een int in de
arglist, ongeacht zijn/haar sizeof.
Het eenvoudigst, IMHO is om de buffer gewoon groot genoeg te maken:
een geformatteerde 32 bits int vergt 10 char +1 voor het teken.
<limits.h> vermeldt:
# if __WORDSIZE == 64
# define LONG_MAX 9223372036854775807L
# else
...
Dat is 19 pos + teken voor een 64bits int, als ik goed geteld hebt.
Samenvattend:
* (over)Alloceren op de stack ("auto") kost vrijwel niks. (je moet het
natuurlijk niet in ieder functie doen, en dan duizenden lagen diep.
* voor strings is "%20s" nodig om maximaal 20 chars af te beelden.
* voor ints (en floats, in mindere mate) ligt het maximaal benodigde
min-of-meer vast.
* Als levensverzekering zijn vsprintf(), en vsnprintf() uiterst
bruikbaar. Problematisch is wel dat ze nog steeds niet op alle
platformen beschikbaar zijn. (meestal zijn ze er wel, ergens diep
in het hart van de library, maar alleen niet publiek zichtbaar)
HTH,
AvK
Re: Printf: vaste lengte strings en ints?
Author: John Bokma
Date: Wed, 02 Mar 2005 15:00
Date: Wed, 02 Mar 2005 15:00
61 lines
2951 bytes
2951 bytes
moi wrote:
> Dr.Ruud wrote:
>> Wat Aquila schreef, bleek het
>> begin van iets moois; kijk zelf maar:
>>
>>
>>>In een stukje logging code gebruik ik volgend commando:
>>>sprintf(buffer, "%s %.9f _%i_ --- %i %i ------- [%i:%i] (%s) %s",
>>>event, timeval2double(now), id, pid, length, nid, dst_i, message,
>>>additional)
>>
>>
>
>>>[...]
>>>Kan %i een maximum lengte opleggen zonder daarvoor extra nullen te
>>>printen? In beide gevallen mag er afgekapt worden, ik wil gewoon
>>>beveiligingsfouten vermijden.
>>
>>
>> Nee, maar je zou wel kunnen casten, bijvoorbeeld
>> (int32) id
>> want op die manier weet je dat %i maximaal 10 tekens kan opleveren,
>> zelfs als later 'id' een 64-bits integer zou worden.
>>
>
> Is wel erg paranoide, IMO, om rekening te houden met andere sizes.
Nee, zeer zeker niet.
> En onsmakelijk om daar een cast voor te gebruiken.
> Een int is een int. een "%d" of "%i" verwijst naar een int in de
> arglist, ongeacht zijn/haar sizeof.
>
> Het eenvoudigst, IMHO is om de buffer gewoon groot genoeg te maken:
Tja, en dat is? Het duidelijkste is om de afmeting van de buffer te
baseren op de maximaal mogelijke afmeting.
> Dat is 19 pos + teken voor een 64bits int, als ik goed geteld hebt.
Te veel bugs zijn van de "als ik goed" vorm :-(
> Samenvattend:
> * (over)Alloceren op de stack ("auto") kost vrijwel niks. (je moet het
> natuurlijk niet in ieder functie doen, en dan duizenden lagen
> diep.
> * voor strings is "%20s" nodig om maximaal 20 chars af te beelden.
Wat gebeurd er als ik een string van 30 tekens heb?
> * voor ints (en floats, in mindere mate) ligt het maximaal benodigde
> min-of-meer vast.
Nee: het ligt vast vzviw.
--
John Bokma
Voorbeeldscripts in Perl: http://johnbokma.com/perl/
Ervaren Perl / Java programmeur beschikbaar: http://castleamber.com/
Tevreden opdrachtgevers: http://castleamber.com/testimonials.html
Re: Printf: vaste lengte strings en ints?
Author: moi
Date: Wed, 02 Mar 2005 15:59
Date: Wed, 02 Mar 2005 15:59
71 lines
3209 bytes
3209 bytes
John Bokma wrote:
> moi wrote:
>
>
>>Dr.Ruud wrote:
>>
>
>>>
>>>Nee, maar je zou wel kunnen casten, bijvoorbeeld
>>> (int32) id
>>>want op die manier weet je dat %i maximaal 10 tekens kan opleveren,
>>>zelfs als later 'id' een 64-bits integer zou worden.
>>>
>>
>>Is wel erg paranoide, IMO, om rekening te houden met andere sizes.
>
>
> Nee, zeer zeker niet.
Ben ik met je eens, maar wordt hier IMO op de verkeerde plaats
geintroduceerd.
>
>
>>En onsmakelijk om daar een cast voor te gebruiken.
>>Een int is een int. een "%d" of "%i" verwijst naar een int in de
>>arglist, ongeacht zijn/haar sizeof.
>>
>>Het eenvoudigst, IMHO is om de buffer gewoon groot genoeg te maken:
>
>
> Tja, en dat is? Het duidelijkste is om de afmeting van de buffer te
> baseren op de maximaal mogelijke afmeting.
>
Volgens mij bedoelen we hetzelfde.
Was al correct berekend, ergens: 10+1 voor 32bits, en 19+1 voor 64bits ints.
>>Dat is 19 pos + teken voor een 64bits int, als ik goed geteld hebt.
>
>
> Te veel bugs zijn van de "als ik goed" vorm :-(
>
>
>>Samenvattend:
>>* (over)Alloceren op de stack ("auto") kost vrijwel niks. (je moet het
>> natuurlijk niet in ieder functie doen, en dan duizenden lagen
>> diep.
>>* voor strings is "%20s" nodig om maximaal 20 chars af te beelden.
>
>
> Wat gebeurd er als ik een string van 30 tekens heb?
>
>
Dan wort ie afgekapd. (althans: niet geprind ;-)
>>* voor ints (en floats, in mindere mate) ligt het maximaal benodigde
>> min-of-meer vast.
>
>
> Nee: het ligt vast vzviw.
>
Sorry voor slag-om-de-arm.
is vzvik ook een "als ik goed" vorm ;-?
AvK
Re: Printf: vaste lengte strings en ints?
Author: John Bokma
Date: Wed, 02 Mar 2005 16:29
Date: Wed, 02 Mar 2005 16:29
41 lines
2194 bytes
2194 bytes
moi wrote:
> John Bokma wrote:
>>>* voor strings is "%20s" nodig om maximaal 20 chars af te beelden.
>>
>> Wat gebeurd er als ik een string van 30 tekens heb?
>
> Dan wort ie afgekapd. (althans: niet geprind ;-)
Ik heb al een tijd geen C gedaan, maar ik weet vrij zeker dat er gewoon
30 tekens worden geprint. Perl gebruikt de C format syntax en:
perl -e "print length( sprintf qq(%20s), 'x' x 30)"
Geeft 30 hier.
En
perl -e "printf( qw(%1s), 'hello, world')"
de klassieker.
>>>* voor ints (en floats, in mindere mate) ligt het maximaal benodigde
>>> min-of-meer vast.
>>
>> Nee: het ligt vast vzviw.
>
> Sorry voor slag-om-de-arm.
>
> is vzvik ook een "als ik goed" vorm ;-?
Nee, ik ben een hele tijd uit C, maar als ik zoiets zou moeten
implementeren zou ik of de documentatie er op na lezen, of wellicht even
kijken hoe dit soort zaken in Perl opgelost zijn.
--
John Bokma
Voorbeeldscripts in Perl: http://johnbokma.com/perl/
Ervaren Perl / Java programmeur beschikbaar: http://castleamber.com/
Tevreden opdrachtgevers: http://castleamber.com/testimonials.html
Re: Printf: vaste lengte strings en ints?
Author: moi
Date: Wed, 02 Mar 2005 16:52
Date: Wed, 02 Mar 2005 16:52
49 lines
2753 bytes
2753 bytes
John Bokma wrote: > moi wrote: > > >>John Bokma wrote: > > >>>>* voor strings is "%20s" nodig om maximaal 20 chars af te beelden. >>> >>>Wat gebeurd er als ik een string van 30 tekens heb? >> >>Dan wort ie afgekapd. (althans: niet geprind ;-) > > > Ik heb al een tijd geen C gedaan, maar ik weet vrij zeker dat er gewoon > 30 tekens worden geprint. Perl gebruikt de C format syntax en: > > perl -e "print length( sprintf qq(%20s), 'x' x 30)" > > Geeft 30 hier. > > En > > perl -e "printf( qw(%1s), 'hello, world')" > > de klassieker. > > >>>>* voor ints (en floats, in mindere mate) ligt het maximaal benodigde >>>> min-of-meer vast. >>> >>>Nee: het ligt vast vzviw. >> >>Sorry voor slag-om-de-arm. >> >>is vzvik ook een "als ik goed" vorm ;-? > > > Nee, ik ben een hele tijd uit C, maar als ik zoiets zou moeten > implementeren zou ik of de documentatie er op na lezen, of wellicht even > kijken hoe dit soort zaken in Perl opgelost zijn. > Je hebt het helemaal goed. t moesd "%s20.20s" zijn. Ik had te oppervlakkig de manpage gelezen. I stand corrected! AvK *gaat zich schamen*
Re: Printf: vaste lengte strings en ints?
Author: Sjoerd A. Schreuder
Date: Wed, 02 Mar 2005 16:54
Date: Wed, 02 Mar 2005 16:54
23 lines
1989 bytes
1989 bytes
John Bokma wrote: > moi wrote: >>John Bokma wrote: >>> moi wrote: >>>>* voor strings is "%20s" nodig om maximaal 20 chars af te beelden. >>> >>>Wat gebeurd er als ik een string van 30 tekens heb? >> >>Dan wort ie afgekapd. (althans: niet geprind ;-) > > Ik heb al een tijd geen C gedaan, maar ik weet vrij zeker dat er gewoon > 30 tekens worden geprint. Klopt. De width is voor strings een minimale breedte. Echter.... De precission is voor strings een maximale breedte. Gebruik dus "%.20s" om maximaal 20 karakters te printen. Of gebruik "%20.20s" om exact 20 karakters te printen. Zie http://www.google.nl/search?q=man+printf(3) Sjoerd
Re: Printf: vaste lengte strings en ints?
Author: Dr.Ruud
Date: Wed, 02 Mar 2005 17:27
Date: Wed, 02 Mar 2005 17:27
75 lines
2985 bytes
2985 bytes
Wat moi schreef, bleek het
begin van iets moois; kijk zelf maar:
> Dr.Ruud:
>> Aquila:
>>> [printf]
>>> Kan %i een maximum lengte opleggen zonder daarvoor extra nullen te
>>> printen? In beide gevallen mag er afgekapt worden, ik wil gewoon
>>> beveiligingsfouten vermijden.
>> Nee, maar je zou wel kunnen casten, bijvoorbeeld
>> (int32) id
>> want op die manier weet je dat %i maximaal 10 tekens kan opleveren,
>> zelfs als later 'id' een 64-bits integer zou worden.
> Is wel erg paranoide, IMO, om rekening te houden met andere sizes.
Het had ons allemaal heel wat exploits kunnen schelen.
> En onsmakelijk om daar een cast voor te gebruiken.
Niet als je je wilt verzekeren.
> Een int is een int. een "%d" of "%i" verwijst naar een int in de
> arglist, ongeacht zijn/haar sizeof.
>
> Het eenvoudigst, IMHO is om de buffer gewoon groot genoeg te maken:
> een geformatteerde 32 bits int vergt 10 char +1 voor het teken.
> <limits.h> vermeldt:
>
> # if __WORDSIZE == 64
> # define LONG_MAX 9223372036854775807L
> # else
> ...
> Dat is 19 pos + teken voor een 64bits int, als ik goed geteld hebt.
Voor een signed int van 8 bits heb je 4 posities nodig,
16 bits: 6 posities
32 bits: 11 posities
64 bits: 20 posities
96 bits: 30 posities
128 bits: 40 posities
en dan steeds per 32 bits er 9 of 10 posities bij.
bits = 8*sizeof(int)
Signed: 1 + INT(1+LOG(2^(bits-1),10))
Unsigned: INT(1+LOG(2^bits,10))
Vanwege 2^10 ~ 10^3 is dit ook zo te benaderen:
Signed: 2 + (39 * sizeof(int)) >> 4
Unsigned: 1 + (39 * sizeof(int)) >> 4
Iets grover kan ook:
Signed: (3 + 5 * sizeof(int)) >> 1
Unnsigned: (1 + 5 * sizeof(int)) >> 1
Dus misschien zoiets:
#define INT2POS(pType) ((int)(2+(39*sizeof(pType))>>4))
--
Affijn, Ruud ` - �
+ ` � *
� ` Jvr qvg yrrfg,
� = ` fgresg wbatre.
Re: Printf: vaste lengte strings en ints?
Author: Sjoerd A. Schreuder
Date: Wed, 02 Mar 2005 17:59
Date: Wed, 02 Mar 2005 17:59
27 lines
2068 bytes
2068 bytes
Dr.Ruud wrote: [knip] > Voor een signed int van 8 bits heb je 4 posities nodig, > 16 bits: 6 posities > 32 bits: 11 posities > 64 bits: 20 posities > 96 bits: 30 posities > 128 bits: 40 posities > en dan steeds per 32 bits er 9 of 10 posities bij. > > bits = 8*sizeof(int) Iets correcter is: bits = CHAR_BITS * sizeof(int) Al zal de aanname dat CHAR_BITS == 8 niet zoveel platforms uitsluiten. Misschien dat ooit er een compiler komt waarbij CHAR_BITS==32, maar er is zoveel code afhankelijk van de aanname dat CHAR_BITS==8 dat ik niet verwacht dat zo'n compiler ooit commercieel succesvol zal zijn. Dus deze bijdrage is vooral van theoretisch belang. [knip: afleiding leuke formules] Sjoerd
Re: Printf: vaste lengte strings en ints?
Author: Dr.Ruud
Date: Wed, 02 Mar 2005 18:46
Date: Wed, 02 Mar 2005 18:46
27 lines
1881 bytes
1881 bytes
Wat Sjoerd A. Schreuder schreef, bleek het
begin van iets moois; kijk zelf maar:
> Dr.Ruud:
>> bits = 8*sizeof(int)
> Iets correcter is:
> bits = CHAR_BITS * sizeof(int)
Dank voor deze aanvulling.
Ik twijfel nog wel, het zou namelijk ook zo kunnen zijn
dat sizeof() altijd in eenheden van 8 bits telt.
Even nazoeken...
"For the TMS320F24x, sizeof(char) = sizeof(int) = 1,
with both being 16-bit."
Dus daar moet CHAR_BITS wel 16 zijn. Ook al omdat een
int altijd minimaal 16 bits is. Je aanvulling is dus
inderdaad nodig.
--
Affijn, Ruud ` - �
+ ` � *
� ` Jvr qvg yrrfg,
� = ` fgresg wbatre.
Re: Printf: vaste lengte strings en ints?
Author: moi
Date: Wed, 02 Mar 2005 20:33
Date: Wed, 02 Mar 2005 20:33
39 lines
2640 bytes
2640 bytes
Dr.Ruud wrote: > Wat Sjoerd A. Schreuder schreef, bleek het > begin van iets moois; kijk zelf maar: > >>Dr.Ruud: > > >>>bits = 8*sizeof(int) > > >>Iets correcter is: >> bits = CHAR_BITS * sizeof(int) > > > Dank voor deze aanvulling. > > Ik twijfel nog wel, het zou namelijk ook zo kunnen zijn > dat sizeof() altijd in eenheden van 8 bits telt. > Even nazoeken... > > "For the TMS320F24x, sizeof(char) = sizeof(int) = 1, > with both being 16-bit." > > Dus daar moet CHAR_BITS wel 16 zijn. Ook al omdat een > int altijd minimaal 16 bits is. Je aanvulling is dus > inderdaad nodig. > Sizeof telt in char's, als je het zo wilt uitdrukken. DWZ, de kleinste adresseerbare eenheid is een char. Hoeveel bits er in die char zitten is niet vastgelegd, behalve dan "genoeg om de karakterset te representeren". [ eea is waarschijnlijk een vorm van politieke correctheid geweest jegens de EBDIC - jongens, en andere zeldzame diersoorten ... ] Nou, nu we toch aan het fijnslijpen zijn: de #define heet CHAR_BIT. AvK
Re: Printf: vaste lengte strings en ints?
Author: moi
Date: Wed, 02 Mar 2005 21:08
Date: Wed, 02 Mar 2005 21:08
128 lines
4966 bytes
4966 bytes
Dr.Ruud wrote: > Wat moi schreef, bleek het > begin van iets moois; kijk zelf maar: > >>Dr.Ruud: >> >>>Aquila: > > >>>>[printf] >>>>Kan %i een maximum lengte opleggen zonder daarvoor extra nullen te >>>>printen? In beide gevallen mag er afgekapt worden, ik wil gewoon >>>>beveiligingsfouten vermijden. > > >>>Nee, maar je zou wel kunnen casten, bijvoorbeeld >>> (int32) id >>>want op die manier weet je dat %i maximaal 10 tekens kan opleveren, >>>zelfs als later 'id' een 64-bits integer zou worden. > > >>Is wel erg paranoide, IMO, om rekening te houden met andere sizes. > > > Het had ons allemaal heel wat exploits kunnen schelen. > > Exploits wegens 32->64 bits "migratie" ? > >>En onsmakelijk om daar een cast voor te gebruiken. > > > Niet als je je wilt verzekeren. > Is een kwestie van smaak/stijl. Ik hou niet van casts. probeer ze tot het uiterste te minimaliseren. In dit geval zou ik zeker geen cast willen. Dit is trouwens ook een "value cast" (mijn terminologie): behalve het type, wordt (mogelijk) *ook de waarde* van de expressie zerfetzt. Zo zou het kunnen, dat als je een 64 bit int aanbiedt aan de printf() call, er bits verdwijnen. (eenzelfde soort cast was was vroegah nodig om een size_t te printen met een %u format) eea komt dus neer op de vraag wat je wilt: een programma dat (mogelijkerwijs) crasht, of een programma dat verkeerde getallen print, zodra ze niet meer in 32 bits passen. (en het opeens hercompileerbaar bleek op een machine waarop de int groter dan 32 bits was) In beide gevallen kom je er wel achter, trouwens. > > >>Een int is een int. een "%d" of "%i" verwijst naar een int in de >>arglist, ongeacht zijn/haar sizeof. >> >>Het eenvoudigst, IMHO is om de buffer gewoon groot genoeg te maken: >>een geformatteerde 32 bits int vergt 10 char +1 voor het teken. >><limits.h> vermeldt: >> >># if __WORDSIZE == 64 >># define LONG_MAX 9223372036854775807L >># else >>... >>Dat is 19 pos + teken voor een 64bits int, als ik goed geteld hebt. > > > Voor een signed int van 8 bits heb je 4 posities nodig, > 16 bits: 6 posities > 32 bits: 11 posities > 64 bits: 20 posities > 96 bits: 30 posities > 128 bits: 40 posities > en dan steeds per 32 bits er 9 of 10 posities bij. > > bits = 8*sizeof(int) > > Signed: 1 + INT(1+LOG(2^(bits-1),10)) > > Unsigned: INT(1+LOG(2^bits,10)) > > > Vanwege 2^10 ~ 10^3 is dit ook zo te benaderen: > > Signed: 2 + (39 * sizeof(int)) >> 4 > > Unsigned: 1 + (39 * sizeof(int)) >> 4 > > > Iets grover kan ook: > Signed: (3 + 5 * sizeof(int)) >> 1 > Unnsigned: (1 + 5 * sizeof(int)) >> 1 > > > Dus misschien zoiets: > > #define INT2POS(pType) ((int)(2+(39*sizeof(pType))>>4)) > > Nou, dat is briljant. Ik denk alleen niet dat de code er leesbaarder van wordt. (trouwens: uitstekend voor gegenereerde code). Ik denk dat: char buff[ 30+ 3 *INT2POS(int) + 2 * FLOAT2POS(double) +1]; sprintf(buff, "%d %d : %d : dubbele vlootjes: [%lf %lf %lf %lf]\n" ,a,b,c, f1,f2,f3,f4); ... een veel lastiger soort probleem kan veroorzaken dan char buff[512] ; printf(buff, "%d %d : %d : dubbele vlootjes: [%lf %lf %lf %lf]\n" ,a,b,c, f1,f2,f3,f4); En, nogmaals: als je het echt zeker wilt weten, is vsnprintf() je vriendje. (er zit een mooie in de de apache-source, mocht je hem missen. is wel HEEL GROOT) AvK
Re: Printf: vaste lengte strings en ints?
Author: Dr.Ruud
Date: Wed, 02 Mar 2005 22:20
Date: Wed, 02 Mar 2005 22:20
50 lines
2807 bytes
2807 bytes
Wat moi schreef, bleek het
begin van iets moois; kijk zelf maar:
> Dr.Ruud:
>> moi:
>>> Dr.Ruud:
>>>> Aquila:
>>>>> [printf]
>>>>> Kan %i een maximum lengte opleggen zonder daarvoor extra nullen te
>>>>> printen? In beide gevallen mag er afgekapt worden, ik wil gewoon
>>>>> beveiligingsfouten vermijden.
>>>> Nee, maar je zou wel kunnen casten, bijvoorbeeld
>>>> (int32) id
>>>> want op die manier weet je dat %i maximaal 10 >>> nee, 11 <<<
>>>> tekens kan opleveren, zelfs als later 'id' een 64-bits integer
>>>> zou worden.
>>> Is wel erg paranoide, IMO, om rekening te houden met andere sizes.
>> Het had ons allemaal heel wat exploits kunnen schelen.
> Exploits wegens 32->64 bits "migratie" ?
Er waren ooit al andere problemen, zoals
printf("value of 32768 is %d\n", 32768);
> Ik hou niet van casts.
> probeer ze tot het uiterste te minimaliseren.
> In dit geval zou ik zeker geen cast willen.
OK, maar OP vroeg om een oplossing bij %d, en er mocht afgekapt worden.
Er zijn, zoals gemeld, genoeg manieren om de buffer lang genoeg te laten
zijn, dus dan heb je die cast helemaal niet nodig, en hoef/mag/moet je
'm dus ook niet gebruiken.
En printf() is meer iets van de vorige eeuw. Die slechte relatie
tussen wat er op de stack wordt gezet (de argumenten) en wat er
weer wordt afgehaald (afhankelijk van de tekst die in de format-
string staat) gaat tegen alle elegantie in. Zelfs late-binding
is minder onfris.
--
Affijn, Ruud ` - �
+ ` � *
� ` Jvr qvg yrrfg,
� = ` fgresg wbatre.
Re: Printf: vaste lengte strings en ints?
Author: Dr.Ruud
Date: Wed, 02 Mar 2005 22:31
Date: Wed, 02 Mar 2005 22:31
44 lines
2376 bytes
2376 bytes
Wat moi schreef, bleek het
begin van iets moois; kijk zelf maar:
> Ik denk dat:
>
> char buff[ 30+ 3 *INT2POS(int) + 2 * FLOAT2POS(double) +1];
> sprintf(buff, "%d %d : %d : dubbele vlootjes: [%lf %lf %lf %lf]\n"
> ,a,b,c, f1,f2,f3,f4);
>
> ... een veel lastiger soort probleem kan veroorzaken dan
>
> char buff[512] ;
> printf(buff, "%d %d : %d : dubbele vlootjes: [%lf %lf %lf %lf]\n"
> ,a,b,c, f1,f2,f3,f4);
Bedoel je die '2 *' terwijl je 4 long floats wilt weergeven?
Of die 30 die >=32 moet zijn?
Een FLOAT2POS is trouwens wat lastiger te maken.
Ik heb de preciese syntax niet gecontroleerd, maar zoiets kan dacht ik
ook:
const char fmt = "%d %d : %d : dubbele vlootjes: [%lf %lf %lf %lf]\n";
char buff[ sizeof(fmt[]) + 3 * INT2POS(int) + 4 * FLOAT2POS(double)
+1];
sprintf(buff, fmt, a,b,c, f1,f2,f3,f4);
Ik denk dat het '%Lf' is en de 'l' alleen voor integer-formats mag
staan.
Of %lf is double, en %Lf long double, dat kan ook nog.
> En, nogmaals: als je het echt zeker wilt weten, is vsnprintf() je
> vriendje.
Ja, dat is beter.
--
Affijn, Ruud ` - �
+ ` � *
� ` Jvr qvg yrrfg,
� = ` fgresg wbatre.
Re: Printf: vaste lengte strings en ints?
Author: moi
Date: Wed, 02 Mar 2005 23:21
Date: Wed, 02 Mar 2005 23:21
56 lines
3563 bytes
3563 bytes
Dr.Ruud wrote:
> Wat moi schreef, bleek het
> begin van iets moois; kijk zelf maar:
>
>>Dr.Ruud:
>>
>
>>>Het had ons allemaal heel wat exploits kunnen schelen.
>
>
>>Exploits wegens 32->64 bits "migratie" ?
>
>
> Er waren ooit al andere problemen, zoals
> printf("value of 32768 is %d\n", 32768);
>
Je bedoelt: op een platform waar een int 16 bits is ?
(trouwens ook hier bewijst casten naar int zijn zinloosheid)
BTW speelt nog wat anders mee: "silent promotion to int" van
functieargumenten.
> OK, maar OP vroeg om een oplossing bij %d, en er mocht afgekapt worden.
>
Ja, maar we zijn nu toch al bijna off-topic.
> Er zijn, zoals gemeld, genoeg manieren om de buffer lang genoeg te laten
> zijn, dus dan heb je die cast helemaal niet nodig, en hoef/mag/moet je
> 'm dus ook niet gebruiken.
>
> En printf() is meer iets van de vorige eeuw. Die slechte relatie
> tussen wat er op de stack wordt gezet (de argumenten) en wat er
> weer wordt afgehaald (afhankelijk van de tekst die in de format-
> string staat) gaat tegen alle elegantie in. Zelfs late-binding
> is minder onfris.
>
Het is idd een vunzige functie. (en hij wordt er niet mooier op)
Heel lastig, hoe de mapping van binaire naar humaan-leesbare
reprensentatie in een formaat-string wordt samengeperst, en tussen de
bedrijven door ook nog even assumpties over types en sizes worden
gedaan. Aan de andere kant is het weer prakties om alles in een
compacte representatie (de formatstring) te hebben. Jammer alleen, dat
die toch wel een beetje samenhangt met de de functie-argumenten.
Als het goed is, dan. Trouwens: de hele varargs construktie is, in al
zijn lelijkheid, uiterst gewenst.
Dat fprintf() cs van de vorige eeuw zijn, zou ik niet willen zeggen.
(kwa ontstaansdatum wel, uiteraard ...)
De functionaliteit blijft toch nodig; bij een grondige redesign zouden
er ook weer keuzes gemaakt worden. Die later weer verkeerd kunnen uitpakken.
AvK
Re: Printf: vaste lengte strings en ints?
Author: moi
Date: Wed, 02 Mar 2005 23:37
Date: Wed, 02 Mar 2005 23:37
78 lines
3730 bytes
3730 bytes
Dr.Ruud wrote:
> Wat moi schreef, bleek het
> begin van iets moois; kijk zelf maar:
>
>
>>Ik denk dat:
>>
>>char buff[ 30+ 3 *INT2POS(int) + 2 * FLOAT2POS(double) +1];
>>sprintf(buff, "%d %d : %d : dubbele vlootjes: [%lf %lf %lf %lf]\n"
>> ,a,b,c, f1,f2,f3,f4);
>>
>>... een veel lastiger soort probleem kan veroorzaken dan
>>
>>char buff[512] ;
>>printf(buff, "%d %d : %d : dubbele vlootjes: [%lf %lf %lf %lf]\n"
>> ,a,b,c, f1,f2,f3,f4);
>
>
> Bedoel je die '2 *' terwijl je 4 long floats wilt weergeven?
> Of die 30 die >=32 moet zijn?
Precies. Vergelijkbaar met het checken van een formatstring is het
checken van de macroargumenten. Alleen lastiger ...
> Een FLOAT2POS is trouwens wat lastiger te maken.
Draadje kan erg lang worden ...
>
> Ik heb de preciese syntax niet gecontroleerd, maar zoiets kan dacht ik
> ook:
>
> const char fmt = "%d %d : %d : dubbele vlootjes: [%lf %lf %lf %lf]\n";
*--------------^
> char buff[ sizeof(fmt[]) + 3 * INT2POS(int) + 4 * FLOAT2POS(double)
> +1];
> sprintf(buff, fmt, a,b,c, f1,f2,f3,f4);
>
Precies. In prototype is het "const char * fmt". en een stringconstante
is daar een goede kandidaat voor.
>
> Ik denk dat het '%Lf' is en de 'l' alleen voor integer-formats mag
> staan.
> Of %lf is double, en %Lf long double, dat kan ook nog.
>
Toch maar even nagezocht:
f,F The double argument is rounded and converted to decimal
notation
in the style [-]ddd.ddd, where the number of digits
after the
decimal-point character is equal to the precision
specification.
If the precision is missing, it is taken as 6; if the
precision
is explicitly zero, no decimal-point character appears.
If a
decimal point appears, at least one digit appears before it.
Default promotie float->double, dus.
De 'l' modifyer blijkt geen betekenis te hebben voor %f ...
Weer wat geleerd.
>
>
>>En, nogmaals: als je het echt zeker wilt weten, is vsnprintf() je
>>vriendje.
>
>
> Ja, dat is beter.
>
Zijn we het eens.
AvK
Re: Printf: vaste lengte strings en ints?
Author: Sjoerd A. Schreuder
Date: Thu, 03 Mar 2005 00:14
Date: Thu, 03 Mar 2005 00:14
14 lines
1694 bytes
1694 bytes
moi wrote: > Dr.Ruud wrote: >> Wat Sjoerd A. Schreuder schreef, bleek het >> begin van iets moois; kijk zelf maar: >>> Dr.Ruud: >>>> bits = 8*sizeof(int) >>> Iets correcter is: >>> bits = CHAR_BITS * sizeof(int) > > Nou, nu we toch aan het fijnslijpen zijn: de #define heet CHAR_BIT. Je hebt gelijk; Dank voor de correctie! Sjoerd
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads