From nobody Mon Feb 9 01:44:21 2026 Received: from mail-wr1-f53.google.com (mail-wr1-f53.google.com [209.85.221.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C103031D725 for ; Tue, 3 Feb 2026 10:30:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770114614; cv=none; b=uqTqyKCYiygbxB8XfL8vuYNQ1VxJeYW0YSz2ZQTnWS7m190HBMB0XSc7DJkj4x3pEI/LwvYurPwiHlC+uudzoUx4mYihrVQcD/0ry2+Yj2DSh9QtEZIAQrdd5e79zuByxadRU8v8FUZm2I8EdgBhhxqvFzC3aroGU+/b2r3cR3c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770114614; c=relaxed/simple; bh=GnI0GY9dJ2+EEzk58xOtNj1SDKqcRI+2curOvTuH8eY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ddR+O1D2KzTxXMc2TeDp2zmE1Lu+w83KJd2TnmMfbi8vd3rjW75MNGm1p+ByjV6d9FN8DuVfayYkVVytCBd9XPf/F5U/fvGARglznOP/UKBIFNeiyU9JfQep9iVy5+K35nh0iiySwxAM2PEeM0w/B9Fq+U/8iu/ZU46P9CsldFk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=NwKoqPvS; arc=none smtp.client-ip=209.85.221.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="NwKoqPvS" Received: by mail-wr1-f53.google.com with SMTP id ffacd0b85a97d-432d2c96215so5177742f8f.3 for ; Tue, 03 Feb 2026 02:30:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1770114611; x=1770719411; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Sql9jJ4+QSjDChfJwwawiEfQbaUcvQt+K3oDgm5ti1M=; b=NwKoqPvSUs3gaF2bWbYrfi5+uEYWwWmw6xZ9YKou8+U90OmotLj2aixqkcVlKyVpOm oGCtEc+dHBjFtbrDLFgHbEpEEUxSdm64nMvy/pSn1LEKfl1b5u6HXY8hbHX4AZb8q6Xx G+2cVrNwjf2JUn7oZHqNPoJZj6SdPuqTSI+vIssuj7XP07uxk/ykrviyiqjCdeiFyJRT trPMU799ZQpIFmtCIGSy4vpRwF+Zk2v6Q4hp+FPsI8bhlWCTsfB3UXNDJnonCXHIrsE5 BEl/U3QmlfST/YyuGwTs6/9yx3UMvgCWeDasdal2gAV5ws4E5L6c7eAJ9d5paIEBP8Mw ywOw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770114611; x=1770719411; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=Sql9jJ4+QSjDChfJwwawiEfQbaUcvQt+K3oDgm5ti1M=; b=iCrr6msHvGTzc5GhPPPWk1oeSZ6NDv3EnkzsfFGK350aV4tvfXsp45OUEfdONrMRAB LYtvazuL9MU4MYG7drE9+oZTQr2dZrHDjZqOurSG883I63qscAF2CaeHJhqxegRLra/Q YFVOI6veh90HtvXYmylGpDkZd6e5iIIWE7aaMe3lz9mji+JjRO36LUswuwbzY6rhfHrw 8COJRy0LHqL0gUGFdhORM1hjZfoc9Qnf3Q7Euv2H/dq3E4H5f1MXgAuIo+hfXNc9DaPL ypu16+mQxnsTeY1ZjqdWTASEzrhsO5A2+opvkgac/UUESfGs/zUA9unnpt1Zvv38E915 Bddg== X-Forwarded-Encrypted: i=1; AJvYcCXzBhU2g69opCj3t5qO5aGXE1zDJG5sFfpN53M4gG/6ZbIw+j8H125+PLjFuAzcRKS2YzRZ6fiTP9eTTUw=@vger.kernel.org X-Gm-Message-State: AOJu0Yz2gtf/N97/gzdk+rACrYzevCH3gqxs42YZ2w003bi1KymmAWvK x10lyuAt9fN12Su2TT4RqxmsPOlHxz76OTSWLO/yyXzr4QfCY8zucfTp X-Gm-Gg: AZuq6aLf/nbGxkazqCZLrArrxhdN4hyNhX1q9aaq+Ynokh7eLZ5cC+K9So4k9WX40UA lnp3OMI9nledPP7nUjAe2BN9gDEdfl7GBr/1byWhsgOxnfO8mNoMq6zZIIhQbWytLSWpyUZsNK3 LL92YjQHYTBug1LZ1KpIGdKTlt1x7fvGBIBl+jHv38aHd0B/0Ca+lN6muXNcxKyx6ic4qpaJ+IX 0OCVBaxswQvxrusScJNGiLTwHv9Ic2VuJVgTrBd62jc7SQ9LRGXw1GEsS8gOAVMxZqqiumfJU9R 7LwB9DCoOLGzqylz1Ys4yVeFPHIEwc9HoUjI7/BZ52Z1EWeXm/o0opgEqBkVOtftQGPgas/5jsj RnJ+sNzzHEEkF+b7Z5gqV2ISuFZK97UQnFxgEM8pAPtAkrp1Ek+wZlShZH0pg26QTQLRWHXmf13 NAw7RYsAKgigAy1viv95dGkF13hFXinm1LWw6JVNEJ8FlGtuzT5Ce0AsOP+KSU/nDtAvlydqJvz QIQlxv1ELQ= X-Received: by 2002:a05:6000:184f:b0:435:ad52:31e0 with SMTP id ffacd0b85a97d-435f3a7b7e6mr21555166f8f.16.1770114610889; Tue, 03 Feb 2026 02:30:10 -0800 (PST) Received: from snowdrop.snailnet.com (82-69-66-36.dsl.in-addr.zen.co.uk. [82.69.66.36]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-435e10edf62sm55940729f8f.13.2026.02.03.02.30.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 Feb 2026 02:30:10 -0800 (PST) From: david.laight.linux@gmail.com To: Willy Tarreau , =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= , linux-kernel@vger.kernel.org, Cheng Li Cc: David Laight Subject: [PATCH next 01/12] tools/nolibc/printf: Move length check to snprintf callback Date: Tue, 3 Feb 2026 10:29:49 +0000 Message-Id: <20260203103000.20206-2-david.laight.linux@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260203103000.20206-1-david.laight.linux@gmail.com> References: <20260203103000.20206-1-david.laight.linux@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: David Laight Move output truncation to the snprintf() callback. This simplifies the main code and ensures the truncation will be correct when left-alignment is added. Add a zero length callback to 'finalise' the buffer rather than doing it in snprintf() itself. Signed-off-by: David Laight --- tools/include/nolibc/stdio.h | 66 +++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h index 1f16dab2ac88..6c8fa41dbc01 100644 --- a/tools/include/nolibc/stdio.h +++ b/tools/include/nolibc/stdio.h @@ -245,15 +245,15 @@ char *fgets(char *s, int size, FILE *stream) * - %s * - unknown modifiers are ignored. */ -typedef int (*__nolibc_printf_cb)(intptr_t state, const char *buf, size_t = size); +typedef int (*__nolibc_printf_cb)(void *state, const char *buf, size_t siz= e); =20 -static __attribute__((unused, format(printf, 4, 0))) -int __nolibc_printf(__nolibc_printf_cb cb, intptr_t state, size_t n, const= char *fmt, va_list args) +static __attribute__((unused, format(printf, 3, 0))) +int __nolibc_printf(__nolibc_printf_cb cb, void *state, const char *fmt, v= a_list args) { char escape, lpref, c; unsigned long long v; unsigned int written, width; - size_t len, ofs, w; + size_t len, ofs; char tmpbuf[21]; const char *outstr; =20 @@ -355,17 +355,13 @@ int __nolibc_printf(__nolibc_printf_cb cb, intptr_t s= tate, size_t n, const char outstr =3D fmt; len =3D ofs - 1; flush_str: - if (n) { - w =3D len < n ? len : n; - n -=3D w; - while (width-- > w) { - if (cb(state, " ", 1) !=3D 0) - return -1; - written +=3D 1; - } - if (cb(state, outstr, w) !=3D 0) + while (width-- > len) { + if (cb(state, " ", 1) !=3D 0) return -1; + written +=3D 1; } + if (cb(state, outstr, len) !=3D 0) + return -1; =20 written +=3D len; do_escape: @@ -378,18 +374,22 @@ int __nolibc_printf(__nolibc_printf_cb cb, intptr_t s= tate, size_t n, const char =20 /* literal char, just queue it */ } + + if (cb(state, NULL, 0) !=3D 0) + return -1; + return written; } =20 -static int __nolibc_fprintf_cb(intptr_t state, const char *buf, size_t siz= e) +static int __nolibc_fprintf_cb(void *stream, const char *buf, size_t size) { - return _fwrite(buf, size, (FILE *)state); + return size ? _fwrite(buf, size, stream) : 0; } =20 static __attribute__((unused, format(printf, 2, 0))) int vfprintf(FILE *stream, const char *fmt, va_list args) { - return __nolibc_printf(__nolibc_fprintf_cb, (intptr_t)stream, SIZE_MAX, f= mt, args); + return __nolibc_printf(__nolibc_fprintf_cb, stream, fmt, args); } =20 static __attribute__((unused, format(printf, 1, 0))) @@ -447,26 +447,38 @@ int dprintf(int fd, const char *fmt, ...) return ret; } =20 -static int __nolibc_sprintf_cb(intptr_t _state, const char *buf, size_t si= ze) +struct __nolibc_sprintf_cb_state { + char *buf; + size_t size; +}; + +static int __nolibc_sprintf_cb(void *v_state, const char *buf, size_t size) { - char **state =3D (char **)_state; + struct __nolibc_sprintf_cb_state *state =3D v_state; + char *tgt; =20 - memcpy(*state, buf, size); - *state +=3D size; + if (size >=3D state->size) { + if (state->size <=3D 1) + return 0; + size =3D state->size - 1; + } + tgt =3D state->buf; + if (size) { + state->size -=3D size; + state->buf =3D tgt + size; + memcpy(tgt, buf, size); + } else { + *tgt =3D '\0'; + } return 0; } =20 static __attribute__((unused, format(printf, 3, 0))) int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) { - char *state =3D buf; - int ret; + struct __nolibc_sprintf_cb_state state =3D { .buf =3D buf, .size =3D size= }; =20 - ret =3D __nolibc_printf(__nolibc_sprintf_cb, (intptr_t)&state, size, fmt,= args); - if (ret < 0) - return ret; - buf[(size_t)ret < size ? (size_t)ret : size - 1] =3D '\0'; - return ret; + return __nolibc_printf(__nolibc_sprintf_cb, &state, fmt, args); } =20 static __attribute__((unused, format(printf, 3, 4))) --=20 2.39.5