A millisecond setting with a unit suffix silently wraps on overflow

Abierto Apto para principiantes
#8,381 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 2 días

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
76/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
java
Área
backend

Línea de trabajo

Empieza en core/src/main/java/io/questdb/std/Numbers.java, en parseMillis(CharSequence), donde las multiplicaciones de unidades en aproximadamente las líneas 1911, 1917 y 1938 no están comprobadas. parseLongSize ya muestra la comprobación de desbordamiento que hay que copiar, y parseMicros y parseNanos necesitan la misma revisión. Luego ejecuta NumbersTest con las entradas indicadas, que deberían lanzar NumericException con "duration overflow", y comprueba que los valores más grandes que caben siguen analizándose exactamente. PropServerConfiguration.getMillis (aproximadamente líneas 3522-3534) debería después hacer fallar la configuración con el nombre de la clave en el mensaje.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

  • Classification: PRE-EXISTING (not introduced by PR #8159; Numbers.java is unchanged by the PR,
    the unit code dates from a4b9a7e4088, 2024-11-05). Not [security], not [crash].
  • Location: core/src/main/java/io/questdb/std/Numbers.java:1911 (val *= Dates.MINUTE_MILLIS),
    :1917 (val *= Dates.SECOND_MILLIS), :1938 (val *= Dates.HOUR_MILLIS) in
    Numbers.parseMillis(CharSequence). PropServerConfiguration.getMillis (:3522-3534) returns the
    result as is.

Problem

parseMillis checks the digit accumulation for overflow (r > val -> "duration overflow"), but
multiplies the accumulated value by its unit (m, s, h) without a check. A value whose
milliseconds do not fit a long wraps around instead of failing. Numbers.parseLongSize does check
its unit multiplication (r > val after val * 1024L), so the two parsers disagree.

Probe at HEAD 9e3e2af653 (probes/M1R3SettingProbeTest.java, Numbers.parseMillis):

input result
9223372036854775807s -1000
10000000000000000s -8446744073709551616
9223372036854775807h -3600000
153722867280913m -9223372036854771616
18446744073709552s 384
9223372036854775808 (no unit) NumericException, as expected

Impact

A server.conf or QDB_... value meant as "practically never" (for example a huge timeout with an
s or h suffix) starts the server with a negative or a small positive value instead of failing at
startup. Every millisecond setting read through getMillis is affected, for example
cairo.mat.view.refresh.busy.retry.timeout (no range check: a negative value retries at once), and
the planned cairo.view.compile.busy.retry.timeout (its "must not be negative" check catches the
negative outcomes, but 18446744073709552s would start with a 384 ms delay). Only an administrator
can set these values, and only absurd ones wrap.

Expected

parseMillis (and the same pattern in parseMicros / parseNanos, to be checked) fails with
"duration overflow" when the unit multiplication overflows, as parseLongSize does, so the server
refuses to start with ServerConfigurationException naming the key.

Suggested test

NumbersTest: parseMillis of each input above throws NumericException with "duration overflow";
the largest values that fit (9223372036854775807, 9223372036854775s, 2562047788015h) parse to
their exact products (plain Java long arithmetic is the oracle). PropServerConfigurationTest:
cairo.mat.view.refresh.busy.retry.timeout=18446744073709552s fails the configuration with the key
in the message.

Found while working on PR #8159 (branch puzpuzpuz_view_matview_fixes); the PR base cd8749a10a has the same behavior.

Lenguaje dominante
Java
Estrellas
17.5k
Forks
1.7k
Merge medio
5 d 11 h
PR fusionados (30 d)
64

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de questdb/questdb

Todos los issues de questdb/questdb

Issues similares

Más issues de Java

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.