Mercurial > hg > nginx
comparison src/core/ngx_string.c @ 6009:15a15f6ae3a2
Core: overflow detection in number parsing functions.
author | Ruslan Ermilov <ru@nginx.com> |
---|---|
date | Tue, 17 Mar 2015 00:26:15 +0300 |
parents | 78271500b8de |
children | fcbac620ae83 |
comparison
equal
deleted
inserted
replaced
6008:b92d5a26d55f | 6009:15a15f6ae3a2 |
---|---|
899 | 899 |
900 | 900 |
901 ngx_int_t | 901 ngx_int_t |
902 ngx_atoi(u_char *line, size_t n) | 902 ngx_atoi(u_char *line, size_t n) |
903 { | 903 { |
904 ngx_int_t value; | 904 ngx_int_t value, cutoff, cutlim; |
905 | 905 |
906 if (n == 0) { | 906 if (n == 0) { |
907 return NGX_ERROR; | 907 return NGX_ERROR; |
908 } | 908 } |
909 | |
910 cutoff = NGX_MAX_INT_T_VALUE / 10; | |
911 cutlim = NGX_MAX_INT_T_VALUE % 10; | |
909 | 912 |
910 for (value = 0; n--; line++) { | 913 for (value = 0; n--; line++) { |
911 if (*line < '0' || *line > '9') { | 914 if (*line < '0' || *line > '9') { |
912 return NGX_ERROR; | 915 return NGX_ERROR; |
913 } | 916 } |
914 | 917 |
918 if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) { | |
919 return NGX_ERROR; | |
920 } | |
921 | |
915 value = value * 10 + (*line - '0'); | 922 value = value * 10 + (*line - '0'); |
916 } | 923 } |
917 | 924 |
918 if (value < 0) { | 925 return value; |
919 return NGX_ERROR; | |
920 | |
921 } else { | |
922 return value; | |
923 } | |
924 } | 926 } |
925 | 927 |
926 | 928 |
927 /* parse a fixed point number, e.g., ngx_atofp("10.5", 4, 2) returns 1050 */ | 929 /* parse a fixed point number, e.g., ngx_atofp("10.5", 4, 2) returns 1050 */ |
928 | 930 |
929 ngx_int_t | 931 ngx_int_t |
930 ngx_atofp(u_char *line, size_t n, size_t point) | 932 ngx_atofp(u_char *line, size_t n, size_t point) |
931 { | 933 { |
932 ngx_int_t value; | 934 ngx_int_t value, cutoff, cutlim; |
933 ngx_uint_t dot; | 935 ngx_uint_t dot; |
934 | 936 |
935 if (n == 0) { | 937 if (n == 0) { |
936 return NGX_ERROR; | 938 return NGX_ERROR; |
937 } | 939 } |
940 | |
941 cutoff = NGX_MAX_INT_T_VALUE / 10; | |
942 cutlim = NGX_MAX_INT_T_VALUE % 10; | |
938 | 943 |
939 dot = 0; | 944 dot = 0; |
940 | 945 |
941 for (value = 0; n--; line++) { | 946 for (value = 0; n--; line++) { |
942 | 947 |
955 | 960 |
956 if (*line < '0' || *line > '9') { | 961 if (*line < '0' || *line > '9') { |
957 return NGX_ERROR; | 962 return NGX_ERROR; |
958 } | 963 } |
959 | 964 |
965 if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) { | |
966 return NGX_ERROR; | |
967 } | |
968 | |
960 value = value * 10 + (*line - '0'); | 969 value = value * 10 + (*line - '0'); |
961 point -= dot; | 970 point -= dot; |
962 } | 971 } |
963 | 972 |
964 while (point--) { | 973 while (point--) { |
974 if (value > cutoff) { | |
975 return NGX_ERROR; | |
976 } | |
977 | |
965 value = value * 10; | 978 value = value * 10; |
966 } | 979 } |
967 | 980 |
968 if (value < 0) { | 981 return value; |
969 return NGX_ERROR; | |
970 | |
971 } else { | |
972 return value; | |
973 } | |
974 } | 982 } |
975 | 983 |
976 | 984 |
977 ssize_t | 985 ssize_t |
978 ngx_atosz(u_char *line, size_t n) | 986 ngx_atosz(u_char *line, size_t n) |
979 { | 987 { |
980 ssize_t value; | 988 ssize_t value, cutoff, cutlim; |
981 | 989 |
982 if (n == 0) { | 990 if (n == 0) { |
983 return NGX_ERROR; | 991 return NGX_ERROR; |
984 } | 992 } |
993 | |
994 cutoff = NGX_MAX_SIZE_T_VALUE / 10; | |
995 cutlim = NGX_MAX_SIZE_T_VALUE % 10; | |
985 | 996 |
986 for (value = 0; n--; line++) { | 997 for (value = 0; n--; line++) { |
987 if (*line < '0' || *line > '9') { | 998 if (*line < '0' || *line > '9') { |
988 return NGX_ERROR; | 999 return NGX_ERROR; |
989 } | 1000 } |
990 | 1001 |
1002 if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) { | |
1003 return NGX_ERROR; | |
1004 } | |
1005 | |
991 value = value * 10 + (*line - '0'); | 1006 value = value * 10 + (*line - '0'); |
992 } | 1007 } |
993 | 1008 |
994 if (value < 0) { | 1009 return value; |
995 return NGX_ERROR; | |
996 | |
997 } else { | |
998 return value; | |
999 } | |
1000 } | 1010 } |
1001 | 1011 |
1002 | 1012 |
1003 off_t | 1013 off_t |
1004 ngx_atoof(u_char *line, size_t n) | 1014 ngx_atoof(u_char *line, size_t n) |
1005 { | 1015 { |
1006 off_t value; | 1016 off_t value, cutoff, cutlim; |
1007 | 1017 |
1008 if (n == 0) { | 1018 if (n == 0) { |
1009 return NGX_ERROR; | 1019 return NGX_ERROR; |
1010 } | 1020 } |
1021 | |
1022 cutoff = NGX_MAX_OFF_T_VALUE / 10; | |
1023 cutlim = NGX_MAX_OFF_T_VALUE % 10; | |
1011 | 1024 |
1012 for (value = 0; n--; line++) { | 1025 for (value = 0; n--; line++) { |
1013 if (*line < '0' || *line > '9') { | 1026 if (*line < '0' || *line > '9') { |
1014 return NGX_ERROR; | 1027 return NGX_ERROR; |
1015 } | 1028 } |
1016 | 1029 |
1030 if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) { | |
1031 return NGX_ERROR; | |
1032 } | |
1033 | |
1017 value = value * 10 + (*line - '0'); | 1034 value = value * 10 + (*line - '0'); |
1018 } | 1035 } |
1019 | 1036 |
1020 if (value < 0) { | 1037 return value; |
1021 return NGX_ERROR; | |
1022 | |
1023 } else { | |
1024 return value; | |
1025 } | |
1026 } | 1038 } |
1027 | 1039 |
1028 | 1040 |
1029 time_t | 1041 time_t |
1030 ngx_atotm(u_char *line, size_t n) | 1042 ngx_atotm(u_char *line, size_t n) |
1031 { | 1043 { |
1032 time_t value; | 1044 time_t value, cutoff, cutlim; |
1033 | 1045 |
1034 if (n == 0) { | 1046 if (n == 0) { |
1035 return NGX_ERROR; | 1047 return NGX_ERROR; |
1036 } | 1048 } |
1049 | |
1050 cutoff = NGX_MAX_TIME_T_VALUE / 10; | |
1051 cutlim = NGX_MAX_TIME_T_VALUE % 10; | |
1037 | 1052 |
1038 for (value = 0; n--; line++) { | 1053 for (value = 0; n--; line++) { |
1039 if (*line < '0' || *line > '9') { | 1054 if (*line < '0' || *line > '9') { |
1040 return NGX_ERROR; | 1055 return NGX_ERROR; |
1041 } | 1056 } |
1042 | 1057 |
1058 if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) { | |
1059 return NGX_ERROR; | |
1060 } | |
1061 | |
1043 value = value * 10 + (*line - '0'); | 1062 value = value * 10 + (*line - '0'); |
1044 } | 1063 } |
1045 | 1064 |
1046 if (value < 0) { | 1065 return value; |
1047 return NGX_ERROR; | |
1048 | |
1049 } else { | |
1050 return value; | |
1051 } | |
1052 } | 1066 } |
1053 | 1067 |
1054 | 1068 |
1055 ngx_int_t | 1069 ngx_int_t |
1056 ngx_hextoi(u_char *line, size_t n) | 1070 ngx_hextoi(u_char *line, size_t n) |
1057 { | 1071 { |
1058 u_char c, ch; | 1072 u_char c, ch; |
1059 ngx_int_t value; | 1073 ngx_int_t value, cutoff; |
1060 | 1074 |
1061 if (n == 0) { | 1075 if (n == 0) { |
1062 return NGX_ERROR; | 1076 return NGX_ERROR; |
1063 } | 1077 } |
1064 | 1078 |
1079 cutoff = NGX_MAX_INT_T_VALUE / 16; | |
1080 | |
1065 for (value = 0; n--; line++) { | 1081 for (value = 0; n--; line++) { |
1082 if (value > cutoff) { | |
1083 return NGX_ERROR; | |
1084 } | |
1085 | |
1066 ch = *line; | 1086 ch = *line; |
1067 | 1087 |
1068 if (ch >= '0' && ch <= '9') { | 1088 if (ch >= '0' && ch <= '9') { |
1069 value = value * 16 + (ch - '0'); | 1089 value = value * 16 + (ch - '0'); |
1070 continue; | 1090 continue; |
1078 } | 1098 } |
1079 | 1099 |
1080 return NGX_ERROR; | 1100 return NGX_ERROR; |
1081 } | 1101 } |
1082 | 1102 |
1083 if (value < 0) { | 1103 return value; |
1084 return NGX_ERROR; | |
1085 | |
1086 } else { | |
1087 return value; | |
1088 } | |
1089 } | 1104 } |
1090 | 1105 |
1091 | 1106 |
1092 u_char * | 1107 u_char * |
1093 ngx_hex_dump(u_char *dst, u_char *src, size_t len) | 1108 ngx_hex_dump(u_char *dst, u_char *src, size_t len) |