authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-09 15:07:45-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-09 15:07:45-07:00
log2468766a894d66037fb81791dc93fcb69e4c4055
treea60db187d75d41af16facd8934d5a6748963c64f
parent51a9a6aab696b9fbd69dadb5a569cfe184fabecc

std: forbid alignment formatting options sometimes


1 files changed, 26 insertions(+), 3 deletions(-)

lib/std/io/Writer.zig+26-3
...@@ -805,15 +805,18 @@ pub fn printValue(...@@ -805,15 +805,18 @@ pub fn printValue(
805 .pointer => |info| switch (info.size) {805 .pointer => |info| switch (info.size) {
806 .one, .slice => {806 .one, .slice => {
807 const slice: []const u8 = value;807 const slice: []const u8 = value;
808 optionsForbidden(options);
808 return printHex(w, slice, .lower);809 return printHex(w, slice, .lower);
809 },810 },
810 .many, .c => {811 .many, .c => {
811 const slice: [:0]const u8 = std.mem.span(value);812 const slice: [:0]const u8 = std.mem.span(value);
813 optionsForbidden(options);
812 return printHex(w, slice, .lower);814 return printHex(w, slice, .lower);
813 },815 },
814 },816 },
815 .array => {817 .array => {
816 const slice: []const u8 = &value;818 const slice: []const u8 = &value;
819 optionsForbidden(options);
817 return printHex(w, slice, .lower);820 return printHex(w, slice, .lower);
818 },821 },
819 .vector => return printVector(w, fmt, options, value, max_depth),822 .vector => return printVector(w, fmt, options, value, max_depth),
...@@ -827,15 +830,18 @@ pub fn printValue(...@@ -827,15 +830,18 @@ pub fn printValue(
827 .pointer => |info| switch (info.size) {830 .pointer => |info| switch (info.size) {
828 .one, .slice => {831 .one, .slice => {
829 const slice: []const u8 = value;832 const slice: []const u8 = value;
833 optionsForbidden(options);
830 return printHex(w, slice, .upper);834 return printHex(w, slice, .upper);
831 },835 },
832 .many, .c => {836 .many, .c => {
833 const slice: [:0]const u8 = std.mem.span(value);837 const slice: [:0]const u8 = std.mem.span(value);
838 optionsForbidden(options);
834 return printHex(w, slice, .upper);839 return printHex(w, slice, .upper);
835 },840 },
836 },841 },
837 .array => {842 .array => {
838 const slice: []const u8 = &value;843 const slice: []const u8 = &value;
844 optionsForbidden(options);
839 return printHex(w, slice, .upper);845 return printHex(w, slice, .upper);
840 },846 },
841 .vector => return printVector(w, fmt, options, value, max_depth),847 .vector => return printVector(w, fmt, options, value, max_depth),
...@@ -845,15 +851,18 @@ pub fn printValue(...@@ -845,15 +851,18 @@ pub fn printValue(
845 .pointer => |info| switch (info.size) {851 .pointer => |info| switch (info.size) {
846 .one, .slice => {852 .one, .slice => {
847 const slice: []const u8 = value;853 const slice: []const u8 = value;
854 optionsForbidden(options); // Alignment not allowed on strings.
848 return w.writeAll(slice);855 return w.writeAll(slice);
849 },856 },
850 .many, .c => {857 .many, .c => {
851 const slice: [:0]const u8 = std.mem.span(value);858 const slice: [:0]const u8 = std.mem.span(value);
859 optionsForbidden(options); // Alignment not allowed on strings.
852 return w.writeAll(slice);860 return w.writeAll(slice);
853 },861 },
854 },862 },
855 .array => {863 .array => {
856 const slice: []const u8 = &value;864 const slice: []const u8 = &value;
865 optionsForbidden(options); // Alignment not allowed on strings.
857 return w.writeAll(slice);866 return w.writeAll(slice);
858 },867 },
859 else => invalidFmtError(fmt, value),868 else => invalidFmtError(fmt, value),
...@@ -900,15 +909,18 @@ pub fn printValue(...@@ -900,15 +909,18 @@ pub fn printValue(
900 .pointer => |info| switch (info.size) {909 .pointer => |info| switch (info.size) {
901 .one, .slice => {910 .one, .slice => {
902 const slice: []const u8 = value;911 const slice: []const u8 = value;
912 optionsForbidden(options);
903 return w.printBase64(slice);913 return w.printBase64(slice);
904 },914 },
905 .many, .c => {915 .many, .c => {
906 const slice: [:0]const u8 = std.mem.span(value);916 const slice: [:0]const u8 = std.mem.span(value);
917 optionsForbidden(options);
907 return w.printBase64(slice);918 return w.printBase64(slice);
908 },919 },
909 },920 },
910 .array => {921 .array => {
911 const slice: []const u8 = &value;922 const slice: []const u8 = &value;
923 optionsForbidden(options);
912 return w.printBase64(slice);924 return w.printBase64(slice);
913 },925 },
914 else => invalidFmtError(fmt, value),926 else => invalidFmtError(fmt, value),
...@@ -933,11 +945,12 @@ pub fn printValue(...@@ -933,11 +945,12 @@ pub fn printValue(
933 },945 },
934 .bool => {946 .bool => {
935 if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);947 if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);
936 return w.writeAll(if (value) "true" else "false");948 const string: []const u8 = if (value) "true" else "false";
949 return w.alignBufferOptions(string, options);
937 },950 },
938 .void => {951 .void => {
939 if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);952 if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);
940 return w.writeAll("void");953 return w.alignBufferOptions("void", options);
941 },954 },
942 .optional => {955 .optional => {
943 const remaining_fmt = comptime if (fmt.len > 0 and fmt[0] == '?')956 const remaining_fmt = comptime if (fmt.len > 0 and fmt[0] == '?')
...@@ -967,10 +980,12 @@ pub fn printValue(...@@ -967,10 +980,12 @@ pub fn printValue(
967 },980 },
968 .error_set => {981 .error_set => {
969 if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);982 if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);
983 optionsForbidden(options);
970 return printErrorSet(w, value);984 return printErrorSet(w, value);
971 },985 },
972 .@"enum" => |info| {986 .@"enum" => |info| {
973 if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);987 if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);
988 optionsForbidden(options);
974 if (info.is_exhaustive) {989 if (info.is_exhaustive) {
975 return printEnumExhaustive(w, value);990 return printEnumExhaustive(w, value);
976 } else {991 } else {
...@@ -1067,6 +1082,7 @@ pub fn printValue(...@@ -1067,6 +1082,7 @@ pub fn printValue(
1067 },1082 },
1068 .many, .c => {1083 .many, .c => {
1069 if (!is_any) @compileError("cannot format pointer without a specifier (i.e. {s} or {*})");1084 if (!is_any) @compileError("cannot format pointer without a specifier (i.e. {s} or {*})");
1085 optionsForbidden(options);
1070 try w.printAddress(value);1086 try w.printAddress(value);
1071 },1087 },
1072 .slice => {1088 .slice => {
...@@ -1102,21 +1118,28 @@ pub fn printValue(...@@ -1102,21 +1118,28 @@ pub fn printValue(
1102 .@"fn" => @compileError("unable to format function body type, use '*const " ++ @typeName(T) ++ "' for a function pointer type"),1118 .@"fn" => @compileError("unable to format function body type, use '*const " ++ @typeName(T) ++ "' for a function pointer type"),
1103 .type => {1119 .type => {
1104 if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);1120 if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);
1121 optionsForbidden(options);
1105 return w.writeAll(@typeName(value));1122 return w.writeAll(@typeName(value));
1106 },1123 },
1107 .enum_literal => {1124 .enum_literal => {
1108 if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);1125 if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);
1126 optionsForbidden(options);
1109 var vecs: [2][]const u8 = .{ ".", @tagName(value) };1127 var vecs: [2][]const u8 = .{ ".", @tagName(value) };
1110 return w.writeVecAll(&vecs);1128 return w.writeVecAll(&vecs);
1111 },1129 },
1112 .null => {1130 .null => {
1113 if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);1131 if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);
1114 return w.writeAll("null");1132 return w.alignBufferOptions("null", options);
1115 },1133 },
1116 else => @compileError("unable to format type '" ++ @typeName(T) ++ "'"),1134 else => @compileError("unable to format type '" ++ @typeName(T) ++ "'"),
1117 }1135 }
1118}1136}
11191137
1138fn optionsForbidden(options: std.fmt.Options) void {
1139 assert(options.precision == null);
1140 assert(options.width == null);
1141}
1142
1120fn printErrorSet(w: *Writer, error_set: anyerror) Error!void {1143fn printErrorSet(w: *Writer, error_set: anyerror) Error!void {
1121 var vecs: [2][]const u8 = .{ "error.", @errorName(error_set) };1144 var vecs: [2][]const u8 = .{ "error.", @errorName(error_set) };
1122 try w.writeVecAll(&vecs);1145 try w.writeVecAll(&vecs);