Commit 1c0459f1 authored by Nick Mathewson's avatar Nick Mathewson 🤹
Browse files

Merge remote-tracking branch 'teor/bug22502' into maint-0.3.1

parents eff5e294 7d535ea9
Loading
Loading
Loading
Loading
+26 −2
Original line number Diff line number Diff line
@@ -102,8 +102,13 @@ tor_compress_impl(int compress,

  stream = tor_compress_new(compress, method, compression_level);

  if (stream == NULL)
  if (stream == NULL) {
    log_warn(LD_GENERAL, "NULL stream while %scompressing",
             compress?"":"de");
    log_debug(LD_GENERAL, "method: %d level: %d at len: %zd",
              method, compression_level, in_len);
    return -1;
  }

  size_t in_len_orig = in_len;
  size_t out_remaining, out_alloc;
@@ -128,14 +133,33 @@ tor_compress_impl(int compress,
          // inputs.
          tor_compress_free(stream);
          stream = tor_compress_new(compress, method, compression_level);
          if (stream == NULL) {
            log_warn(LD_GENERAL, "NULL stream while %scompressing",
                     compress?"":"de");
            goto err;
          }
        }
        break;
      case TOR_COMPRESS_OK:
        if (compress || complete_only) {
          log_fn(protocol_warn_level, LD_PROTOCOL,
                 "Unexpected %s while %scompressing",
                 complete_only?"end of input":"result",
                 compress?"":"de");
          log_debug(LD_GENERAL, "method: %d level: %d at len: %zd",
                    method, compression_level, in_len);
          goto err;
        } else {
          if (in_len != 0) {
            log_fn(protocol_warn_level, LD_PROTOCOL,
                   "Unexpected extra input while decompressing");
            log_debug(LD_GENERAL, "method: %d level: %d at len: %zd",
                      method, compression_level, in_len);
            goto err;
          } else {
            goto done;
          }
        }
        break;
      case TOR_COMPRESS_BUFFER_FULL: {
        if (!compress && outptr < *out+out_alloc) {
+16 −4
Original line number Diff line number Diff line
@@ -312,6 +312,8 @@ tor_zstd_compress_process(tor_zstd_compress_state_t *state,
      return TOR_COMPRESS_ERROR;
    }

    // ZSTD_flushStream returns 0 if the frame is done, or >0 if it
    // is incomplete.
    if (retval > 0)
      return TOR_COMPRESS_BUFFER_FULL;
  }
@@ -319,7 +321,7 @@ tor_zstd_compress_process(tor_zstd_compress_state_t *state,
  if (!finish) {
    // We're not done with the input, so no need to flush.
    return TOR_COMPRESS_OK;
  } else if (state->compress && finish) {
  } else if (state->compress) {
    retval = ZSTD_endStream(state->u.compress_stream, &output);

    *out = (char *)output.dst + output.pos;
@@ -338,10 +340,20 @@ tor_zstd_compress_process(tor_zstd_compress_state_t *state,
      return TOR_COMPRESS_BUFFER_FULL;

    return TOR_COMPRESS_DONE;
  } else {
    // ZSTD_flushStream returns 0 if the frame is done, or >0 if it
  } else /* if (!state->compress) */ {
    // ZSTD_decompressStream returns 0 if the frame is done, or >0 if it
    // is incomplete.
    return (retval == 0) ? TOR_COMPRESS_DONE : TOR_COMPRESS_OK;
    // We check this above.
    tor_assert_nonfatal(!ZSTD_isError(retval));
    // Start a new frame if this frame is done
    if (retval == 0)
      return TOR_COMPRESS_DONE;
    // Don't check out_len, it might have some space left if the next output
    // chunk is larger than the remaining space
    else if (*in_len > 0)
      return  TOR_COMPRESS_BUFFER_FULL;
    else
      return TOR_COMPRESS_OK;
  }

#else // HAVE_ZSTD.
+32 −17
Original line number Diff line number Diff line
@@ -2327,12 +2327,13 @@ connection_dir_client_reached_eof(dir_connection_t *conn)

  plausible = body_is_plausible(body, body_len, conn->base_.purpose);
  if (compression != NO_METHOD || !plausible) {
    int severity = LOG_DEBUG;
    char *new_body = NULL;
    size_t new_len = 0;
    compress_method_t guessed = detect_compression_method(body, body_len);
    if (compression == UNKNOWN_METHOD || guessed != compression) {
      /* Tell the user if we don't believe what we're told about compression.*/
    const char *description1, *description2;
    int want_to_try_both = 0;
    int tried_both = 0;
    compress_method_t guessed = detect_compression_method(body, body_len);

    description1 = compression_method_get_human_name(compression);

@@ -2344,12 +2345,21 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
    else
      description2 = compression_method_get_human_name(guessed);

      log_info(LD_HTTP, "HTTP body from server '%s:%d' was labeled as %s, "
               "but it seems to be %s.%s",
    /* Tell the user if we don't believe what we're told about compression.*/
    want_to_try_both = (compression == UNKNOWN_METHOD ||
                        guessed != compression);
    if (want_to_try_both) {
      severity = LOG_INFO;
    }

    tor_log(severity, LD_HTTP,
            "HTTP body from server '%s:%d' was labeled as %s, "
            "%s it seems to be %s.%s",
            conn->base_.address, conn->base_.port, description1,
            guessed != compression?"but":"and",
            description2,
               (compression>0 && guessed>0)?"  Trying both.":"");
    }
            (compression>0 && guessed>0 && want_to_try_both)?
            "  Trying both.":"");

    /* Try declared compression first if we can.
     * tor_compress_supports_method() also returns true for NO_METHOD.
@@ -2376,14 +2386,19 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
    }

    if (!new_body && tor_compress_supports_method(guessed) &&
        compression != guessed)
        compression != guessed) {
      tor_uncompress(&new_body, &new_len, body, body_len, guessed,
                     !allow_partial, LOG_PROTOCOL_WARN);
      tried_both = 1;
    }
    /* If we're pretty sure that we have a compressed directory, and
     * we didn't manage to uncompress it, then warn and bail. */
    if (!plausible && !new_body) {
      log_fn(LOG_PROTOCOL_WARN, LD_HTTP,
             "Unable to decompress HTTP body (server '%s:%d').",
             "Unable to decompress HTTP body (tried %s%s%s, server '%s:%d').",
             description1,
             tried_both?" and ":"",
             tried_both?description2:"",
             conn->base_.address, conn->base_.port);
      rv = -1;
      goto done;