这是indexloc提供的服务,不要输入任何密码
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .github/workflows/dependency-submission.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Automatic Dependency Submission

on:
push:
branches: [ 'master' ]
workflow_dispatch:

permissions:
contents: write

jobs:
dependency-submission:
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 17
- name: Generate and submit dependency graph
uses: gradle/actions/dependency-submission@v4
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ The core [Termux](https://github.com/termux/termux-app) app comes with the follo

## Installation

Latest version is `v0.118.1`.
Latest version is `v0.118.3`.

**NOTICE: It is highly recommended that you update to `v0.118.0` or higher ASAP for various bug fixes, including a critical world-readable vulnerability reported [here](https://termux.github.io/general/2022/02/15/termux-apps-vulnerability-disclosures.html). See [below](#google-play-store-experimental-branch) for information regarding Termux on Google Play.**

Expand Down
1 change: 1 addition & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Check https://termux.dev/security for info on Termux security policies and how to report vulnerabilities.
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,9 @@ public void checkForFontAndColors() {
try {
File colorsFile = TermuxConstants.TERMUX_COLOR_PROPERTIES_FILE;
File fontFile = TermuxConstants.TERMUX_FONT_FILE;
File italicFontFile = TermuxConstants.TERMUX_ITALIC_FONT_FILE;
File boldFontFile = TermuxConstants.TERMUX_BOLD_FONT_FILE;
File boldItalicFontFile = TermuxConstants.TERMUX_BOLD_ITALIC_FONT_FILE;

final Properties props = new Properties();
if (colorsFile.isFile()) {
Expand All @@ -511,7 +514,16 @@ public void checkForFontAndColors() {
updateBackgroundColor();

final Typeface newTypeface = (fontFile.exists() && fontFile.length() > 0) ? Typeface.createFromFile(fontFile) : Typeface.MONOSPACE;
mActivity.getTerminalView().setTypeface(newTypeface);
final Typeface newItalicTypeface = (italicFontFile.exists() && italicFontFile.length() > 0) ? Typeface.createFromFile(italicFontFile) : newTypeface;
final Typeface newBoldTypeface = (boldFontFile.exists() && boldFontFile.length() > 0) ? Typeface.createFromFile(boldFontFile) : newTypeface;
final Typeface newBoldItalicTypeface;
if (boldItalicFontFile.exists() && boldItalicFontFile.length() > 0) {
newBoldItalicTypeface = Typeface.createFromFile(boldItalicFontFile);
} else {
newBoldItalicTypeface = newBoldTypeface != newTypeface ? newBoldTypeface : newItalicTypeface;
}

mActivity.getTerminalView().setTypefaces(newTypeface, newItalicTypeface, newBoldTypeface, newBoldItalicTypeface);
} catch (Exception e) {
Logger.logStackTraceWithMessage(LOG_TAG, "Error in checkForFontAndColors()", e);
}
Expand Down
2 changes: 2 additions & 0 deletions jitpack.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
jdk:
- openjdk11
env:
JITPACK_NDK_VERSION: "21.1.6352462"
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ public final class TerminalEmulator {
private static final int ESC_APC = 20;
/** Escape processing: "ESC _" or Application Program Command (APC), followed by Escape. */
private static final int ESC_APC_ESCAPE = 21;
/** Escape processing: ESC [ <parameter bytes> */
private static final int ESC_CSI_UNSUPPORTED_PARAMETER_BYTE = 22;
/** Escape processing: ESC [ <parameter bytes> <intermediate bytes> */
private static final int ESC_CSI_UNSUPPORTED_INTERMEDIATE_BYTE = 23;

/** The number of parameter arguments including colon separated sub-parameters. */
private static final int MAX_ESCAPE_PARAMETERS = 32;
Expand Down Expand Up @@ -658,6 +662,10 @@ public void processCodePoint(int b) {
case ESC_CSI:
doCsi(b);
break;
case ESC_CSI_UNSUPPORTED_PARAMETER_BYTE:
case ESC_CSI_UNSUPPORTED_INTERMEDIATE_BYTE:
doCsiUnsupportedParameterOrIntermediateByte(b);
break;
case ESC_CSI_EXCLAMATION:
if (b == 'p') { // Soft terminal reset (DECSTR, http://vt100.net/docs/vt510-rm/DECSTR).
reset();
Expand Down Expand Up @@ -1059,6 +1067,37 @@ private int nextTabStop(int numTabs) {
return mRightMargin - 1;
}

/**
* Process byte while in the {@link #ESC_CSI_UNSUPPORTED_PARAMETER_BYTE} or
* {@link #ESC_CSI_UNSUPPORTED_INTERMEDIATE_BYTE} escape state.
*
* Parse unsupported parameter, intermediate and final bytes but ignore them.
*
* > For Control Sequence Introducer, ... the ESC [ is followed by
* > - any number (including none) of "parameter bytes" in the range 0x30–0x3F (ASCII 0–9:;<=>?),
* > - then by any number of "intermediate bytes" in the range 0x20–0x2F (ASCII space and !"#$%&'()*+,-./),
* > - then finally by a single "final byte" in the range 0x40–0x7E (ASCII @A–Z[\]^_`a–z{|}~).
*
* - https://en.wikipedia.org/wiki/ANSI_escape_code#Control_Sequence_Introducer_commands
* - https://invisible-island.net/xterm/ecma-48-parameter-format.html#section5.4
*/
private void doCsiUnsupportedParameterOrIntermediateByte(int b) {
if (mEscapeState == ESC_CSI_UNSUPPORTED_PARAMETER_BYTE && b >= 0x30 && b <= 0x3F) {
// Supported `0–9:;>?` or unsupported `<=` parameter byte after an
// initial unsupported parameter byte in `doCsi()`, or a sequential parameter byte.
continueSequence(ESC_CSI_UNSUPPORTED_PARAMETER_BYTE);
} else if (b >= 0x20 && b <= 0x2F) {
// Optional intermediate byte `!"#$%&'()*+,-./` after parameter or intermediate byte.
continueSequence(ESC_CSI_UNSUPPORTED_INTERMEDIATE_BYTE);
} else if (b >= 0x40 && b <= 0x7E) {
// Final byte `@A–Z[\]^_`a–z{|}~` after parameter or intermediate byte.
// Calling `unknownSequence()` would log an error with only a final byte, so ignore it for now.
finishSequence();
} else {
unknownSequence(b);
}
}

/** Process byte while in the {@link #ESC_CSI_QUESTIONMARK} escape state. */
private void doCsiQuestionMark(int b) {
switch (b) {
Expand Down Expand Up @@ -1656,12 +1695,16 @@ private void doCsi(int b) {
}
mCursorCol = newCol;
break;
case '?': // Esc [ ? -- start of a private mode set
case '?': // Esc [ ? -- start of a private parameter byte
continueSequence(ESC_CSI_QUESTIONMARK);
break;
case '>': // "Esc [ >" --
case '>': // "Esc [ >" -- start of a private parameter byte
continueSequence(ESC_CSI_BIGGERTHAN);
break;
case '<': // "Esc [ <" -- start of a private parameter byte
case '=': // "Esc [ =" -- start of a private parameter byte
continueSequence(ESC_CSI_UNSUPPORTED_PARAMETER_BYTE);
break;
case '`': // Horizontal position absolute (HPA - http://www.vt100.net/docs/vt510-rm/HPA).
setCursorColRespectingOriginMode(getArg0(1) - 1);
break;
Expand Down
64 changes: 54 additions & 10 deletions terminal-view/src/main/java/com/termux/view/TerminalRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.Typeface;
import android.util.Log;

import com.termux.terminal.TerminalBuffer;
import com.termux.terminal.TerminalEmulator;
Expand All @@ -17,9 +18,15 @@
* Saves font metrics, so needs to be recreated each time the typeface or font size changes.
*/
public final class TerminalRenderer {
boolean uniqueItalicTypeface;
boolean uniqueBoldTypeface;
boolean uniqueBoldItalicTypeface;

final int mTextSize;
final Typeface mTypeface;
final Typeface mItalicTypeface;
final Typeface mBoldTypeface;
final Typeface mBoldItalicTypeface;
private final Paint mTextPaint = new Paint();

/** The width of a single mono spaced character obtained by {@link Paint#measureText(String)} on a single 'X'. */
Expand All @@ -30,16 +37,24 @@ public final class TerminalRenderer {
private final int mFontAscent;
/** The {@link #mFontLineSpacing} + {@link #mFontAscent}. */
final int mFontLineSpacingAndAscent;

private final float[] asciiMeasures = new float[127];

public TerminalRenderer(int textSize, Typeface typeface) {
public TerminalRenderer(int textSize, Typeface typeface, Typeface italicTypeface, Typeface boldTypeface, Typeface boldItalicTypeface) {
mTextSize = textSize;
mTypeface = typeface;
mItalicTypeface = italicTypeface;
mBoldTypeface = boldTypeface;
mBoldItalicTypeface = boldItalicTypeface;

uniqueItalicTypeface = !mItalicTypeface.equals(mTypeface);
uniqueBoldTypeface = !mBoldTypeface.equals(mTypeface);
uniqueBoldItalicTypeface = !mBoldItalicTypeface.equals(mTypeface) && !mBoldItalicTypeface.equals(mItalicTypeface) && !mBoldItalicTypeface.equals(mBoldTypeface);


mTextPaint.setTypeface(typeface);
mTextPaint.setAntiAlias(true);
mTextPaint.setTextSize(textSize);
typeface.getStyle();

mFontLineSpacing = (int) Math.ceil(mTextPaint.getFontSpacing());
mFontAscent = (int) Math.ceil(mTextPaint.ascent());
Expand Down Expand Up @@ -168,6 +183,37 @@ private void drawTextRun(Canvas canvas, char[] text, int[] palette, float y, int
final boolean strikeThrough = (effect & TextStyle.CHARACTER_ATTRIBUTE_STRIKETHROUGH) != 0;
final boolean dim = (effect & TextStyle.CHARACTER_ATTRIBUTE_DIM) != 0;


if (italic && bold) {
mTextPaint.setTypeface(mBoldItalicTypeface);
if (mBoldItalicTypeface.equals(mBoldTypeface) && uniqueBoldTypeface) {
mTextPaint.setFakeBoldText(false);
mTextPaint.setTextSkewX(-0.35f);
} else if (mBoldItalicTypeface.equals(mItalicTypeface) && uniqueItalicTypeface){
mTextPaint.setFakeBoldText(true);
mTextPaint.setTextSkewX(uniqueItalicTypeface ? 0.f : -0.35f);
} else {
mTextPaint.setFakeBoldText(false);
mTextPaint.setTextSkewX(0.f);
}
} else if (italic) {
mTextPaint.setTypeface(mItalicTypeface);
mTextPaint.setFakeBoldText(false);
mTextPaint.setTextSkewX(uniqueItalicTypeface ? 0.f : -0.35f);
} else if (bold) {
mTextPaint.setTypeface(mBoldTypeface);
mTextPaint.setFakeBoldText(!uniqueBoldTypeface);
mTextPaint.setTextSkewX(0.f);
} else {
mTextPaint.setTypeface(mTypeface);
mTextPaint.setFakeBoldText(false);
mTextPaint.setTextSkewX(0.f);
}

final float fontWidth = mTextPaint.measureText("X");
final int fontAscent = (int) Math.ceil(mTextPaint.ascent());
final int fontLineSpacingAndAscent = (int) Math.ceil(mTextPaint.getFontSpacing()) + fontAscent;

if ((foreColor & 0xff000000) != 0xff000000) {
// Let bold have bright colors if applicable (one of the first 8):
if (bold && foreColor >= 0 && foreColor < 8) foreColor += 8;
Expand All @@ -186,10 +232,10 @@ private void drawTextRun(Canvas canvas, char[] text, int[] palette, float y, int
backColor = tmp;
}

float left = startColumn * mFontWidth;
float right = left + runWidthColumns * mFontWidth;
float left = startColumn * fontWidth;
float right = left + runWidthColumns * fontWidth;

mes = mes / mFontWidth;
mes = mes / fontWidth;
boolean savedMatrix = false;
if (Math.abs(mes - runWidthColumns) > 0.01) {
canvas.save();
Expand All @@ -202,12 +248,12 @@ private void drawTextRun(Canvas canvas, char[] text, int[] palette, float y, int
if (backColor != palette[TextStyle.COLOR_INDEX_BACKGROUND]) {
// Only draw non-default background.
mTextPaint.setColor(backColor);
canvas.drawRect(left, y - mFontLineSpacingAndAscent + mFontAscent, right, y, mTextPaint);
canvas.drawRect(left, y - fontLineSpacingAndAscent + fontAscent, right, y, mTextPaint);
}

if (cursor != 0) {
mTextPaint.setColor(cursor);
float cursorHeight = mFontLineSpacingAndAscent - mFontAscent;
float cursorHeight = fontLineSpacingAndAscent - fontAscent;
if (cursorStyle == TerminalEmulator.TERMINAL_CURSOR_STYLE_UNDERLINE) cursorHeight /= 4.;
else if (cursorStyle == TerminalEmulator.TERMINAL_CURSOR_STYLE_BAR) right -= ((right - left) * 3) / 4.;
canvas.drawRect(left, y - cursorHeight, right, y, mTextPaint);
Expand All @@ -226,14 +272,12 @@ private void drawTextRun(Canvas canvas, char[] text, int[] palette, float y, int
foreColor = 0xFF000000 + (red << 16) + (green << 8) + blue;
}

mTextPaint.setFakeBoldText(bold);
mTextPaint.setUnderlineText(underline);
mTextPaint.setTextSkewX(italic ? -0.35f : 0.f);
mTextPaint.setStrikeThruText(strikeThrough);
mTextPaint.setColor(foreColor);

// The text alignment is the default Paint.Align.LEFT.
canvas.drawTextRun(text, startCharIndex, runWidthChars, startCharIndex, runWidthChars, left, y - mFontLineSpacingAndAscent, false, mTextPaint);
canvas.drawTextRun(text, startCharIndex, runWidthChars, startCharIndex, runWidthChars, left, y - fontLineSpacingAndAscent, false, mTextPaint);
}

if (savedMatrix) canvas.restore();
Expand Down
10 changes: 7 additions & 3 deletions terminal-view/src/main/java/com/termux/view/TerminalView.java
Original file line number Diff line number Diff line change
Expand Up @@ -512,12 +512,16 @@ public void onContextMenuClosed(Menu menu) {
* @param textSize the new font size, in density-independent pixels.
*/
public void setTextSize(int textSize) {
mRenderer = new TerminalRenderer(textSize, mRenderer == null ? Typeface.MONOSPACE : mRenderer.mTypeface);
if (mRenderer == null) {
mRenderer = new TerminalRenderer(textSize,Typeface.MONOSPACE, Typeface.MONOSPACE, Typeface.MONOSPACE, Typeface.MONOSPACE);
} else {
mRenderer = new TerminalRenderer(textSize, mRenderer.mTypeface, mRenderer.mItalicTypeface, mRenderer.mBoldTypeface, mRenderer.mBoldItalicTypeface);
}
updateSize();
}

public void setTypeface(Typeface newTypeface) {
mRenderer = new TerminalRenderer(mRenderer.mTextSize, newTypeface);
public void setTypefaces(Typeface newTypeface, Typeface newItalicTypeFace, Typeface newBoldTypeface, Typeface newBoldItalicTypeface) {
mRenderer = new TerminalRenderer(mRenderer.mTextSize, newTypeface, newItalicTypeFace, newBoldTypeface, newBoldItalicTypeface);
updateSize();
invalidate();
}
Expand Down
3 changes: 2 additions & 1 deletion termux-shared/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ apply plugin: 'maven-publish'

android {
compileSdkVersion project.properties.compileSdkVersion.toInteger()
ndkVersion = System.getenv("JITPACK_NDK_VERSION") ?: project.properties.ndkVersion

dependencies {
implementation "androidx.appcompat:appcompat:1.3.1"
Expand All @@ -14,7 +15,7 @@ android {
implementation "io.noties.markwon:ext-strikethrough:$markwonVersion"
implementation "io.noties.markwon:linkify:$markwonVersion"
implementation "io.noties.markwon:recycler:$markwonVersion"
implementation "org.lsposed.hiddenapibypass:hiddenapibypass:5.0"
implementation "org.lsposed.hiddenapibypass:hiddenapibypass:6.1"

// Do not increment version higher than 1.0.0-alpha09 since it will break ViewUtils and needs to be looked into
// noinspection GradleDependency
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.termux.shared.models;

import androidx.annotation.Keep;

import com.termux.shared.markdown.MarkdownUtils;
import com.termux.shared.android.AndroidUtils;

Expand All @@ -10,6 +12,25 @@
*/
public class ReportInfo implements Serializable {

/**
* Explicitly define `serialVersionUID` to prevent exceptions on deserialization.
*
* Like when calling `Bundle.getSerializable()` on Android.
* `android.os.BadParcelableException: Parcelable encountered IOException reading a Serializable object` (name = <class_name>)
* `java.io.InvalidClassException: <class_name>; local class incompatible`
*
* The `@Keep` annotation is necessary to prevent the field from being removed by proguard when
* app is compiled, even if its kept during library compilation.
*
* **See Also:**
* - https://docs.oracle.com/javase/8/docs/platform/serialization/spec/version.html#a6678
* - https://docs.oracle.com/javase/8/docs/platform/serialization/spec/class.html#a4100
*/
@Keep
private static final long serialVersionUID = 1L;



/** The user action that was being processed for which the report was generated. */
public final String userAction;
/** The internal app component that sent the report. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import android.graphics.Color;
import android.graphics.Typeface;

import androidx.annotation.Keep;
import androidx.annotation.NonNull;

import com.termux.shared.activities.TextIOActivity;
Expand All @@ -19,6 +20,25 @@
*/
public class TextIOInfo implements Serializable {

/**
* Explicitly define `serialVersionUID` to prevent exceptions on deserialization.
*
* Like when calling `Bundle.getSerializable()` on Android.
* `android.os.BadParcelableException: Parcelable encountered IOException reading a Serializable object` (name = <class_name>)
* `java.io.InvalidClassException: <class_name>; local class incompatible`
*
* The `@Keep` annotation is necessary to prevent the field from being removed by proguard when
* app is compiled, even if its kept during library compilation.
*
* **See Also:**
* - https://docs.oracle.com/javase/8/docs/platform/serialization/spec/version.html#a6678
* - https://docs.oracle.com/javase/8/docs/platform/serialization/spec/class.html#a4100
*/
@Keep
private static final long serialVersionUID = 1L;



public static final int GENERAL_DATA_SIZE_LIMIT_IN_BYTES = 1000;
public static final int LABEL_SIZE_LIMIT_IN_BYTES = 4000;
public static final int TEXT_SIZE_LIMIT_IN_BYTES = 100000 - GENERAL_DATA_SIZE_LIMIT_IN_BYTES - LABEL_SIZE_LIMIT_IN_BYTES; // < 100KB
Expand Down
Loading