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