From f08916310e60fd2af85edc364ee167e1063f222e Mon Sep 17 00:00:00 2001 From: wayne1029 Date: Sun, 2 Mar 2025 11:09:42 +0000 Subject: [PATCH 01/11] Updated lab0.js to print Hello world! --- lab0/lab0.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lab0/lab0.js b/lab0/lab0.js index e69de29..940a3ff 100644 --- a/lab0/lab0.js +++ b/lab0/lab0.js @@ -0,0 +1 @@ +console.log("Hello world!"); From 9d0813d67038d993ca7c234371333c722ebb8186 Mon Sep 17 00:00:00 2001 From: AxelHowe Date: Wed, 5 Mar 2025 21:45:27 +0800 Subject: [PATCH 02/11] feat: lab1 --- lab1/README.md | 22 +++++++++++++++++++ lab1/main.js | 55 +++++++++++++++++++++++++++++++++++++++++++++++ lab1/main_test.js | 23 ++++++++++++++++++++ lab1/validate.sh | 38 ++++++++++++++++++++++++++++++++ 4 files changed, 138 insertions(+) create mode 100644 lab1/README.md create mode 100644 lab1/main.js create mode 100644 lab1/main_test.js create mode 100755 lab1/validate.sh diff --git a/lab1/README.md b/lab1/README.md new file mode 100644 index 0000000..df0ab9f --- /dev/null +++ b/lab1/README.md @@ -0,0 +1,22 @@ +# Lab1 + +## Introduction + +In this lab, you will write unit tests for functions implemented in `main.js`. You can learn how to use classes and functions in it by uncommenting the code in it. (But remember don't commit them on GitHub) + +## Requirement + +1. Write test cases in `main_test.js` and achieve 100% code coverage. (100%) + +You can run `validate.sh` in your local to test if you satisfy the requirements. + +Please note that you must not alter files other than `main_test.js`. You will get 0 points if + +1. you modify other files to achieve requirements. +2. you can't pass all CI on your PR. + +## Submission + +You need to open a pull request to your branch (e.g. 311XXXXXX, your student number) and contain the code that satisfies the abovementioned requirements. + +Moreover, please submit the URL of your PR to E3. Your submission will only be accepted when you present at both places. diff --git a/lab1/main.js b/lab1/main.js new file mode 100644 index 0000000..c9aed9f --- /dev/null +++ b/lab1/main.js @@ -0,0 +1,55 @@ +// NOTICE: DO NOT MODIFY THE CODE IN THIS FILE +// But you can uncomment code below and run this file to understand how to use the classes + +class MyClass { + constructor() { + this.students = []; + } + + addStudent(student) { + if (!(student instanceof Student)) { + return -1; + } + this.students.push(student); + return this.students.length - 1; + } + + getStudentById(id) { + if (id < 0 || id >= this.students.length) { + return null; + } + return this.students[id]; + } +} + +class Student { + constructor() { + this.name = undefined; + } + + setName(userName) { + if (typeof userName !== 'string') { + return; + } + this.name = userName; + } + + getName() { + if (this.name === undefined) { + return ''; + } + return this.name; + } +} + +// const myClass = new MyClass(); +// const names = ['John', 'Jane', 'Doe', 'Smith']; +// names.forEach(name => { +// const student = new Student(); +// student.setName(name); +// const newStudentId = myClass.addStudent(student); +// const newStudentName = myClass.getStudentById(newStudentId).getName(); +// console.log('[+] Added student with id: %d, name: %s', newStudentId, newStudentName); +// }); + +module.exports = { MyClass, Student }; \ No newline at end of file diff --git a/lab1/main_test.js b/lab1/main_test.js new file mode 100644 index 0000000..74a716b --- /dev/null +++ b/lab1/main_test.js @@ -0,0 +1,23 @@ +const test = require('node:test'); +const assert = require('assert'); +const { MyClass, Student } = require('./main'); + +test("Test MyClass's addStudent", () => { + // TODO + throw new Error("Test not implemented"); +}); + +test("Test MyClass's getStudentById", () => { + // TODO + throw new Error("Test not implemented"); +}); + +test("Test Student's setName", () => { + // TODO + throw new Error("Test not implemented"); +}); + +test("Test Student's getName", () => { + // TODO + throw new Error("Test not implemented"); +}); \ No newline at end of file diff --git a/lab1/validate.sh b/lab1/validate.sh new file mode 100755 index 0000000..8f2fcd4 --- /dev/null +++ b/lab1/validate.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +# Check for unwanted files +for file in *; do + if [[ $file != "main.js" && $file != "main_test.js" && $file != "README.md" && $file != "validate.sh" ]]; then + echo "[!] Unwanted file detected: $file." + exit 1 + fi +done + +node=$(which node) +test_path="${BASH_SOURCE[0]}" +solution_path="$(realpath .)" +tmp_dir=$(mktemp -d -t lab1-XXXXXXXXXX) + +cd $tmp_dir + +rm -rf * +cp $solution_path/*.js . +result=$($"node" --test --experimental-test-coverage) ; ret=$? +if [ $ret -ne 0 ] ; then + echo "[!] testing fails." + exit 1 +else + coverage=$(echo "$result" | grep 'all files' | awk -F '|' '{print $2}' | sed 's/ //g') + if (( $(echo "$coverage < 100" | bc -l) )); then + echo "[!] Coverage is only $coverage%, should be 100%." + exit 1 + else + echo "[V] Coverage is 100%, great job!" + fi +fi + +rm -rf $tmp_dir + +exit 0 + +# vim: set fenc=utf8 ff=unix et sw=2 ts=2 sts=2: \ No newline at end of file From 63b34c172bf8d94c62f858c9bd5a1bdd7c89029d Mon Sep 17 00:00:00 2001 From: Zayn1029 Date: Thu, 6 Mar 2025 15:38:53 +0000 Subject: [PATCH 03/11] main_test.js --- lab1/main_test.js | 48 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/lab1/main_test.js b/lab1/main_test.js index 74a716b..01ba89c 100644 --- a/lab1/main_test.js +++ b/lab1/main_test.js @@ -3,21 +3,53 @@ const assert = require('assert'); const { MyClass, Student } = require('./main'); test("Test MyClass's addStudent", () => { - // TODO - throw new Error("Test not implemented"); + const myClass = new MyClass(); + + const student1 = new Student(); + student1.setName("Alice"); + const id1 = myClass.addStudent(student1); + assert.strictEqual(id1, 0, "First student ID should be 0"); + + const student2 = new Student(); + student2.setName("Bob"); + const id2 = myClass.addStudent(student2); + assert.strictEqual(id2, 1, "Second student ID should be 1"); + + const invalidId = myClass.addStudent({ name: "FakeStudent" }); + assert.strictEqual(invalidId, -1, "Non-Student object should return -1"); }); test("Test MyClass's getStudentById", () => { - // TODO - throw new Error("Test not implemented"); + const myClass = new MyClass(); + const student = new Student(); + student.setName("Charlie"); + + const id = myClass.addStudent(student); + const retrievedStudent = myClass.getStudentById(id); + assert.ok(retrievedStudent, "Student should be retrieved"); + assert.strictEqual(retrievedStudent.getName(), "Charlie", "Retrieved student's name should match"); + + assert.strictEqual(myClass.getStudentById(-1), null, "Negative ID should return null"); + assert.strictEqual(myClass.getStudentById(99), null, "Out of range ID should return null"); }); test("Test Student's setName", () => { - // TODO - throw new Error("Test not implemented"); + const student = new Student(); + + student.setName("David"); + assert.strictEqual(student.getName(), "David", "Should set name correctly"); + + student.setName(12345); + assert.strictEqual(student.getName(), "David", "Non-string name should be ignored"); + + student.setName(""); + assert.strictEqual(student.getName(), "", "Empty string should be a valid name"); }); test("Test Student's getName", () => { - // TODO - throw new Error("Test not implemented"); + const student = new Student(); + assert.strictEqual(student.getName(), "", "Default name should be empty string"); + + student.setName("Eve"); + assert.strictEqual(student.getName(), "Eve", "getName should return the correct name"); }); \ No newline at end of file From 5f127b365d212932cae6370f06c5029d3153b36a Mon Sep 17 00:00:00 2001 From: AxelHowe Date: Wed, 12 Mar 2025 20:52:47 +0800 Subject: [PATCH 04/11] feat: lab2 --- lab1/main_test.js | 48 +++++----------------------- lab2/README.md | 22 +++++++++++++ lab2/main.js | 81 +++++++++++++++++++++++++++++++++++++++++++++++ lab2/main_test.js | 6 ++++ lab2/validate.sh | 38 ++++++++++++++++++++++ 5 files changed, 155 insertions(+), 40 deletions(-) create mode 100644 lab2/README.md create mode 100644 lab2/main.js create mode 100644 lab2/main_test.js create mode 100755 lab2/validate.sh diff --git a/lab1/main_test.js b/lab1/main_test.js index 01ba89c..74a716b 100644 --- a/lab1/main_test.js +++ b/lab1/main_test.js @@ -3,53 +3,21 @@ const assert = require('assert'); const { MyClass, Student } = require('./main'); test("Test MyClass's addStudent", () => { - const myClass = new MyClass(); - - const student1 = new Student(); - student1.setName("Alice"); - const id1 = myClass.addStudent(student1); - assert.strictEqual(id1, 0, "First student ID should be 0"); - - const student2 = new Student(); - student2.setName("Bob"); - const id2 = myClass.addStudent(student2); - assert.strictEqual(id2, 1, "Second student ID should be 1"); - - const invalidId = myClass.addStudent({ name: "FakeStudent" }); - assert.strictEqual(invalidId, -1, "Non-Student object should return -1"); + // TODO + throw new Error("Test not implemented"); }); test("Test MyClass's getStudentById", () => { - const myClass = new MyClass(); - const student = new Student(); - student.setName("Charlie"); - - const id = myClass.addStudent(student); - const retrievedStudent = myClass.getStudentById(id); - assert.ok(retrievedStudent, "Student should be retrieved"); - assert.strictEqual(retrievedStudent.getName(), "Charlie", "Retrieved student's name should match"); - - assert.strictEqual(myClass.getStudentById(-1), null, "Negative ID should return null"); - assert.strictEqual(myClass.getStudentById(99), null, "Out of range ID should return null"); + // TODO + throw new Error("Test not implemented"); }); test("Test Student's setName", () => { - const student = new Student(); - - student.setName("David"); - assert.strictEqual(student.getName(), "David", "Should set name correctly"); - - student.setName(12345); - assert.strictEqual(student.getName(), "David", "Non-string name should be ignored"); - - student.setName(""); - assert.strictEqual(student.getName(), "", "Empty string should be a valid name"); + // TODO + throw new Error("Test not implemented"); }); test("Test Student's getName", () => { - const student = new Student(); - assert.strictEqual(student.getName(), "", "Default name should be empty string"); - - student.setName("Eve"); - assert.strictEqual(student.getName(), "Eve", "getName should return the correct name"); + // TODO + throw new Error("Test not implemented"); }); \ No newline at end of file diff --git a/lab2/README.md b/lab2/README.md new file mode 100644 index 0000000..60a9c80 --- /dev/null +++ b/lab2/README.md @@ -0,0 +1,22 @@ +# Lab2 + +## Introduction + +In this lab, you will write unit tests for functions implemented in `main.js`. You can learn how to use classes and functions in it by uncommenting the code in it. (But remember don't commit them on GitHub) + +## Requirement + +1. Write test cases in `main_test.js` and achieve 100% code coverage. Remember to use Mock, Spy, or Stub when necessary, you need to at least use one of them in your test cases. (100%) + +You can run `validate.sh` in your local to test if you satisfy the requirements. + +Please note that you must not alter files other than `main_test.js`. You will get 0 points if + +1. you modify other files to achieve requirements. +2. you can't pass all CI on your PR. + +## Submission + +You need to open a pull request to your branch (e.g. 311XXXXXX, your student number) and contain the code that satisfies the abovementioned requirements. + +Moreover, please submit the URL of your PR to E3. Your submission will only be accepted when you present at both places. diff --git a/lab2/main.js b/lab2/main.js new file mode 100644 index 0000000..2e159e7 --- /dev/null +++ b/lab2/main.js @@ -0,0 +1,81 @@ +const fs = require('fs'); +const util = require('util'); +const readFile = util.promisify(fs.readFile); + +class MailSystem { + write(name) { + console.log('--write mail for ' + name + '--'); + const context = 'Congrats, ' + name + '!'; + return context; + } + + send(name, context) { + console.log('--send mail to ' + name + '--'); + // Interact with mail system and send mail + // random success or failure + const success = Math.random() > 0.5; + if (success) { + console.log('mail sent'); + } else { + console.log('mail failed'); + } + return success; + } +} + +class Application { + constructor() { + this.people = []; + this.selected = []; + this.mailSystem = new MailSystem(); + this.getNames().then(([people, selected]) => { + this.people = people; + this.selected = selected; + }); + } + + async getNames() { + const data = await readFile('name_list.txt', 'utf8'); + const people = data.split('\n'); + const selected = []; + return [people, selected]; + } + + getRandomPerson() { + const i = Math.floor(Math.random() * this.people.length); + return this.people[i]; + } + + selectNextPerson() { + console.log('--select next person--'); + if (this.people.length === this.selected.length) { + console.log('all selected'); + return null; + } + let person = this.getRandomPerson(); + while (this.selected.includes(person)) { + person = this.getRandomPerson(); + } + this.selected.push(person); + return person; + } + + notifySelected() { + console.log('--notify selected--'); + for (const x of this.selected) { + const context = this.mailSystem.write(x); + this.mailSystem.send(x, context); + } + } +} + +// const app = new Application(); +// app.selectNextPerson(); +// app.selectNextPerson(); +// app.selectNextPerson(); +// app.notifySelected(); + +module.exports = { + Application, + MailSystem, +}; \ No newline at end of file diff --git a/lab2/main_test.js b/lab2/main_test.js new file mode 100644 index 0000000..5034468 --- /dev/null +++ b/lab2/main_test.js @@ -0,0 +1,6 @@ +const test = require('node:test'); +const assert = require('assert'); +const { Application, MailSystem } = require('./main'); + +// TODO: write your tests here +// Remember to use Stub, Mock, and Spy when necessary \ No newline at end of file diff --git a/lab2/validate.sh b/lab2/validate.sh new file mode 100755 index 0000000..13b53ed --- /dev/null +++ b/lab2/validate.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +# Check for unwanted files +for file in *; do + if [[ $file != "main.js" && $file != "main_test.js" && $file != "README.md" && $file != "validate.sh" ]]; then + echo "[!] Unwanted file detected: $file." + exit 1 + fi +done + +node=$(which node) +test_path="${BASH_SOURCE[0]}" +solution_path="$(realpath .)" +tmp_dir=$(mktemp -d -t lab2-XXXXXXXXXX) + +cd $tmp_dir + +rm -rf * +cp $solution_path/*.js . +result=$($"node" --test --experimental-test-coverage) ; ret=$? +if [ $ret -ne 0 ] ; then + echo "[!] testing fails" + exit 1 +else + coverage=$(echo "$result" | grep 'all files' | awk -F '|' '{print $2}' | sed 's/ //g') + if (( $(echo "$coverage < 100" | bc -l) )); then + echo "[!] Coverage is only $coverage%" + exit 1 + else + echo "[V] Coverage is 100%" + fi +fi + +rm -rf $tmp_dir + +exit 0 + +# vim: set fenc=utf8 ff=unix et sw=2 ts=2 sts=2: \ No newline at end of file From abfc30437464b0bac3d2729ede8b9c1f397c3147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=A0=E7=9A=84GitHub=E5=B8=B3=E8=99=9F=E5=90=8D?= =?UTF-8?q?=E7=A8=B1?= <你的GitHub郵箱> Date: Fri, 14 Mar 2025 15:12:00 +0000 Subject: [PATCH 05/11] Lab2 --- lab2/main_test.js | 187 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 184 insertions(+), 3 deletions(-) diff --git a/lab2/main_test.js b/lab2/main_test.js index 5034468..0d7d0b9 100644 --- a/lab2/main_test.js +++ b/lab2/main_test.js @@ -1,6 +1,187 @@ -const test = require('node:test'); const assert = require('assert'); +const test = require('node:test'); const { Application, MailSystem } = require('./main'); +const fs = require('node:fs'); +const util = require('util'); +const writeFile = util.promisify(fs.writeFile); +const unlinkFile = util.promisify(fs.unlink); + +async function createTestFile(content = "Alice\nBob\nCharlie") { + await writeFile("name_list.txt", content, 'utf-8'); +} + +async function removeTestFile() { + try { + await unlinkFile("name_list.txt"); + } catch (error) { + // Ignore errors + } +} + +// 我們使用單獨的測試進行設置 +test('Setup test environment', async () => { + await createTestFile(); +}); + +// Tests for MailSystem class +test('MailSystem.write should return congratulatory message', (t) => { + const mailSystem = new MailSystem(); + const result = mailSystem.write('John'); + assert.strictEqual(result, 'Congrats, John!'); +}); + +test('MailSystem.send should return boolean indicating success', (t) => { + const mailSystem = new MailSystem(); + + const originalRandom = Math.random; + + // Test success case + Math.random = () => 0.6; // return true + const successResult = mailSystem.send('John', 'Congrats, John!'); + assert.strictEqual(successResult, true); + + // Test failure case + Math.random = () => 0.4; // return false + const failureResult = mailSystem.send('John', 'Congrats, John!'); + assert.strictEqual(failureResult, false); + + Math.random = originalRandom; +}); + +test('Application constructor should initialize properties', async (t) => { + await createTestFile("Alice\nBob\nCharlie"); + const app = new Application(); + + await new Promise(resolve => setTimeout(resolve, 10)); + + assert.deepStrictEqual(app.people, ['Alice', 'Bob', 'Charlie']); + assert.deepStrictEqual(app.selected, []); + assert.ok(app.mailSystem instanceof MailSystem); +}); + +test('getNames should read and parse names from file', async (t) => { + await createTestFile("Dave\nEve\nFrank"); + + const app = new Application(); + const [people, selected] = await app.getNames(); + + assert.deepStrictEqual(people, ['Dave', 'Eve', 'Frank']); + assert.deepStrictEqual(selected, []); +}); + +test('getRandomPerson should return a person from the people array', async (t) => { + const app = new Application(); + + await new Promise(resolve => setTimeout(resolve, 10)); + + app.people = ['Alice', 'Bob', 'Charlie']; + + const originalRandom = Math.random; + const originalFloor = Math.floor; + + // Create a spy + let floorCallCount = 0; + Math.floor = (num) => { + floorCallCount++; + return originalFloor(num); + }; + + Math.random = () => 0; //select idx 0 + assert.strictEqual(app.getRandomPerson(), 'Alice'); + + Math.random = () => 0.34; // select idx 1 + assert.strictEqual(app.getRandomPerson(), 'Bob'); + + Math.random = () => 0.67; // select idx 2 + assert.strictEqual(app.getRandomPerson(), 'Charlie'); + + assert.strictEqual(floorCallCount, 3); + + Math.random = originalRandom; + Math.floor = originalFloor; +}); + +test('selectNextPerson should select a random unselected person', async (t) => { + const app = new Application(); + await new Promise(resolve => setTimeout(resolve, 10)); + + app.people = ['Alice', 'Bob', 'Charlie']; + app.selected = []; + + const originalGetRandomPerson = app.getRandomPerson; + let randomPersonCalls = 0; + + app.getRandomPerson = () => { + randomPersonCalls++; + if (randomPersonCalls === 1) return 'Bob'; + if (randomPersonCalls === 2) return 'Bob'; + if (randomPersonCalls === 3) return 'Alice'; + return 'Charlie'; + }; + + const result = app.selectNextPerson(); + assert.strictEqual(result, 'Bob'); + assert.deepStrictEqual(app.selected, ['Bob']); + + const secondResult = app.selectNextPerson(); + assert.strictEqual(secondResult, 'Alice'); + assert.deepStrictEqual(app.selected, ['Bob', 'Alice']); + + app.getRandomPerson = originalGetRandomPerson; +}); + +test('selectNextPerson should return null when all people are selected', async (t) => { + const app = new Application(); + await new Promise(resolve => setTimeout(resolve, 10)); + + app.people = ['Alice', 'Bob']; + app.selected = ['Alice', 'Bob']; + + const result = app.selectNextPerson(); + + assert.strictEqual(result, null); +}); + +test('notifySelected should send mail to all selected people', async (t) => { + const app = new Application(); + await new Promise(resolve => setTimeout(resolve, 10)); + + app.selected = ['Alice', 'Bob']; + + const originalWrite = app.mailSystem.write; + const originalSend = app.mailSystem.send; + + const writeCalls = []; + const sendCalls = []; + + app.mailSystem.write = (name) => { + writeCalls.push(name); + return `Congrats, ${name}!`; + }; + + app.mailSystem.send = (name, context) => { + sendCalls.push({ name, context }); + return true; + }; + + app.notifySelected(); + + assert.strictEqual(writeCalls.length, 2); + assert.strictEqual(sendCalls.length, 2); + + assert.strictEqual(writeCalls[0], 'Alice'); + assert.strictEqual(writeCalls[1], 'Bob'); + + assert.strictEqual(sendCalls[0].name, 'Alice'); + assert.strictEqual(sendCalls[0].context, 'Congrats, Alice!'); + assert.strictEqual(sendCalls[1].name, 'Bob'); + assert.strictEqual(sendCalls[1].context, 'Congrats, Bob!'); + + app.mailSystem.write = originalWrite; + app.mailSystem.send = originalSend; +}); -// TODO: write your tests here -// Remember to use Stub, Mock, and Spy when necessary \ No newline at end of file +// 我們使用單獨的測試進行清理 +test('Cleanup test environment', async () => { + await removeTestFile(); +}); From 337f5576a2251a255717706de96ec42c1d27eba1 Mon Sep 17 00:00:00 2001 From: CTHua Date: Thu, 20 Mar 2025 15:35:07 +0800 Subject: [PATCH 06/11] feat: lab3 --- lab3/README.md | 29 +++++++++++++++++++++++++++++ lab3/main.js | 34 ++++++++++++++++++++++++++++++++++ lab3/main_test.js | 5 +++++ lab3/validate.sh | 38 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 106 insertions(+) create mode 100644 lab3/README.md create mode 100644 lab3/main.js create mode 100644 lab3/main_test.js create mode 100755 lab3/validate.sh diff --git a/lab3/README.md b/lab3/README.md new file mode 100644 index 0000000..b591ab8 --- /dev/null +++ b/lab3/README.md @@ -0,0 +1,29 @@ +# Lab3 + +## Introduction + +In this lab, you will write unit tests for functions implemented in `main.js`. You can learn how to use classes and functions in it by uncommenting the code in it. (But remember don't commit them on GitHub) + +## Preparation (Important!!!) + +1. Sync fork on GitHub +2. `git checkout -b lab3` (**NOT** your student ID !!!) + +## Requirement + +1. (40%) Write test cases in `main_test.js` and achieve 100% code coverage. +2. (30%) For each function, parameterize their testcases to test the error-results. +3. (30%) For each function, use at least 3 parameterized testcases to test the non-error-results. + +You can run `validate.sh` in your local to test if you satisfy the requirements. + +Please note that you must not alter files other than `main_test.js`. You will get 0 points if + +1. you modify other files to achieve requirements. +2. you can't pass all CI on your PR. + +## Submission + +You need to open a pull request to your branch (e.g. 312XXXXXX, your student number) and contain the code that satisfies the abovementioned requirements. + +Moreover, please submit the URL of your PR to E3. Your submission will only be accepted when you present at both places. diff --git a/lab3/main.js b/lab3/main.js new file mode 100644 index 0000000..cee5de7 --- /dev/null +++ b/lab3/main.js @@ -0,0 +1,34 @@ +class Calculator { + exp(x) { + if (!Number.isFinite(x)) { + throw Error('unsupported operand type'); + } + const result = Math.exp(x); + if (result === Infinity) { + throw Error('overflow'); + } + return result; + } + + log(x) { + if (!Number.isFinite(x)) { + throw Error('unsupported operand type'); + } + const result = Math.log(x); + if (result === -Infinity) { + throw Error('math domain error (1)'); + } + if (Number.isNaN(result)) { + throw Error('math domain error (2)'); + } + return result; + } +} + +// const calculator = new Calculator(); +// console.log(calculator.exp(87)); +// console.log(calculator.log(48763)); + +module.exports = { + Calculator +}; \ No newline at end of file diff --git a/lab3/main_test.js b/lab3/main_test.js new file mode 100644 index 0000000..e6d6414 --- /dev/null +++ b/lab3/main_test.js @@ -0,0 +1,5 @@ +const {describe, it} = require('node:test'); +const assert = require('assert'); +const { Calculator } = require('./main'); + +// TODO: write your tests here diff --git a/lab3/validate.sh b/lab3/validate.sh new file mode 100755 index 0000000..7a758fb --- /dev/null +++ b/lab3/validate.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +# Check for unwanted files +for file in *; do + if [[ $file != "main.js" && $file != "main_test.js" && $file != "README.md" && $file != "validate.sh" ]]; then + echo "[!] Unwanted file detected: $file." + exit 1 + fi +done + +node=$(which node) +test_path="${BASH_SOURCE[0]}" +solution_path="$(realpath .)" +tmp_dir=$(mktemp -d -t lab3-XXXXXXXXXX) + +cd $tmp_dir + +rm -rf * +cp $solution_path/*.js . +result=$($"node" --test --experimental-test-coverage) ; ret=$? +if [ $ret -ne 0 ] ; then + echo "[!] testing fails" + exit 1 +else + coverage=$(echo "$result" | grep 'all files' | awk -F '|' '{print $2}' | sed 's/ //g') + if (( $(echo "$coverage < 100" | bc -l) )); then + echo "[!] Coverage is only $coverage%" + exit 1 + else + echo "[V] Coverage is 100%" + fi +fi + +rm -rf $tmp_dir + +exit 0 + +# vim: set fenc=utf8 ff=unix et sw=2 ts=2 sts=2: \ No newline at end of file From 2312ca61cfedb9f39925d8484bf9c84cddb6a6c2 Mon Sep 17 00:00:00 2001 From: CTHua Date: Thu, 27 Mar 2025 13:32:20 +0800 Subject: [PATCH 07/11] feat: lab4 --- lab4/README.md | 29 + lab4/main_test.js | 22 + lab4/package-lock.json | 1174 ++++++++++++++++++++++++++++++++++++++++ lab4/package.json | 5 + lab4/validate.sh | 45 ++ 5 files changed, 1275 insertions(+) create mode 100644 lab4/README.md create mode 100644 lab4/main_test.js create mode 100644 lab4/package-lock.json create mode 100644 lab4/package.json create mode 100755 lab4/validate.sh diff --git a/lab4/README.md b/lab4/README.md new file mode 100644 index 0000000..c9cb0b7 --- /dev/null +++ b/lab4/README.md @@ -0,0 +1,29 @@ +# Lab4 + +## Introduction + +In this lab, you will write tests in `main_test.js`. You can learn how to use [Puppeteer](https://pptr.dev/) to tests a web UI. + +## Preparation (Important!!!) + +1. Sync fork your branch (e.g., `SQLab:312XXXXXX`) +2. `git checkout -b lab4` (**NOT** your student ID !!!) + +## Requirement + +1. (100%) Goto https://pptr.dev/, type `chipi chipi chapa chapa` into the search box, click on **1st** result in the **Docs** section, and print the title. + +For the detailed steps and hints, please check the slide of this lab. + +You can run `validate.sh` in your local to test if you satisfy the requirements. + +Please note that you must not alter files other than `main_test.js`. You will get 0 points if + +1. you modify other files to achieve requirements. +2. you can't pass all CI on your PR. + +## Submission + +You need to open a pull request to your branch (e.g. 312XXXXXX, your student number) and contain the code that satisfies the abovementioned requirements. + +Moreover, please submit the URL of your PR to E3. Your submission will only be accepted when you present at both places. diff --git a/lab4/main_test.js b/lab4/main_test.js new file mode 100644 index 0000000..e37d21a --- /dev/null +++ b/lab4/main_test.js @@ -0,0 +1,22 @@ +const puppeteer = require('puppeteer'); + +(async () => { + // Launch the browser and open a new blank page + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + + // Navigate the page to a URL + await page.goto('https://pptr.dev/'); + + // Hints: + // Click search button + // Type into search box + // Wait for search result + // Get the `Docs` result section + // Click on first result in `Docs` section + // Locate the title + // Print the title + + // Close the browser + await browser.close(); +})(); \ No newline at end of file diff --git a/lab4/package-lock.json b/lab4/package-lock.json new file mode 100644 index 0000000..ced9fee --- /dev/null +++ b/lab4/package-lock.json @@ -0,0 +1,1174 @@ +{ + "name": "lab4", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "puppeteer": "^22.5.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.1.tgz", + "integrity": "sha512-bC49z4spJQR3j8vFtJBLqzyzFV0ciuL5HYX7qfSl3KEqeMVV+eTquRvmXxpvB0AMubRrvv7y5DILiLLPi57Ewg==", + "dependencies": { + "@babel/highlight": "^7.24.1", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.1.tgz", + "integrity": "sha512-EPmDPxidWe/Ex+HTFINpvXdPHRmgSF3T8hGvzondYjmgzTQ/0EbLpSxyt+w3zzlYSk9cNBQNF9k0dT5Z2NiBjw==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@puppeteer/browsers": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.2.0.tgz", + "integrity": "sha512-MC7LxpcBtdfTbzwARXIkqGZ1Osn3nnZJlm+i0+VqHl72t//Xwl9wICrXT8BwtgC6s1xJNHsxOpvzISUqe92+sw==", + "dependencies": { + "debug": "4.3.4", + "extract-zip": "2.0.1", + "progress": "2.0.3", + "proxy-agent": "6.4.0", + "semver": "7.6.0", + "tar-fs": "3.0.5", + "unbzip2-stream": "1.4.3", + "yargs": "17.7.2" + }, + "bin": { + "browsers": "lib/cjs/main-cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==" + }, + "node_modules/@types/node": { + "version": "20.11.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.30.tgz", + "integrity": "sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw==", + "optional": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/b4a": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", + "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==" + }, + "node_modules/bare-events": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.2.1.tgz", + "integrity": "sha512-9GYPpsPFvrWBkelIhOhTWtkeZxVxZOdb3VnFTCzlOo3OjvmTvzLoZFUT8kNFACx0vJej6QPney1Cf9BvzCNE/A==", + "optional": true + }, + "node_modules/bare-fs": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.2.2.tgz", + "integrity": "sha512-X9IqgvyB0/VA5OZJyb5ZstoN62AzD7YxVGog13kkfYWYqJYcK0kcqLZ6TrmH5qr4/8//ejVcX4x/a0UvaogXmA==", + "optional": true, + "dependencies": { + "bare-events": "^2.0.0", + "bare-os": "^2.0.0", + "bare-path": "^2.0.0", + "streamx": "^2.13.0" + } + }, + "node_modules/bare-os": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.2.1.tgz", + "integrity": "sha512-OwPyHgBBMkhC29Hl3O4/YfxW9n7mdTr2+SsO29XBWKKJsbgj3mnorDB80r5TiCQgQstgE5ga1qNYrpes6NvX2w==", + "optional": true + }, + "node_modules/bare-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.0.tgz", + "integrity": "sha512-DIIg7ts8bdRKwJRJrUMy/PICEaQZaPGZ26lsSx9MJSwIhSrcdHn7/C8W+XmnG/rKi6BaRcz+JO00CjZteybDtw==", + "optional": true, + "dependencies": { + "bare-os": "^2.1.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/basic-ftp": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "engines": { + "node": "*" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chromium-bidi": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.5.13.tgz", + "integrity": "sha512-OHbYCetDxdW/xmlrafgOiLsIrw4Sp1BEeolbZ1UGJO5v/nekQOJBj/Kzyw6sqKcAVabUTo0GS3cTYgr6zIf00g==", + "dependencies": { + "mitt": "3.0.1", + "urlpattern-polyfill": "10.0.0", + "zod": "3.22.4" + }, + "peerDependencies": { + "devtools-protocol": "*" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "engines": { + "node": ">= 14" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/devtools-protocol": { + "version": "0.0.1249869", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1249869.tgz", + "integrity": "sha512-Ctp4hInA0BEavlUoRy9mhGq0i+JSo/AwVyX2EFgZmV1kYB+Zq+EMBAn52QWu6FbRr10hRb6pBl420upbp4++vg==" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==" + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-uri": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", + "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4", + "fs-extra": "^11.2.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", + "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==" + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/pac-proxy-agent": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.1.tgz", + "integrity": "sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==", + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", + "pac-resolver": "^7.0.0", + "socks-proxy-agent": "^8.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "dependencies": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/proxy-agent": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", + "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.3", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.0.1", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/puppeteer": { + "version": "22.5.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-22.5.0.tgz", + "integrity": "sha512-PNVflixb6w3FMhehYhLcaQHTCcNKVkjxekzyvWr0n0yBnhUYF0ZhiG4J1I14Mzui2oW8dGvUD8kbXj0GiN1pFg==", + "hasInstallScript": true, + "dependencies": { + "@puppeteer/browsers": "2.2.0", + "cosmiconfig": "9.0.0", + "puppeteer-core": "22.5.0" + }, + "bin": { + "puppeteer": "lib/esm/puppeteer/node/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/puppeteer-core": { + "version": "22.5.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-22.5.0.tgz", + "integrity": "sha512-bcfmM1nNSysjnES/ZZ1KdwFAFFGL3N76qRpisBb4WL7f4UAD4vPDxlhKZ1HJCDgMSWeYmeder4kftyp6lKqMYg==", + "dependencies": { + "@puppeteer/browsers": "2.2.0", + "chromium-bidi": "0.5.13", + "debug": "4.3.4", + "devtools-protocol": "0.0.1249869", + "ws": "8.16.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.1.tgz", + "integrity": "sha512-B6w7tkwNid7ToxjZ08rQMT8M9BJAf8DKx8Ft4NivzH0zBUfd6jldGcisJn/RLgxcX3FPNDdNQCUEMMT79b+oCQ==", + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.2.tgz", + "integrity": "sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g==", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "socks": "^2.7.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==" + }, + "node_modules/streamx": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.16.1.tgz", + "integrity": "sha512-m9QYj6WygWyWa3H1YY69amr4nVgy61xfjys7xO7kviL5rfIEc2naf+ewFiOA+aEJD7y0JO3h2GoiUv4TDwEGzQ==", + "dependencies": { + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tar-fs": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.5.tgz", + "integrity": "sha512-JOgGAmZyMgbqpLwct7ZV8VzkEB6pxXFBVErLtb+XCOqzc6w1xiWKI9GVd6bwk68EX7eJ4DWmfXVmq8K2ziZTGg==", + "dependencies": { + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^2.1.1", + "bare-path": "^2.1.0" + } + }, + "node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "node_modules/unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dependencies": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "optional": true + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/urlpattern-polyfill": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", + "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/ws": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/zod": { + "version": "3.22.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", + "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/lab4/package.json b/lab4/package.json new file mode 100644 index 0000000..5014ba0 --- /dev/null +++ b/lab4/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "puppeteer": "^22.5.0" + } +} diff --git a/lab4/validate.sh b/lab4/validate.sh new file mode 100755 index 0000000..1130e5c --- /dev/null +++ b/lab4/validate.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +# Check for unwanted files +for file in *; do + if [[ $file != "node_modules" && $file != "main_test.js" && $file != "package-lock.json" && $file != "package.json" && $file != "README.md" && $file != "validate.sh" ]]; then + echo "[!] Unwanted file detected: $file." + exit 1 + fi +done + +node=$(which node) +test_path="${BASH_SOURCE[0]}" +solution_path="$(realpath .)" +tmp_dir=$(mktemp -d -t lab4-XXXXXXXXXX) +answer="ElementHandle.dragAndDrop() method" + +cd $tmp_dir + +rm -rf * +cp $solution_path/*.js . +cp $solution_path/*.json . + +# Install dependencies +npm ci + +result=$($"node" main_test.js) ; ret=$? +if [ $ret -ne 0 ] ; then + echo "[!] testing fails" + exit 1 +else + title=$(echo "$result" | head -1) + if [[ $title != $answer ]]; then + echo "[!] Expected: $answer" + echo "[!] Actual: $title" + exit 1 + else + echo "[V] Pass" + fi +fi + +rm -rf $tmp_dir + +exit 0 + +# vim: set fenc=utf8 ff=unix et sw=2 ts=2 sts=2: \ No newline at end of file From 3aa4c5b028d42c8dd6dce0ad508593ff250eb69b Mon Sep 17 00:00:00 2001 From: Zayn1029 Date: Wed, 2 Apr 2025 10:49:15 +0000 Subject: [PATCH 08/11] Add Puppeteer test script --- lab4/main_test.js | 71 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 20 deletions(-) diff --git a/lab4/main_test.js b/lab4/main_test.js index e37d21a..a2d21b8 100644 --- a/lab4/main_test.js +++ b/lab4/main_test.js @@ -1,22 +1,53 @@ -const puppeteer = require('puppeteer'); +import puppeteer from 'puppeteer'; -(async () => { - // Launch the browser and open a new blank page - const browser = await puppeteer.launch(); - const page = await browser.newPage(); +async function runTest() { + try { + // Launch the browser + const browser = await puppeteer.launch(); + + // Create a new page + const page = await browser.newPage(); + + // Navigate to the Puppeteer documentation + await page.goto('https://pptr.dev/'); + + // Click search button + await page.waitForSelector('.DocSearch-Button'); + await page.click('.DocSearch-Button'); + + // Type into search box + await page.waitForSelector('.DocSearch-Input'); + await page.type('.DocSearch-Input', 'andy popoo'); + + // Wait for search results + await page.waitForSelector('.DocSearch-Hit', { timeout: 20000 }); + await new Promise(resolve => setTimeout(resolve, 1000)); + + // Find the first result with "ElementHandle." in the title + const resultTitle = await page.$$eval('.DocSearch-Hit', hits => { + for (const hit of hits) { + const title = hit.querySelector('.DocSearch-Hit-title')?.innerText.trim(); + + if (title && title.includes('ElementHandle.')) { + return title; + } + } + return null; + }); + + // Log the result + if (resultTitle) { + console.log(resultTitle); + } else { + console.log('No title containing "ElementHandle." was found.'); + } + + // Close the browser + await browser.close(); + } catch (error) { + console.error('An error occurred:', error); + } +} - // Navigate the page to a URL - await page.goto('https://pptr.dev/'); - - // Hints: - // Click search button - // Type into search box - // Wait for search result - // Get the `Docs` result section - // Click on first result in `Docs` section - // Locate the title - // Print the title - - // Close the browser - await browser.close(); -})(); \ No newline at end of file +// Run the test +runTest(); \ No newline at end of file From 96643cf7194da5903f2127805c654742d88139c5 Mon Sep 17 00:00:00 2001 From: YingMuo Date: Thu, 24 Apr 2025 06:03:24 +0800 Subject: [PATCH 09/11] feat: lab5 --- lab5/Makefile | 19 +++++++++++++++++++ lab5/README.md | 26 ++++++++++++++++++++++++++ lab5/ans | 4 ++++ lab5/antiasan.c | 6 ++++++ lab5/antiasan.h | 6 ++++++ lab5/bss_overflow.c | 21 +++++++++++++++++++++ lab5/validate.sh | 43 +++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 125 insertions(+) create mode 100644 lab5/Makefile create mode 100644 lab5/README.md create mode 100644 lab5/ans create mode 100644 lab5/antiasan.c create mode 100644 lab5/antiasan.h create mode 100644 lab5/bss_overflow.c create mode 100755 lab5/validate.sh diff --git a/lab5/Makefile b/lab5/Makefile new file mode 100644 index 0000000..266dba9 --- /dev/null +++ b/lab5/Makefile @@ -0,0 +1,19 @@ +CC=gcc + +.PHONY: all +all: bss_overflow_asan + +bss_overflow_asan: bss_overflow.c libantiasan.so + $(CC) -fsanitize=address -Og -g -o $@ $< -lantiasan -L. + +libantiasan.so: antiasan.c + $(CC) -g -fPIC -c antiasan.c + $(CC) -shared antiasan.o -o libantiasan.so + +.PHINY: run +run: + LD_LIBRARY_PATH=. ./bss_overflow_asan + +.PHONY: clean +clean: + rm bss_overflow_asan antiasan.o libantiasan.so diff --git a/lab5/README.md b/lab5/README.md new file mode 100644 index 0000000..1528ef4 --- /dev/null +++ b/lab5/README.md @@ -0,0 +1,26 @@ +# Lab5 + +## Introduction + +In this lab, you will write a function antoasan to bypass detection of ASan in `antiasan.c`. + +## Preparation (Important!!!) + +1. Sync fork your branch (e.g., `SQLab:311XXXXXX`) +2. `git checkout -b lab5` (**NOT** your student ID !!!) + +## Requirement + +1. (100%) write a function antoasan to bypass detection of ASan in `antiasan.c`. +You can run `validate.sh` in your local to test if you satisfy the requirements. + +Please note that you must not alter files other than `antiasan.c`. You will get 0 points if + +1. you modify other files to achieve requirements. +2. you can't pass all CI on your PR. + +## Submission + +You need to open a pull request to your branch (e.g. 311XXXXXX, your student number) and contain the code that satisfies the abovementioned requirements. + +Moreover, please submit the URL of your PR to E3. Your submission will only be accepted when you present at both places. diff --git a/lab5/ans b/lab5/ans new file mode 100644 index 0000000..59ad6ce --- /dev/null +++ b/lab5/ans @@ -0,0 +1,4 @@ +LD_LIBRARY_PATH=. ./bss_overflow_asan +gBadBuf = HAHAHAHAHAHAHAHAHAHAHAH +gS = HAHAHAHAHAHAHAHAHAHAHAH +gS = HAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAH diff --git a/lab5/antiasan.c b/lab5/antiasan.c new file mode 100644 index 0000000..8a8936d --- /dev/null +++ b/lab5/antiasan.c @@ -0,0 +1,6 @@ +#include + +void antiasan(unsigned long addr) +{ + +} diff --git a/lab5/antiasan.h b/lab5/antiasan.h new file mode 100644 index 0000000..3035179 --- /dev/null +++ b/lab5/antiasan.h @@ -0,0 +1,6 @@ +#ifndef HIJACK_H +#define HIJACK_H + +void antiasan(unsigned long); + +#endif diff --git a/lab5/bss_overflow.c b/lab5/bss_overflow.c new file mode 100644 index 0000000..3470cda --- /dev/null +++ b/lab5/bss_overflow.c @@ -0,0 +1,21 @@ +#include +#include +#include "antiasan.h" + +char gS[0x18]; +char gBadBuf[0x87]; + +int main(void) +{ + strcpy(gBadBuf, "HAHAHAHAHAHAHAHAHAHAHAH"); + strcpy(gS, "HAHAHAHAHAHAHAHAHAHAHAH"); + printf("gBadBuf = %s\n", gBadBuf); + printf("gS = %s\n", gS); + antiasan((unsigned long)&gBadBuf); + for (int i = 0; i < 0x10; i += 2) { + gS[0x17 + i] = 'A'; + gS[0x17 + i + 1] = 'H'; + } + printf("gS = %s\n", gS); + return 0; +} diff --git a/lab5/validate.sh b/lab5/validate.sh new file mode 100755 index 0000000..be3d608 --- /dev/null +++ b/lab5/validate.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +# Check for unwanted files +for file in *; do + if [[ $file != "bss_overflow.c" && $file != "antiasan.c" && $file != "antiasan.h" && $file != "Makefile" && $file != "README.md" && $file != "validate.sh" && $file != "ans" ]]; then + echo "[!] Unwanted file detected: $file." + exit 1 + fi +done + +test_path="${BASH_SOURCE[0]}" +solution_path="$(realpath .)" +tmp_dir=$(mktemp -d -t lab5-XXXXXXXXXX) +answer="" + +cd $tmp_dir + +rm -rf * +cp $solution_path/Makefile . +cp $solution_path/*.c . +cp $solution_path/*.h . +cp $solution_path/ans . + +make +make run > out 2>&1 +result=$(diff --strip-trailing-cr ans out) +if [[ -n $result ]]; then + echo "[!] Expected: " + cat ans + echo "" + echo "[!] Actual: " + cat out + echo "" + exit 1 +else + echo "[V] Pass" +fi + +rm -rf $tmp_dir + +exit 0 + +# vim: set fenc=utf8 ff=unix et sw=2 ts=2 sts=2: From 8de96b80c70691a3796fa9f4804d17fc734060a9 Mon Sep 17 00:00:00 2001 From: YingMuo Date: Sat, 26 Apr 2025 00:08:49 +0800 Subject: [PATCH 10/11] fix: autograding --- .github/workflows/lab-autograding.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lab-autograding.yml b/.github/workflows/lab-autograding.yml index 9016526..25a89a3 100644 --- a/.github/workflows/lab-autograding.yml +++ b/.github/workflows/lab-autograding.yml @@ -45,7 +45,7 @@ jobs: const files = await github.rest.pulls.listFiles({ owner, repo, pull_number: issue_number }); const changedFiles = files.data.map((file) => file.filename); const allowedFileRegex = /^lab\d+\/main_test.js$/; - const specialChangedFiles = ["lab0/lab0.js"]; + const specialChangedFiles = ["lab0/lab0.js", "lab5/antiasan.c"]; if (!changedFiles.every((file) => (allowedFileRegex.test(file) || specialChangedFiles.includes(file)))) { core.setFailed('The PR contains changes to files other than the allowed files.'); } From 801b9f474362298be5727b41bd67f44f3b2df4a8 Mon Sep 17 00:00:00 2001 From: Zayn1029 Date: Wed, 30 Apr 2025 10:49:14 +0000 Subject: [PATCH 11/11] add lab5 --- lab5/antiasan.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lab5/antiasan.c b/lab5/antiasan.c index 8a8936d..dd0a2c4 100644 --- a/lab5/antiasan.c +++ b/lab5/antiasan.c @@ -1,6 +1,6 @@ #include +#include -void antiasan(unsigned long addr) -{ - +void antiasan(unsigned long addr) { + __asan_unpoison_memory_region((void *)addr, 0x100); }