Parsing integers in C

In the standard libc API set there are multiple functions provided that do ASCII numbers to integer conversions.

They are handy and easy to use, but also error-prone and quite lenient in what they accept and silently just swallow.

atoi

atoi() is perhaps the most common and basic one. It converts from a string to signed integer. There is also the companion atol() which instead converts to a long.

Some problems these have include that they return 0 instead of an error, that they have no checks for under or overflow and in the atol() case there’s this challenge that long has different sizes on different platforms. So neither of them can reliably be used for 64-bit numbers. They also don’t say where the number ended.

Using these functions opens up your parser to not detect and handle errors or weird input. We write better and stricter parser when we avoid these functions.

strtol

This function, along with its siblings strtoul() and strtoll() etc, is more capable. They have overflow detection and they can detect errors – like if there is no digit at all to parse.

However, these functions as well too happily swallow leading whitespace and they allow a + or – in front of the number. The long versions of these functions have the problem that long is not universally 64-bit and the long long version has the problem that it is not universally available.

The overflow and underflow detection with these function is quite quirky, involves errno and forces us to spend multiple extra lines of conditions on every invoke just to be sure we catch those.

curl code

I think we in the curl project as well as more or less the entire world has learned through the years that it is usually better to be strict when parsing protocols and data, rather than be lenient and try to accept many things and guess what it otherwise maybe meant.

As a direct result of this we make sure that curl parses and interprets data exactly as that data is meant to look and we error out as soon as we detect the data to be wrong. For security and for solid functionality, providing syntactically incorrect data is not accepted.

This also implies that all number parsing has to be exact, handle overflows and maximum allowed values correctly and conveniently and errors must be detected. It always supports up to 64-bit numbers.

strparse

I have previously blogged about how we have implemented our own set of parsing function in curl, and these also include number parsing.

curlx_str_number() is the most commonly used of the ones we have created. It parses a string and stores the value in a 64-bit variable (which in curl code is always present and always 64-bit). It also has a max value argument so that it returns error if too large. And it of course also errors out on overflows etc.

This function of ours does not allow any leading whitespace and certainly no prefixing pluses or minuses. If they should be allowed, the surrounding parsing code needs to explicitly allow them.

The curlx_str_number function is most probably a little slower that the functions it replaces, but I don’t think the difference is huge and the convenience and the added strictness is much welcomed. We write better code and parsers this way. More secure. (curlx_str number source code)

History

As of yesterday, November 12 2025 all of those weak functions calls have been wiped out from the curl source code. The drop seen in early 2025 was when we got rid of all strtrol() variations. Yesterday we finally got rid of the last atoi() calls.

(Daily updated version of the graph.)

curlx

The function mentioned above uses a ‘curlx’ prefix. We use this prefix in curl code for functions that exist in libcurl source code but that be used by the curl tool as well – sharing the same code without them being offered by the libcurl API.

A thing we do to reduce code duplication and share code between the library and the command line tool.

curl 8.17.0

Download curl from curl.se.

Release presentation

Numbers

the 271st release
11 changes
56 days (total: 10,092)
448 bugfixes (total: 12,537)
699 commits (total: 36,725)
2 new public libcurl function (total: 100)
0 new curl_easy_setopt() option (total: 308)
1 new curl command line option (total: 273)
69 contributors, 35 new (total: 3,534)
22 authors, 5 new (total: 1,415)
1 security fixes (total: 170)

Security

CVE-2025-10966: missing SFTP host verification with wolfSSH. curl’s code for managing SSH connections when SFTP was done using the wolfSSH powered backend was flawed and missed host verification mechanisms.

Changes

We drop support for several things this time around:

  • drop Heimdal support
  • drop the winbuild build system
  • drop support for Kerberos FTP
  • drop support for wolfSSH

And then we did some other smaller changes:

  • up the minimum libssh2 requirement to 1.9.0
  • add a notifications API to the multi interface
  • expand to use 6 characters per size in the progress meter
  • support Apple SecTrust – use the native CA store
  • add --knownhosts to the command line tool
  • wcurl: import v2025.11.04
  • write-out: make %header{} able to output all occurrences of a header

