Yksi cast voi muuttaa näennäisen tavallisen välityspalvelinasetusten apurin arkkitehtuurista riippuvaksi virheeksi:

current = (IntPtr)((int)current + optionSize);

Tuo koodi kaventaa natiivin osoitteen 32-bittiseksi kokonaisluvuksi ennen seuraavan rakenteen koon lisäämistä. 64-bittinen prosessi voi sisältää osoitteita, jotka eivät mahdu. Muunnoksesta ja arvosta riippuen tulos voi olla ylivuotopoikkeus tai virheellinen osoite. Buildin palauttaminen x86:lle voi piilottaa virheen, mutta jättää interop-toteutuksen tuon kiertotien varaan.

Pidä osoitteet osoittimen kokoisina. Esimerkiksi jo varatun taulukon läpi kulkemiseen voidaan käyttää:

IntPtr item = IntPtr.Add(buffer, checked(index * optionSize));

Siirtymä pysyy kokonaislukuna; itse osoitetta ei puristeta sellaisen läpi. Varauksen koon ja indeksin on silti oltava kelvollisia.

Tarkastele sitten ympäröiviä määrittelyjä

WinINetin yhteyksittäiset asetukset sisältävät unionin, jonka jäseniä ovat DWORD, merkkijono-osoitin ja FILETIME. Osoitinkentät tarvitsevat IntPtr; DWORD-kentät pysyvät 32-bittisinä. Natiivi kohdistus on tärkeää, joten jokaisen kokonaisluvun korvaaminen 64-bittisellä kokonaisluvulla tai pakotetun pakatun asettelun käyttö ei ole kestävä korjaus.

Käytä taulukkoa läpikäydessäsi marshalingin jälkeistä rakenteen kokoa, sovita ANSI- tai Unicode-määrittely johdonmukaisesti ja seuraa jokaista varausta erikseen. Asetusrakenteiden lohkon vapauttaminen ei vapauta automaattisesti muualla varattuja merkkijonoja, joihin nuo rakenteet viittaavat.

Lopuksi pidä asetusten laajuuskysymys erillään muistin oikeellisuudesta. Castin korjaaminen ei todista, että apurin valitsema WinINet-asetus vaikuttaisi vain yhteen säätimeen, yhteen prosessiin tai nykyisen käyttäjän asetuksiin. Tarkista tuo API-käyttäytyminen ennen vanhan esimerkin muun osan omaksumista. Jos se lähettää myös päivitysilmoituksia, valitse ne aiottuun laajuuteen.

Aiheeseen liittyvät artikkelit