mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-31 13:11:05 +01:00 
			
		
		
		
	Amend sanitization of format strings. Support ' without stb_printf. Simpler loops, will also be used for ImStrv branch. (8ee77f1) (#3604)
				
					
				
			Widgets: Sliders: Fix a bug where numbers after format specifier (eg. %d123) would cause RoundScalarWithFormatT() return incorrect value.
This commit is contained in:
		| @@ -2077,37 +2077,36 @@ static const char* ImAtoi(const char* src, TYPE* output) | ||||
|     return src; | ||||
| } | ||||
|  | ||||
| // Sanitize format | ||||
| // - Zero terminate so extra characters after format (e.g. "%f123") don't confuse atof/atoi | ||||
| // - stb_sprintf.h supports several new modifiers which format numbers in a way that also makes them incompatible atof/atoi. | ||||
| static void SanitizeFormatString(const char* fmt, char* fmt_out, size_t fmt_out_size) | ||||
| { | ||||
|     const char* fmt_end = ImParseFormatFindEnd(fmt); | ||||
|     IM_ASSERT((size_t)(fmt_end - fmt + 1) < fmt_out_size); // Format is too long, let us know if this happens to you! | ||||
|     while (fmt < fmt_end) | ||||
|     { | ||||
|         char c = *(fmt++); | ||||
|         if (c != '\'' && c != '$' && c != '_') // Custom flags provided by stb_sprintf.h. POSIX 2008 also supports '. | ||||
|             *(fmt_out++) = c; | ||||
|     } | ||||
|     *fmt_out = 0; // Zero-terminate | ||||
| } | ||||
|  | ||||
| template<typename TYPE, typename SIGNEDTYPE> | ||||
| TYPE ImGui::RoundScalarWithFormatT(const char* format, ImGuiDataType data_type, TYPE v) | ||||
| { | ||||
|     const char* fmt_start = ImParseFormatFindStart(format); | ||||
|     if (fmt_start[0] != '%' || fmt_start[1] == '%') // Don't apply if the value is not visible in the format string | ||||
|         return v; | ||||
|  | ||||
|     // Sanitize format | ||||
|     char fmt_sanitized[32]; | ||||
|     SanitizeFormatString(fmt_start, fmt_sanitized, IM_ARRAYSIZE(fmt_sanitized)); | ||||
|     fmt_start = fmt_sanitized; | ||||
|  | ||||
|     // Format value with our rounding, and read back | ||||
|     char v_str[64]; | ||||
|     char fmt[32]; | ||||
|     const char* fmt_end = ImParseFormatFindEnd(fmt_start); | ||||
|     IM_ASSERT(fmt_end - fmt_start < IM_ARRAYSIZE(fmt) && "Number format is too long!"); | ||||
| #ifdef IMGUI_USE_STB_SPRINTF | ||||
|     // stb_sprintf.h supports several new modifiers which format numbers in a way that makes them incompatible with | ||||
|     // ImAtof()/ImAtoi(). Copy format string omitting incompatible modifiers and anything past the end of format specifier. | ||||
|     int fmt_len = 0; | ||||
|     for (int i = 0, end = fmt_end - fmt_start; i < end; i++) | ||||
|     { | ||||
|         char c = fmt_start[i]; | ||||
|         if (c == '\'' || c == '$' || c == '_')                                  // Custom flags provided by stb_sprintf.h | ||||
|             continue; | ||||
|         fmt[fmt_len++] = c; | ||||
|     } | ||||
|     fmt[fmt_len] = 0; | ||||
|     fmt_start = fmt; | ||||
| #else | ||||
|     // Extra characters after format specifier may confuse ImAtof()/ImAtoi(), therefore copying is performed, excluding anything beyond. | ||||
|     if (*fmt_end != 0) | ||||
|     { | ||||
|         ImStrncpy(fmt, fmt_start, fmt_end - fmt_start + 1); | ||||
|         fmt_start = fmt; | ||||
|     } | ||||
| #endif | ||||
|     ImFormatString(v_str, IM_ARRAYSIZE(v_str), fmt_start, v); | ||||
|     const char* p = v_str; | ||||
|     while (*p == ' ') | ||||
|   | ||||
		Reference in New Issue
	
	Block a user