Bugfixes

We set a new project record this time with no less than 448 documented bugfixes since the previous release.

The release presentation mentioned above discusses some of the perhaps most significant ones.

Coming next

There a small set of pull-requests waiting to get merged, but other than that our future is not set and we greatly appreciate your feedback, submitted issues and provided pull-requests to guide us.

If this release happens to include an annoying regression, there might be a patch release already next week. If we are lucky and it doesn’t, then we aim for a 8.18.0 release in the early January 2026.

Yes really, curl is still developed

A lot!

One of the most common reactions or questions I get about curl when I show up at conferences somewhere and do presentations:

is curl still being actively developed?

How many more protocols can there be? This of course being asked by people without very close proximity or insight into the curl project and probably neither into the internet protocol world – which frankly probably is most of the civilized world. Still, these questions keep surprising me. Can projects actually ever get done?

(And do people really believe that adding protocols is the only thing that is left to do?)

Everything changes

There are new car models being made every year in spite of the roads being mostly the same for the last decades and there are new browser versions shipped every few weeks even though the web to most casual observers look roughly the same now as it did a few years ago. Etc etc. Even things such as shoes or bicycles are developed and shipped in new versions every year.

In spite of how it may appear to casual distant observers, very few things remain the same over time in this world. This certainly is also true for internet, the web and how to do data transfers over them. Just five years ago we did internet transfers differently than how we (want to) do them today. New tweaks and proposals are brought up at least on a monthly basis.

Not evolving implies stagnation and eventually… death.

As standards, browsers and users update their expectations, curl does as well. curl needs to adapt and keep up to stay relevant. We want to keep improving it so that it can match and go beyond what people want from it. We want to help drive and push internet transfer technologies to help users to do better, more efficient and more secure operations. We like carrying the world’s infrastructure on our shoulders.

It might evolve for decades to come

One of the things that actually have occurred to me, after having worked on this project for some decades by now – and this is something I did not at all consider in the past, is that there is a chance that the project will remain alive and in use the next few decades as well. Because of exactly this nothing-ever-stops characteristic of the world around us, but also of course because of the existing amount of users and usage.

Current development should be done with care, a sense of responsibility and with the anticipation that we will carry everything we merge today with us for several more decades – at least. At the latest curl up meeting, I had session I called 100 year curl where I brought up thoughts for us as a project that we might need to work on and keep in mind if indeed we believe the curl project will and should be able to celebrate its 100th birthday in a future. It is a slightly overwhelming (terrifying even?) thought but in my opinion not entirely unrealistic. And when you think about it, we have already traveled almost 30% of the way towards that goalpost.

But it looks the same

— I used curl the first time decades ago and it still looks the same.

This is a common follow-up statement. What have we actually done during all this time that the users can’t spot?

A related question that to me also is a little amusing is then:

— You say you worked on curl full time since 2019, but what do you actually do all days?

We work hard at maintaining backwards compatibility and not breaking existing use cases. If you cannot spot any changes and your command lines just keep working, it confirms that we do things right. curl is meant to do its job and stay out of the way. To mostly be boring. A dull stack is a good stack.

We have refactored and rearranged the internal architecture of curl and libcurl several times in the past and we keep doing it at regular intervals as we improve and adapt to new concepts, new ideas and the ever-evolving world. But we never let that impact the API, the ABI or by breaking any previously working curl tool command lines.

I personally think that this is curl’s secret super power. The one thing we truly have accomplished and managed to stick to: stability. In several aspects of the word.

curl offers stability in an unstable world.

Now more than ever

Counting commit frequency or any other metric of project activity, the curl project is actually doing more development now and at a higher pace than ever before during its entire lifetime.

We do this to offer you and everyone else the best, the most reliable, the fastest, the most feature rich, the best documented and the most secure internet transfer library on the planet.