🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: be.comp.programming
Article #1506

Re: Printf: vaste lengte strings en ints?

#1506
From: moi
Date: Wed, 02 Mar 2005 21:08
128 lines
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
Technical Details
Message-ID: <FMSdnW58LdbOtrvfRVnyvQ@casema.nl>
Path: arc1-ca.pugleaf.net!g2news1.google.com!news4.google.com!news.glorb.com!border1.nntp.dca.giganews.com!nntp.giganews.com!local01.nntp.dca.giganews.com!nntp.casema.nl!news.casema.nl.POSTED!not-for-mail
References: <M5qdnYvpZutbs7nfRVnyjA@scarlet.biz> <d01i4u.14c.1@news.isolution.nl> <CqudnXnc_MjnCbjfRVnyhg@casema.nl> <d050po.130.1@news.isolution.nl>

Show Full Headers
Complete Article Headers
X-Google-Thread: fcea4,f962124bbb04ff22
X-Google-Thread: 107324,f962124bbb04ff22
X-Google-Attributes: gidfcea4,gid107324,public
X-Google-Language: DUTCH,ASCII-7-bit
Path: arc1-ca.pugleaf.net!g2news1.google.com!news4.google.com!news.glorb.com!border1.nntp.dca.giganews.com!nntp.giganews.com!local01.nntp.dca.giganews.com!nntp.casema.nl!news.casema.nl.POSTED!not-for-mail
NNTP-Posting-Date: Wed, 02 Mar 2005 15:08:35 -0600
Date: Wed, 02 Mar 2005 22:08:35 +0100
From: moi <avk@localhost>
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040510
X-Accept-Language: en-us, en
MIME-Version: 1.0
Newsgroups: be.comp.programming,nl.comp.programmeren
Subject: Re: Printf: vaste lengte strings en ints?
References: <M5qdnYvpZutbs7nfRVnyjA@scarlet.biz> <d01i4u.14c.1@news.isolution.nl> <CqudnXnc_MjnCbjfRVnyhg@casema.nl> <d050po.130.1@news.isolution.nl>
In-Reply-To: <d050po.130.1@news.isolution.nl>
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
Message-ID: <FMSdnW58LdbOtrvfRVnyvQ@casema.nl>
Lines: 128
NNTP-Posting-Host: 83.83.6.100
X-Trace: sv3-P8lqw5ng19K1dn6XA9O5gPMPsPPXhQMDxUazE42DdRDHWbUdF967lW9PombcqM+tZwfY2vNki4RIPgs!wb+xghTD9fD4AGHWGQlyws4SeaP1WtDhieZTrqc379Z5h7b5LdCv4N2A41cG0bS8iDI=
X-Complaints-To: abuse@casema.nl
X-DMCA-Complaints-To: abuse@casema.nl
X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers
X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly
X-Postfilter: 1.3.32